Skip to content

Commit d1f9416

Browse files
Pretty: limit the number of recursions, like the Parser
The pretty-dumper code did not have a limit, assuming that the input had been validated beforehand, so if the nesting was too deep, one would have got an error before getting to the dumper. However, it's not inconceivable that someone adds a logger code to a packet a bit too early. So let's be defensive and apply the limiter here too. Signed-off-by: Thiago Macieira <[email protected]>
1 parent 5433fc3 commit d1f9416

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

src/cborinternal_p.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
# define CBOR_INTERNAL_API
3232
#endif
3333

34+
#ifndef CBOR_PARSER_MAX_RECURSIONS
35+
# define CBOR_PARSER_MAX_RECURSIONS 1024
36+
#endif
37+
3438
/*
3539
* CBOR Major types
3640
* Encoded in the high 3 bits of the descriptor byte

src/cborparser.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@
3838

3939
#include <string.h>
4040

41-
#ifndef CBOR_PARSER_MAX_RECURSIONS
42-
# define CBOR_PARSER_MAX_RECURSIONS 1024
43-
#endif
44-
4541
/**
4642
* \defgroup CborParsing Parsing CBOR streams
4743
* \brief Group of functions used to parse CBOR streams.

src/cborpretty.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@
147147
* \value CborPrettyDefaultFlags Default conversion flags.
148148
*/
149149

150+
static void printRecursionLimit(FILE *out)
151+
{
152+
fputs("<nesting too deep, recursion stopped>", out);
153+
}
154+
150155
static CborError hexDump(FILE *out, const void *ptr, size_t n)
151156
{
152157
const uint8_t *buffer = (const uint8_t *)ptr;
@@ -273,16 +278,22 @@ static const char *get_indicator(const CborValue *it, int flags)
273278
return resolve_indicator(it->ptr, it->parser->end, flags);
274279
}
275280

276-
static CborError value_to_pretty(FILE *out, CborValue *it, int flags);
277-
static CborError container_to_pretty(FILE *out, CborValue *it, CborType containerType, int flags)
281+
static CborError value_to_pretty(FILE *out, CborValue *it, int flags, int recursionsLeft);
282+
static CborError container_to_pretty(FILE *out, CborValue *it, CborType containerType,
283+
int flags, int recursionsLeft)
278284
{
285+
if (!recursionsLeft) {
286+
printRecursionLimit(out);
287+
return CborNoError; /* do allow the dumping to continue */
288+
}
289+
279290
const char *comma = "";
280291
while (!cbor_value_at_end(it)) {
281292
if (fprintf(out, "%s", comma) < 0)
282293
return CborErrorIO;
283294
comma = ", ";
284295

285-
CborError err = value_to_pretty(out, it, flags);
296+
CborError err = value_to_pretty(out, it, flags, recursionsLeft);
286297
if (err)
287298
return err;
288299

@@ -292,14 +303,14 @@ static CborError container_to_pretty(FILE *out, CborValue *it, CborType containe
292303
/* map: that was the key, so get the value */
293304
if (fprintf(out, ": ") < 0)
294305
return CborErrorIO;
295-
err = value_to_pretty(out, it, flags);
306+
err = value_to_pretty(out, it, flags, recursionsLeft);
296307
if (err)
297308
return err;
298309
}
299310
return CborNoError;
300311
}
301312

302-
static CborError value_to_pretty(FILE *out, CborValue *it, int flags)
313+
static CborError value_to_pretty(FILE *out, CborValue *it, int flags, int recursionsLeft)
303314
{
304315
CborError err;
305316
CborType type = cbor_value_get_type(it);
@@ -319,7 +330,7 @@ static CborError value_to_pretty(FILE *out, CborValue *it, int flags)
319330
it->ptr = recursed.ptr;
320331
return err; /* parse error */
321332
}
322-
err = container_to_pretty(out, &recursed, type, flags);
333+
err = container_to_pretty(out, &recursed, type, flags, recursionsLeft - 1);
323334
if (err) {
324335
it->ptr = recursed.ptr;
325336
return err; /* parse error */
@@ -424,7 +435,10 @@ static CborError value_to_pretty(FILE *out, CborValue *it, int flags)
424435
err = cbor_value_advance_fixed(it);
425436
if (err)
426437
return err;
427-
err = value_to_pretty(out, it, flags);
438+
if (recursionsLeft)
439+
err = value_to_pretty(out, it, flags, recursionsLeft - 1);
440+
else
441+
printRecursionLimit(out);
428442
if (err)
429443
return err;
430444
if (fprintf(out, ")") < 0)
@@ -533,7 +547,7 @@ static CborError value_to_pretty(FILE *out, CborValue *it, int flags)
533547
*/
534548
CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value)
535549
{
536-
return value_to_pretty(out, value, CborPrettyDefaultFlags);
550+
return value_to_pretty(out, value, CborPrettyDefaultFlags, CBOR_PARSER_MAX_RECURSIONS);
537551
}
538552

539553
/**
@@ -552,7 +566,7 @@ CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value)
552566
*/
553567
CborError cbor_value_to_pretty_advance_flags(FILE *out, CborValue *value, int flags)
554568
{
555-
return value_to_pretty(out, value, flags);
569+
return value_to_pretty(out, value, flags, CBOR_PARSER_MAX_RECURSIONS);
556570
}
557571

558572
/** @} */

0 commit comments

Comments
 (0)