summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/tinycbor/tests/parser/tst_parser.cpp')
-rw-r--r--src/3rdparty/tinycbor/tests/parser/tst_parser.cpp377
1 files changed, 279 insertions, 98 deletions
diff --git a/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp b/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
index 74c480bc51..2b10004faa 100644
--- a/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
+++ b/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation
+** Copyright (C) 2019 Intel Corporation
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
@@ -23,11 +23,22 @@
****************************************************************************/
#define _XOPEN_SOURCE 700
+#define _DARWIN_C_SOURCE 1 /* need MAP_ANON */
#include <QtTest>
#include "cbor.h"
#include <stdio.h>
#include <stdarg.h>
+#if defined(Q_OS_UNIX)
+# include <sys/mman.h>
+# include <unistd.h>
+#elif defined(Q_OS_WIN)
+# define WIN32_LEAN_AND_MEAN 1
+# define NOMINMAX 1
+# include <windows.h>
+#endif
+
+
namespace QTest {
template<> char *toString<CborError>(const CborError &err)
{
@@ -44,6 +55,8 @@ private slots:
// parsing API
void integers_data();
void integers();
+ void halfFloat_data();
+ void halfFloat();
void fixed_data();
void fixed();
void strings_data();
@@ -105,6 +118,100 @@ private slots:
void recursionLimit();
};
+struct ParserWrapper
+{
+ void *realdata = nullptr;
+ uint8_t *data;
+ size_t len;
+ CborParser parser;
+ CborValue first;
+
+ ~ParserWrapper() { freeMemory(); }
+
+ CborError init(const QByteArray &ba, uint32_t flags = 0)
+ {
+ return init(ba.constData(), ba.size(), flags);
+ }
+ CborError init(const char *ptr, int n, uint32_t flags = 0)
+ {
+ freeMemory();
+ data = allocateMemory(n);
+ memcpy(data, ptr, len);
+ return cbor_parser_init(data, len, flags, &parser, &first);
+ }
+ uint8_t *begin() { return data; }
+ uint8_t *end() { return data + len; }
+
+ uint8_t *allocateMemory(size_t);
+ void freeMemory();
+
+ static const size_t PageSize = 4096;
+ static inline size_t mmapAllocation(size_t n)
+ {
+ // round up and add one page
+ return (n + 2*PageSize) & ~(PageSize - 1);
+ }
+ static bool shouldUseMmap();
+};
+
+bool ParserWrapper::shouldUseMmap()
+{
+ static int v = qEnvironmentVariableIntValue("PARSER_NO_MMAP");
+ return !v;
+}
+
+uint8_t *ParserWrapper::allocateMemory(size_t n)
+{
+ len = n;
+ if (shouldUseMmap()) {
+ size_t alloc = mmapAllocation(n);
+#if defined(Q_OS_UNIX)
+ realdata = mmap(nullptr, alloc, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ Q_ASSERT_X(realdata != MAP_FAILED, "allocateMemory", "mmap failed!");
+
+ // mark last page inaccessible
+ uint8_t *ptr = static_cast<uint8_t *>(realdata);
+ ptr += alloc - PageSize;
+ mprotect(ptr, PageSize, PROT_NONE);
+
+ ptr -= n;
+ return ptr;
+#elif defined(Q_OS_WIN)
+ DWORD flAllocationType = MEM_COMMIT | MEM_RESERVE;
+ DWORD flProtect = PAGE_READWRITE;
+ realdata = VirtualAlloc(nullptr, alloc, flAllocationType, flProtect);
+ Q_ASSERT_X(realdata, "allocateMemory", "VirtualAlloc failed!");
+
+ // mark last page inaccessible
+ uint8_t *ptr = static_cast<uint8_t *>(realdata);
+ ptr += alloc - PageSize;
+ VirtualProtect(ptr, PageSize, PAGE_NOACCESS, nullptr);
+
+ ptr -= n;
+ return ptr;
+#endif
+ }
+ realdata = malloc(n);
+ return static_cast<uint8_t *>(realdata);
+}
+
+void ParserWrapper::freeMemory()
+{
+ if (shouldUseMmap()) {
+ if (realdata) {
+#if defined(Q_OS_UNIX)
+ size_t alloc = mmapAllocation(len);
+ munmap(realdata, alloc);
+#elif defined(Q_OS_WIN)
+ VirtualFree(realdata, 0, MEM_RELEASE);
+#endif
+ }
+ return;
+ }
+
+ free(realdata);
+}
+
static CborError qstring_printf(void *out, const char *fmt, ...)
{
auto str = static_cast<QString *>(out);
@@ -166,47 +273,46 @@ bool compareFailed = true;
void compareOne_real(const QByteArray &data, const QString &expected, int line, int n = -1)
{
compareFailed = true;
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
- if (cbor_value_get_type(&first) == CborArrayType) {
+ if (cbor_value_get_type(&w.first) == CborArrayType) {
size_t len;
if (n >= 0) {
- QVERIFY(cbor_value_is_length_known(&first));
- QCOMPARE(cbor_value_get_array_length(&first, &len), CborNoError);
+ QVERIFY(cbor_value_is_length_known(&w.first));
+ QCOMPARE(cbor_value_get_array_length(&w.first, &len), CborNoError);
QCOMPARE(len, size_t(len));
} else {
- QVERIFY(!cbor_value_is_length_known(&first));
- QCOMPARE(cbor_value_get_array_length(&first, &len), CborErrorUnknownLength);
+ QVERIFY(!cbor_value_is_length_known(&w.first));
+ QCOMPARE(cbor_value_get_array_length(&w.first, &len), CborErrorUnknownLength);
}
- } else if (cbor_value_get_type(&first) == CborMapType) {
+ } else if (cbor_value_get_type(&w.first) == CborMapType) {
size_t len;
if (n >= 0) {
- QVERIFY(cbor_value_is_length_known(&first));
- QCOMPARE(cbor_value_get_map_length(&first, &len), CborNoError);
+ QVERIFY(cbor_value_is_length_known(&w.first));
+ QCOMPARE(cbor_value_get_map_length(&w.first, &len), CborNoError);
QCOMPARE(len, size_t(len));
} else {
- QVERIFY(!cbor_value_is_length_known(&first));
- QCOMPARE(cbor_value_get_map_length(&first, &len), CborErrorUnknownLength);
+ QVERIFY(!cbor_value_is_length_known(&w.first));
+ QCOMPARE(cbor_value_get_map_length(&w.first, &len), CborErrorUnknownLength);
}
- } else if (cbor_value_is_text_string(&first) || cbor_value_is_byte_string(&first)) {
+ } else if (cbor_value_is_text_string(&w.first) || cbor_value_is_byte_string(&w.first)) {
size_t len;
- QCOMPARE(cbor_value_calculate_string_length(&first, &len), CborNoError);
- if (cbor_value_is_length_known(&first)) {
+ QCOMPARE(cbor_value_calculate_string_length(&w.first, &len), CborNoError);
+ if (cbor_value_is_length_known(&w.first)) {
size_t len2;
- QCOMPARE(cbor_value_get_string_length(&first, &len2), CborNoError);
+ QCOMPARE(cbor_value_get_string_length(&w.first, &len2), CborNoError);
QCOMPARE(len2, len);
} else {
- QCOMPARE(cbor_value_get_string_length(&first, &len), CborErrorUnknownLength);
+ QCOMPARE(cbor_value_get_string_length(&w.first, &len), CborErrorUnknownLength);
}
}
- CborError err2 = cbor_value_validate_basic(&first);
+ CborError err2 = cbor_value_validate_basic(&w.first);
QString decoded;
- err = parseOne(&first, &decoded);
+ err = parseOne(&w.first, &decoded);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) +
"\"; decoded stream:\n" + decoded.toLatin1());
QCOMPARE(decoded, expected);
@@ -215,7 +321,7 @@ void compareOne_real(const QByteArray &data, const QString &expected, int line,
QCOMPARE(err2, err);
// check that we consumed everything
- QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
+ QCOMPARE((void*)cbor_value_get_next_byte(&w.first), (void*)w.end());
compareFailed = false;
}
@@ -237,39 +343,112 @@ void tst_Parser::integers()
QFETCH(qint64, expectedValue);
QFETCH(bool, inInt64Range);
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- QVERIFY(cbor_value_is_integer(&first));
+ QVERIFY(cbor_value_is_integer(&w.first));
uint64_t raw;
- cbor_value_get_raw_integer(&first, &raw);
+ cbor_value_get_raw_integer(&w.first, &raw);
QCOMPARE(quint64(raw), expectedRaw);
if (isNegative) {
- QVERIFY(cbor_value_is_negative_integer(&first));
- QVERIFY(!cbor_value_is_unsigned_integer(&first));
+ QVERIFY(cbor_value_is_negative_integer(&w.first));
+ QVERIFY(!cbor_value_is_unsigned_integer(&w.first));
} else {
- QVERIFY(!cbor_value_is_negative_integer(&first));
- QVERIFY(cbor_value_is_unsigned_integer(&first));
+ QVERIFY(!cbor_value_is_negative_integer(&w.first));
+ QVERIFY(cbor_value_is_unsigned_integer(&w.first));
}
int64_t value;
if (inInt64Range) {
- cbor_value_get_int64(&first, &value);
+ cbor_value_get_int64(&w.first, &value);
QCOMPARE(qint64(value), expectedValue);
}
- err = cbor_value_get_int64_checked(&first, &value);
+ err = cbor_value_get_int64_checked(&w.first, &value);
QCOMPARE(err, inInt64Range ? CborNoError : CborErrorDataTooLarge);
int ivalue;
bool inIntRange = inInt64Range && (expectedValue == int(expectedValue));
- err = cbor_value_get_int_checked(&first, &ivalue);
+ err = cbor_value_get_int_checked(&w.first, &ivalue);
QCOMPARE(err, inIntRange ? CborNoError : CborErrorDataTooLarge);
}
+static void addHalfFloat()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<unsigned>("expectedRaw");
+ QTest::addColumn<double>("expectedValue");
+
+ QTest::newRow("+0") << raw("\x00\x00") << 0U << 0.0;
+ QTest::newRow("-0") << raw("\x80\x00") << 0x8000U << 0.0;
+
+ QTest::newRow("min.denorm") << raw("\x00\x01") << 1U << ldexp(1.0, -14) * ldexp(1.0, -10);
+ QTest::newRow("-min.denorm") << raw("\x80\x01") << 0x8001U << ldexp(-1.0, -14) * ldexp(1.0, -10);
+
+ QTest::newRow("max.denorm") << raw("\x03\xff") << 0x03ffU << ldexp(1.0, -14) * (1.0 - ldexp(1.0, -10));
+ QTest::newRow("-max.denorm") << raw("\x83\xff") << 0x83ffU << ldexp(-1.0, -14) * (1.0 - ldexp(1.0, -10));
+
+ QTest::newRow("min.norm") << raw("\x04\x00") << 0x0400U << ldexp(1.0, -14);
+ QTest::newRow("-min.norm") << raw("\x84\x00") << 0x8400U << ldexp(-1.0, -14);
+
+ QTest::newRow("1.0") << raw("\x3c\x00") << 0x3c00U << 1.0;
+ QTest::newRow("-1.0") << raw("\xbc\x00") << 0xbc00U << -1.0;
+
+ QTest::newRow("1.5") << raw("\x3e\x00") << 0x3e00U << 1.5;
+ QTest::newRow("-1.5") << raw("\xbe\x00") << 0xbe00U << -1.5;
+
+ QTest::newRow("max") << raw("\x7b\xff") << 0x7bffU << ldexp(1.0, 15) * (2.0 - ldexp(1.0, -10));
+ QTest::newRow("-max") << raw("\xfb\xff") << 0xfbffU << ldexp(-1.0, 15) * (2.0 - ldexp(1.0, -10));
+
+ QTest::newRow("inf") << raw("\x7c\x00") << 0x7c00U << double(INFINITY);
+ QTest::newRow("-inf") << raw("\xfc\x00") << 0xfc00U << double(-INFINITY);
+
+ QTest::newRow("nan") << raw("\x7c\x01") << 0x7c01U << double(NAN);
+ QTest::newRow("nan2") << raw("\xfc\x01") << 0xfc01U << double(NAN);
+ QTest::newRow("nan3") << raw("\x7e\x00") << 0x7e00U << double(NAN);
+ QTest::newRow("nan4") << raw("\xfe\x00") << 0xfe00U << double(NAN);
+}
+
+void tst_Parser::halfFloat_data()
+{
+ addHalfFloat();
+}
+
+void tst_Parser::halfFloat()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(unsigned, expectedRaw);
+ QFETCH(double, expectedValue);
+
+ CborParser parser;
+ CborValue first;
+
+ data.prepend('\xf9');
+
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QVERIFY(cbor_value_is_half_float(&first));
+
+ uint16_t raw;
+ cbor_value_get_half_float(&first, &raw);
+ QCOMPARE(raw, uint16_t(expectedRaw));
+
+ float value;
+ cbor_value_get_half_float_as_float(&first, &value);
+
+ const double epsilon = ldexp(1.0, -25);
+
+ if (qIsNaN(expectedValue)) {
+ QVERIFY(qIsNaN(value));
+ } else if (qIsInf(expectedValue)) {
+ QVERIFY(value == (float)expectedValue);
+ } else {
+ QVERIFY(qAbs(value - (float)expectedValue) < epsilon);
+ }
+}
+
void tst_Parser::fixed_data()
{
addColumns();
@@ -678,14 +857,13 @@ void tst_Parser::chunkedString_data()
static void chunkedStringTest(const QByteArray &data, const QString &concatenated,
QStringList &chunks, CborType ourType)
{
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
CborValue value;
- QVERIFY(cbor_value_is_array(&first));
- err = cbor_value_enter_container(&first, &value);
+ QVERIFY(cbor_value_is_array(&w.first));
+ err = cbor_value_enter_container(&w.first, &value);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
QVERIFY(cbor_value_is_byte_string(&value) || cbor_value_is_text_string(&value));
@@ -748,9 +926,9 @@ static void chunkedStringTest(const QByteArray &data, const QString &concatenate
// confirm EOF
QVERIFY(cbor_value_at_end(&value));
- err = cbor_value_leave_container(&first, &value);
+ err = cbor_value_leave_container(&w.first, &value);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
+ QCOMPARE((void*)cbor_value_get_next_byte(&w.first), (void*)w.end());
}
void tst_Parser::chunkedString()
@@ -840,18 +1018,17 @@ void tst_Parser::stringLength()
QFETCH(QByteArray, data);
QFETCH(int, expected);
- CborParser parser;
- CborValue value;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
size_t result;
- err = cbor_value_calculate_string_length(&value, &result);
+ err = cbor_value_calculate_string_length(&w.first, &result);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
QCOMPARE(result, size_t(expected));
- if (cbor_value_is_length_known(&value)) {
- QCOMPARE(cbor_value_get_string_length(&value, &result), CborNoError);
+ if (cbor_value_is_length_known(&w.first)) {
+ QCOMPARE(cbor_value_get_string_length(&w.first, &result), CborNoError);
QCOMPARE(result, size_t(expected));
}
@@ -935,25 +1112,24 @@ void compareOneString(const QByteArray &data, const QString &string, bool expect
{
compareFailed = true;
- CborParser parser;
- CborValue value;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
bool result;
QByteArray bastring = string.toUtf8();
- err = cbor_value_text_string_equals(&value, bastring.constData(), &result);
+ err = cbor_value_text_string_equals(&w.first, bastring.constData(), &result);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
QCOMPARE(result, expected);
if (expected) {
size_t len;
- cbor_value_skip_tag(&value);
- if (cbor_value_is_length_known(&value)) {
- QCOMPARE(cbor_value_get_string_length(&value, &len), CborNoError);
+ cbor_value_skip_tag(&w.first);
+ if (cbor_value_is_length_known(&w.first)) {
+ QCOMPARE(cbor_value_get_string_length(&w.first, &len), CborNoError);
QCOMPARE(int(len), bastring.size());
}
- QCOMPARE(cbor_value_calculate_string_length(&value, &len), CborNoError);
+ QCOMPARE(cbor_value_calculate_string_length(&w.first, &len), CborNoError);
QCOMPARE(int(len), bastring.size());
}
@@ -1042,13 +1218,12 @@ void tst_Parser::mapFind()
QFETCH(QByteArray, data);
QFETCH(bool, expected);
- CborParser parser;
- CborValue value;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
CborValue element;
- err = cbor_value_map_find_value(&value, "needle", &element);
+ err = cbor_value_map_find_value(&w.first, "needle", &element);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
if (expected) {
@@ -1119,13 +1294,12 @@ void tst_Parser::checkedIntegers()
QFETCH(QVariant, result);
int64_t expected = result.toLongLong();
- CborParser parser;
- CborValue value;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
int64_t v;
- err = cbor_value_get_int64_checked(&value, &v);
+ err = cbor_value_get_int64_checked(&w.first, &v);
if (result.isNull()) {
QCOMPARE(err, CborErrorDataTooLarge);
} else {
@@ -1133,7 +1307,7 @@ void tst_Parser::checkedIntegers()
}
int v2;
- err = cbor_value_get_int_checked(&value, &v2);
+ err = cbor_value_get_int_checked(&w.first, &v2);
if (result.isNull() || expected < std::numeric_limits<int>::min() || expected > std::numeric_limits<int>::max()) {
QCOMPARE(err, CborErrorDataTooLarge);
} else {
@@ -1154,14 +1328,13 @@ void tst_Parser::validation()
QFETCH(CborError, expectedError);
QString decoded;
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), flags, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data, uint32_t(flags));
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- CborError err2 = cbor_value_validate_basic(&first);
- CborError err3 = cbor_value_validate(&first, CborValidateBasic);
- err = parseOne(&first, &decoded);
+ CborError err2 = cbor_value_validate_basic(&w.first);
+ CborError err3 = cbor_value_validate(&w.first, CborValidateBasic);
+ err = parseOne(&w.first, &decoded);
QCOMPARE(err, expectedError);
if (!QByteArray(QTest::currentDataTag()).contains("utf8")) {
QCOMPARE(err2, expectedError);
@@ -1352,24 +1525,36 @@ void tst_Parser::strictValidation_data()
QTest::newRow("overlong-_stringx2-0*8") << raw("\x7f\x60\x7b\0\0\0\0\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
// strict mode
- QTest::newRow("invalid-utf8-1char") << raw("\x61\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-2chars-1") << raw("\x62\xc2\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-2chars-2") << raw("\x62\xc3\xdf") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-2chars-3") << raw("\x62\xc7\xf0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-3chars-1") << raw("\x63\xe0\xa0\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-3chars-2") << raw("\x63\xe0\xc0\xa0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-4chars-1") << raw("\x64\xf0\x90\x80\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-4chars-2") << raw("\x64\xf0\x90\xc0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
- QTest::newRow("invalid-utf8-4chars-3") << raw("\x64\xf0\xc0\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // UTF-8 sequences with invalid continuation bytes
+ QTest::newRow("invalid-utf8-bad-continuation-1char") << raw("\x61\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-2chars-1") << raw("\x62\xc2\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-2chars-2") << raw("\x62\xc3\xdf") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-2chars-3") << raw("\x62\xc7\xf0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-3chars-1") << raw("\x63\xe0\xa0\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-3chars-2") << raw("\x63\xe0\xc0\xa0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-4chars-1") << raw("\x64\xf0\x90\x80\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-4chars-2") << raw("\x64\xf0\x90\xc0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-bad-continuation-4chars-3") << raw("\x64\xf0\xc0\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // Too short UTF-8 sequences (in an array so there's a byte after that would make it valid UTF-8 if it were part of the string)
+ QTest::newRow("invalid-utf8-too-short-2chars") << raw("\x82\x61\xc2\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-too-short-3chars-1") << raw("\x82\x61\xe0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-too-short-3chars-2") << raw("\x82\x62\xe0\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-too-short-4chars-1") << raw("\x82\x61\xf0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-too-short-4chars-2") << raw("\x82\x62\xf0\x90\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-too-short-4chars-3") << raw("\x82\x63\xf0\x90\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // UTF-16 surrogages encoded in UTF-8
QTest::newRow("invalid-utf8-hi-surrogate") << raw("\x63\xed\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-lo-surrogate") << raw("\x63\xed\xb0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-surrogate-pair") << raw("\x66\xed\xa0\x80\xed\xb0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // Non-Unicode UTF-8 sequences
QTest::newRow("invalid-utf8-non-unicode-1") << raw("\x64\xf4\x90\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-non-unicode-2") << raw("\x65\xf8\x88\x80\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-non-unicode-3") << raw("\x66\xfc\x84\x80\x80\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-non-unicode-4") << raw("\x66\xfd\xbf\xbf\xbf\xbf\xbf") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // invalid bytes in UTF-8
QTest::newRow("invalid-utf8-fe") << raw("\x61\xfe") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-ff") << raw("\x61\xff") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ // Overlong sequences
QTest::newRow("invalid-utf8-overlong-1-2") << raw("\x62\xc1\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-overlong-1-3") << raw("\x63\xe0\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
QTest::newRow("invalid-utf8-overlong-1-4") << raw("\x64\xf0\x80\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
@@ -1525,12 +1710,11 @@ void tst_Parser::strictValidation()
QFETCH(CborError, expectedError);
QString decoded;
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- err = cbor_value_validate(&first, flags);
+ err = cbor_value_validate(&w.first, flags);
QCOMPARE(err, expectedError);
}
@@ -1549,12 +1733,11 @@ void tst_Parser::incompleteData()
QFETCH(QString, expected);
for (int len = 0; len < data.length() - 1; ++len) {
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), len, 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data.constData(), len);
if (!err) {
QString decoded;
- err = parseOne(&first, &decoded);
+ err = parseOne(&w.first, &decoded);
}
if (err != CborErrorUnexpectedEOF)
qDebug() << "Length is" << len;
@@ -1583,14 +1766,13 @@ void tst_Parser::endPointer()
QFETCH(int, offset);
QString decoded;
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- err = parseOne(&first, &decoded);
+ err = parseOne(&w.first, &decoded);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
- QCOMPARE(int(cbor_value_get_next_byte(&first) - reinterpret_cast<const quint8 *>(data.constBegin())), offset);
+ QCOMPARE(int(cbor_value_get_next_byte(&w.first) - w.begin()), offset);
}
void tst_Parser::recursionLimit_data()
@@ -1638,24 +1820,23 @@ void tst_Parser::recursionLimit()
{
QFETCH(QByteArray, data);
- CborParser parser;
- CborValue first;
- CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ ParserWrapper w;
+ CborError err = w.init(data);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
// check that it is valid:
- CborValue it = first;
+ CborValue it = w.first;
{
QString dummy;
err = parseOne(&it, &dummy);
QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
}
- it = first;
+ it = w.first;
err = cbor_value_advance(&it);
QCOMPARE(err, CborErrorNestingTooDeep);
- it = first;
+ it = w.first;
if (cbor_value_is_map(&it)) {
CborValue dummy;
err = cbor_value_map_find_value(&it, "foo", &dummy);