Archived
Pretty: ensure recursionsLeft is not zero before decrementing it
When value_to_pretty is called with recursionsLeft=0 and an Array or Map
type, container_to_pretty is called with recursionsLeft - 1 = -1. This
breaks the recursion limit check.
In practice, this can be triggered with a CBOR data containing 1023
Arrays, a Tag and many more Arrays:
$ python3 -c 'import sys;sys.stdout.buffer.write(b"\x9f" * 1023 + b"\xc0\x9f" + b"\x9f" * 100000 + b"\xff" * 101024)' | ./bin/cbordump
Segmentation fault (core dumped)
This segmentation fault is due to the stack growing too much, due to the
quantity of recursive calls.
Fix this by reporting a proper error when recursionsLeft <= 0, instead
of when recursionsLeft == 0. The same input now produces:
[_ [_ [_ ... [_ 0([
-: internal error: too many nested containers found in recursive function
_ <nesting too deep, recursion stopped>
Moreover, using fewer nested arrays works fine:
$ python3 -c 'import sys;sys.stdout.buffer.write(b"\x9f" * 1023 + b"\xc0\x9f" + b"\x9f" * 1024 + b"\xff" * 2048)' |./bin/cbordump
[_ [_ [_ ... [_ 0([_ <nesting too deep, recursion stopped>])] ... ]]]
Also modify the test when formatting CborTagType to ensure
value_to_pretty is never called with a negative recursionsLeft.
This commit is contained in:
committed by
Thiago Macieira
parent
f96502575f
commit
4682eaa1e0
+5
-2
@@ -308,7 +308,7 @@ static CborError container_to_pretty(CborStreamFunction stream, void *out, CborV
|
||||
const char *comma = "";
|
||||
CborError err = CborNoError;
|
||||
|
||||
if (!recursionsLeft) {
|
||||
if (recursionsLeft <= 0) {
|
||||
printRecursionLimit(stream, out);
|
||||
while (!cbor_value_at_end(it) && !err) {
|
||||
err = cbor_value_advance(it);
|
||||
@@ -356,6 +356,9 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
|
||||
copy_current_position(it, &recursed);
|
||||
return err; /* parse error */
|
||||
}
|
||||
/* N.B. recursionsLeft can be zero, in which case container_to_pretty is called with
|
||||
* recursionsLeft = -1 and reports that nesting is too deep.
|
||||
*/
|
||||
err = container_to_pretty(stream, out, &recursed, type, flags, recursionsLeft - 1);
|
||||
if (err) {
|
||||
copy_current_position(it, &recursed);
|
||||
@@ -452,7 +455,7 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
|
||||
err = stream(out, "%" PRIu64 "%s(", tag, get_indicator(it, flags));
|
||||
if (!err)
|
||||
err = cbor_value_advance_fixed(it);
|
||||
if (!err && recursionsLeft)
|
||||
if (!err && recursionsLeft > 0)
|
||||
err = value_to_pretty(stream, out, it, flags, recursionsLeft - 1);
|
||||
else if (!err)
|
||||
printRecursionLimit(stream, out);
|
||||
|
||||
Reference in New Issue
Block a user