Skip to content

Commit 7388112

Browse files
Add an API to verify that a CborValue is valid
This is the first of two functions and this one does only a basic validation, which ensures that parsing will be ok, with no errors. Signed-off-by: Thiago Macieira <[email protected]>
1 parent 4841bc4 commit 7388112

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/cbor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ typedef struct CborValue CborValue;
248248

249249
CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it);
250250

251+
CBOR_API CborError cbor_value_validate_basic(const CborValue *it);
252+
251253
CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
252254
{ return it->remaining == 0; }
253255
CBOR_INLINE_API const uint8_t *cbor_value_get_next_byte(const CborValue *it)

src/cborparser.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,33 @@ CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborPa
420420
* \sa cbor_value_advance(), cbor_valie_at_end(), cbor_value_get_type()
421421
*/
422422

423+
/**
424+
* Performs a basic validation of the CBOR stream pointed by \a it and returns
425+
* the error it found. If no error was found, it returns CborNoError and the
426+
* application can iterate over the items with certainty that no other errors
427+
* will appear during parsing.
428+
*
429+
* A basic validation checks for:
430+
* \list
431+
* \li absence of undefined additional information bytes;
432+
* \li well-formedness of all numbers, lengths, and simple values;
433+
* \li string contents match reported sizes;
434+
* \li arrays and maps contain the number of elements they are reported to have;
435+
* \endlist
436+
*
437+
* For further checks, see cbor_value_validate().
438+
*
439+
* This function has the same timing and memory requirements as
440+
* cbor_value_advance().
441+
*
442+
* \sa cbor_value_validate(), cbor_value_advance()
443+
*/
444+
CborError cbor_value_validate_basic(const CborValue *it)
445+
{
446+
CborValue value = *it;
447+
return cbor_value_advance(&value);
448+
}
449+
423450
/**
424451
* Advances the CBOR value \a it by one fixed-size position. Fixed-size types
425452
* are: integers, tags, simple types (including boolean, null and undefined
@@ -481,6 +508,9 @@ static CborError advance_recursive(CborValue *it, int nestingLevel)
481508
* elements or chunks and will use O(n) memory for the number of nested
482509
* containers).
483510
*
511+
* The number of recursions can be limited at compile time to avoid stack
512+
* exhaustion in constrained systems.
513+
*
484514
* \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_enter_container(), cbor_value_leave_container()
485515
*/
486516
CborError cbor_value_advance(CborValue *it)

tests/parser/tst_parser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,17 @@ void compareOne_real(const QByteArray &data, const QString &expected, int line,
222222
}
223223
}
224224

225+
CborError err2 = cbor_value_validate_basic(&first);
226+
225227
QString decoded;
226228
err = parseOne(&first, &decoded);
227229
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) +
228230
"\"; decoded stream:\n" + decoded.toLatin1());
229231
QCOMPARE(decoded, expected);
230232

233+
// check that the errors are the same
234+
QCOMPARE(int(err2), int(err));
235+
231236
// check that we consumed everything
232237
QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
233238

@@ -1520,8 +1525,11 @@ void tst_Parser::validation()
15201525
CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), flags, &parser, &first);
15211526
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
15221527

1528+
CborError err2 = cbor_value_validate_basic(&first);
15231529
err = parseOne(&first, &decoded);
15241530
QCOMPARE(int(err), int(expectedError));
1531+
if (!QByteArray(QTest::currentDataTag()).contains("utf8"))
1532+
QCOMPARE(int(err2), int(expectedError));
15251533
}
15261534

15271535
void tst_Parser::resumeParsing_data()

0 commit comments

Comments
 (0)