1 /****************************************************************************
3 ** Copyright (C) 2015 Intel Corporation
5 ** Permission is hereby granted, free of charge, to any person obtaining a copy
6 ** of this software and associated documentation files (the "Software"), to deal
7 ** in the Software without restriction, including without limitation the rights
8 ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 ** copies of the Software, and to permit persons to whom the Software is
10 ** furnished to do so, subject to the following conditions:
12 ** The above copyright notice and this permission notice shall be included in
13 ** all copies or substantial portions of the Software.
15 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 ****************************************************************************/
25 #define _XOPEN_SOURCE 700
31 extern "C" FILE *open_memstream(char **bufptr, size_t *sizeptr);
33 Q_DECLARE_METATYPE(CborError)
35 class tst_Parser : public QObject
39 void initParserEmpty();
45 void strings() { fixed(); }
47 void tags() { fixed(); }
48 void tagTags_data() { tags_data(); }
50 void emptyContainers_data();
51 void emptyContainers();
54 void undefLengthArrays_data() { arrays_data(); }
55 void undefLengthArrays();
56 void nestedArrays_data() { arrays_data(); }
60 void undefLengthMaps_data() { maps_data(); }
61 void undefLengthMaps();
62 void nestedMaps_data() { maps_data(); }
65 void mapMixed() { arrays(); }
66 void mapsAndArrays_data() { arrays_data(); }
70 void stringLength_data();
72 void stringCompare_data();
77 // validation & errors
78 void validation_data();
80 void resumeParsing_data();
82 void endPointer_data();
84 void recursionLimit_data();
85 void recursionLimit();
88 CborError parseOne(CborValue *it, QString *parsed)
94 setlocale(LC_ALL, "C");
95 FILE *f = open_memstream(&buffer, &size);
96 err = cbor_value_to_pretty_advance(f, it);
99 *parsed = QString::fromLatin1(buffer, size);
104 template <size_t N> QByteArray raw(const char (&data)[N])
106 return QByteArray::fromRawData(data, N - 1);
109 void tst_Parser::initParserEmpty()
113 CborError err = cbor_parser_init((const quint8 *)"", 0, 0, &parser, &first);
114 QCOMPARE(err, CborErrorUnexpectedEOF);
119 QTest::addColumn<QByteArray>("data");
120 QTest::addColumn<QString>("expected");
121 QTest::addColumn<int>("n"); // some aux integer, not added in all columns
124 bool compareFailed = true;
125 void compareOne_real(const QByteArray &data, const QString &expected, int line, int n = -1)
127 compareFailed = true;
130 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
131 QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
133 if (cbor_value_get_type(&first) == CborArrayType) {
136 QCOMPARE(cbor_value_get_array_length(&first, &len), CborNoError);
137 QCOMPARE(len, size_t(len));
139 QCOMPARE(cbor_value_get_array_length(&first, &len), CborErrorUnknownLength);
141 } else if (cbor_value_get_type(&first) == CborMapType) {
144 QCOMPARE(cbor_value_get_map_length(&first, &len), CborNoError);
145 QCOMPARE(len, size_t(len));
147 QCOMPARE(cbor_value_get_map_length(&first, &len), CborErrorUnknownLength);
152 err = parseOne(&first, &decoded);
153 QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) +
154 "\"; decoded stream:\n" + decoded.toLatin1());
155 QCOMPARE(decoded, expected);
157 // check that we consumed everything
158 QCOMPARE((void*)first.ptr, (void*)data.constEnd());
160 compareFailed = false;
162 #define compareOne(data, expected) compareOne_real(data, expected, __LINE__)
163 #define compareOneSize(n, data, expected) compareOne_real(data, expected, __LINE__, n)
168 QTest::newRow("0") << raw("\x00") << "0";
169 QTest::newRow("1") << raw("\x01") << "1";
170 QTest::newRow("10") << raw("\x0a") << "10";
171 QTest::newRow("23") << raw("\x17") << "23";
172 QTest::newRow("24") << raw("\x18\x18") << "24";
173 QTest::newRow("UINT8_MAX") << raw("\x18\xff") << "255";
174 QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << "256";
175 QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << "65535";
176 QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << "65536";
177 QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << "4294967295";
178 QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << "4294967296";
179 QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
180 << QString::number(std::numeric_limits<uint64_t>::max());
183 QTest::newRow("-1") << raw("\x20") << "-1";
184 QTest::newRow("-2") << raw("\x21") << "-2";
185 QTest::newRow("-24") << raw("\x37") << "-24";
186 QTest::newRow("-25") << raw("\x38\x18") << "-25";
187 QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << "-256";
188 QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << "-257";
189 QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << "-65536";
190 QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << "-65537";
191 QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << "-4294967296";
192 QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << "-4294967297";
193 QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
194 << QString::number(std::numeric_limits<int64_t>::min() + 1);
195 QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
196 << QString::number(std::numeric_limits<int64_t>::min());
197 QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << "-9223372036854775809";
198 QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
199 << '-' + QString::number(std::numeric_limits<uint64_t>::max());
200 QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
201 << "-18446744073709551616";
204 QTest::newRow("0*1") << raw("\x18\x00") << "0";
205 QTest::newRow("0*2") << raw("\x19\x00\x00") << "0";
206 QTest::newRow("0*4") << raw("\x1a\0\0\0\0") << "0";
207 QTest::newRow("0*8") << raw("\x1b\0\0\0\0\0\0\0\0") << "0";
208 QTest::newRow("-1*1") << raw("\x38\x00") << "-1";
209 QTest::newRow("-1*2") << raw("\x39\x00\x00") << "-1";
210 QTest::newRow("-1*4") << raw("\x3a\0\0\0\0") << "-1";
211 QTest::newRow("-1*8") << raw("\x3b\0\0\0\0\0\0\0\0") << "-1";
213 QTest::newRow("simple0") << raw("\xe0") << "simple(0)";
214 QTest::newRow("simple19") << raw("\xf3") << "simple(19)";
215 QTest::newRow("false") << raw("\xf4") << "false";
216 QTest::newRow("true") << raw("\xf5") << "true";
217 QTest::newRow("null") << raw("\xf6") << "null";
218 QTest::newRow("undefined") << raw("\xf7") << "undefined";
219 QTest::newRow("simple32") << raw("\xf8\x20") << "simple(32)";
220 QTest::newRow("simple255") << raw("\xf8\xff") << "simple(255)";
224 QTest::newRow("0.f16") << raw("\xf9\0\0") << "0.f16";
225 QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "0.f";
226 QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "0.";
227 QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "-1.f16";
228 QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "-1.f";
229 QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "-1.";
230 QTest::newRow("65504.f16") << raw("\xf9\x7b\xff") << "65504.f16";
231 QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
232 QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "16777215.";
233 QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "-16777215.f";
234 QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "-16777215.";
236 QTest::newRow("0.5f16") << raw("\xf9\x38\0") << "0.5f16";
237 QTest::newRow("0.5f") << raw("\xfa\x3f\0\0\0") << "0.5f";
238 QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << "0.5";
239 QTest::newRow("2.f16^11-1") << raw("\xf9\x67\xff") << "2047.f16";
240 QTest::newRow("2.f^24-1") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
241 QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "9007199254740991.";
242 QTest::newRow("2.f^64-epsilon") << raw("\xfa\x5f\x7f\xff\xff") << "18446742974197923840.f";
243 QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "18446744073709549568.";
244 QTest::newRow("2.f^64") << raw("\xfa\x5f\x80\0\0") << "1.8446744073709552e+19f";
245 QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << "1.8446744073709552e+19";
247 QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "nan";
248 QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "nan";
249 QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "nan";
250 QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "-inf";
251 QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "-inf";
252 QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "-inf";
253 QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "inf";
254 QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "inf";
255 QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "inf";
259 void tst_Parser::fixed_data()
265 void tst_Parser::fixed()
267 QFETCH(QByteArray, data);
268 QFETCH(QString, expected);
270 compareOne(data, expected);
273 void addStringsData()
276 QTest::newRow("emptybytestring") << raw("\x40") << "h''";
277 QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'";
278 QTest::newRow("bytestring1-nul") << raw("\x41\0") << "h'00'";
279 QTest::newRow("bytestring5") << raw("\x45Hello") << "h'48656c6c6f'";
280 QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
281 << "h'313233343536373839303132333435363738393031323334'";
282 QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3')
283 << "h'" + QString(256 * 2, '3') + '\'';
286 QTest::newRow("emptytextstring") << raw("\x60") << "\"\"";
287 QTest::newRow("textstring1") << raw("\x61 ") << "\" \"";
288 QTest::newRow("textstring1-nul") << raw("\x61\0") << "\"\\u0000\"";
289 QTest::newRow("textstring5") << raw("\x65Hello") << "\"Hello\"";
290 QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
291 << "\"123456789012345678901234\"";
292 QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
293 << '"' + QString(256, '3') + '"';
295 // strings with overlong length
296 QTest::newRow("emptybytestring*1") << raw("\x58\x00") << "h''";
297 QTest::newRow("emptytextstring*1") << raw("\x78\x00") << "\"\"";
298 QTest::newRow("emptybytestring*2") << raw("\x59\x00\x00") << "h''";
299 QTest::newRow("emptytextstring*2") << raw("\x79\x00\x00") << "\"\"";
300 QTest::newRow("emptybytestring*4") << raw("\x5a\0\0\0\0") << "h''";
301 QTest::newRow("emptytextstring*4") << raw("\x7a\0\0\0\0") << "\"\"";
302 QTest::newRow("emptybytestring*8") << raw("\x5b\0\0\0\0\0\0\0\0") << "h''";
303 QTest::newRow("emptytextstring*8") << raw("\x7b\0\0\0\0\0\0\0\0") << "\"\"";
304 QTest::newRow("bytestring5*1") << raw("\x58\x05Hello") << "h'48656c6c6f'";
305 QTest::newRow("textstring5*1") << raw("\x78\x05Hello") << "\"Hello\"";
306 QTest::newRow("bytestring5*2") << raw("\x59\0\5Hello") << "h'48656c6c6f'";
307 QTest::newRow("textstring5*2") << raw("\x79\0\x05Hello") << "\"Hello\"";
308 QTest::newRow("bytestring5*4") << raw("\x5a\0\0\0\5Hello") << "h'48656c6c6f'";
309 QTest::newRow("textstring5*4") << raw("\x7a\0\0\0\x05Hello") << "\"Hello\"";
310 QTest::newRow("bytestring5*8") << raw("\x5b\0\0\0\0\0\0\0\5Hello") << "h'48656c6c6f'";
311 QTest::newRow("textstring5*8") << raw("\x7b\0\0\0\0\0\0\0\x05Hello") << "\"Hello\"";
313 // strings with undefined length
314 QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "h''";
315 QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "\"\"";
316 QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "h''";
317 QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "\"\"";
318 QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "h''";
319 QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "\"\"";
320 QTest::newRow("_bytestring5*2") << raw("\x5f\x43Hel\x42lo\xff") << "h'48656c6c6f'";
321 QTest::newRow("_textstring5*2") << raw("\x7f\x63Hel\x62lo\xff") << "\"Hello\"";
322 QTest::newRow("_bytestring5*5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << "h'48656c6c6f'";
323 QTest::newRow("_textstring5*5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "\"Hello\"";
324 QTest::newRow("_bytestring5*6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << "h'48656c6c6f'";
325 QTest::newRow("_textstring5*6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << "\"Hello\"";
328 void tst_Parser::strings_data()
336 // since parseOne() works recursively for tags, we can't test lone tags
337 QTest::newRow("tag0") << raw("\xc0\x00") << "0(0)";
338 QTest::newRow("tag1") << raw("\xc1\x00") << "1(0)";
339 QTest::newRow("tag24") << raw("\xd8\x18\x00") << "24(0)";
340 QTest::newRow("tag255") << raw("\xd8\xff\x00") << "255(0)";
341 QTest::newRow("tag256") << raw("\xd9\1\0\x00") << "256(0)";
342 QTest::newRow("tag65535") << raw("\xd9\xff\xff\x00") << "65535(0)";
343 QTest::newRow("tag65536") << raw("\xda\0\1\0\0\x00") << "65536(0)";
344 QTest::newRow("tagUINT32_MAX-1") << raw("\xda\xff\xff\xff\xff\x00") << "4294967295(0)";
345 QTest::newRow("tagUINT32_MAX") << raw("\xdb\0\0\0\1\0\0\0\0\x00") << "4294967296(0)";
346 QTest::newRow("tagUINT64_MAX") << raw("\xdb" "\xff\xff\xff\xff" "\xff\xff\xff\xff" "\x00")
347 << QString::number(std::numeric_limits<uint64_t>::max()) + "(0)";
350 QTest::newRow("tag0*1") << raw("\xd8\0\x00") << "0(0)";
351 QTest::newRow("tag0*2") << raw("\xd9\0\0\x00") << "0(0)";
352 QTest::newRow("tag0*4") << raw("\xda\0\0\0\0\x00") << "0(0)";
353 QTest::newRow("tag0*8") << raw("\xdb\0\0\0\0\0\0\0\0\x00") << "0(0)";
356 QTest::newRow("unixtime") << raw("\xc1\x1a\x55\x4b\xbf\xd3") << "1(1431027667)";
357 QTest::newRow("rfc3339date") << raw("\xc0\x78\x19" "2015-05-07 12:41:07-07:00")
358 << "0(\"2015-05-07 12:41:07-07:00\")";
359 QTest::newRow("tag6+false") << raw("\xc6\xf4") << "6(false)";
360 QTest::newRow("tag25+true") << raw("\xd8\x19\xf5") << "25(true)";
361 QTest::newRow("tag256+null") << raw("\xd9\1\0\xf6") << "256(null)";
362 QTest::newRow("tag65536+simple32") << raw("\xda\0\1\0\0\xf8\x20") << "65536(simple(32))";
363 QTest::newRow("float+unixtime") << raw("\xc1\xfa\x4e\xaa\x97\x80") << "1(1431027712.f)";
364 QTest::newRow("double+unixtime") << raw("\xc1\xfb" "\x41\xd5\x52\xef" "\xf4\xc7\xce\xfe")
365 << "1(1431027667.1220088)";
368 void tst_Parser::tags_data()
374 void tst_Parser::tagTags()
376 QFETCH(QByteArray, data);
377 QFETCH(QString, expected);
379 compareOne("\xd9\xd9\xf7" + data, "55799(" + expected + ')');
381 compareOne("\xd9\xd9\xf7" "\xd9\xd9\xf7" + data, "55799(55799(" + expected + "))");
384 void addEmptyContainersData()
386 QTest::newRow("emptyarray") << raw("\x80") << "[]" << 0;
387 QTest::newRow("emptymap") << raw("\xa0") << "{}" << 0;
388 QTest::newRow("_emptyarray") << raw("\x9f\xff") << "[_ ]" << -1;
389 QTest::newRow("_emptymap") << raw("\xbf\xff") << "{_ }" << -1;
392 void tst_Parser::emptyContainers_data()
395 addEmptyContainersData();
398 void tst_Parser::emptyContainers()
400 QFETCH(QByteArray, data);
401 QFETCH(QString, expected);
404 compareOneSize(n, data, expected);
407 void tst_Parser::arrays_data()
415 void tst_Parser::arrays()
417 QFETCH(QByteArray, data);
418 QFETCH(QString, expected);
420 compareOneSize(1, "\x81" + data, '[' + expected + ']');
421 if (compareFailed) return;
423 compareOneSize(2, "\x82" + data + data, '[' + expected + ", " + expected + ']');
424 if (compareFailed) return;
427 compareOneSize(1, "\x98\1" + data, '[' + expected + ']');
428 if (compareFailed) return;
429 compareOneSize(1, raw("\x99\0\1") + data, '[' + expected + ']');
430 if (compareFailed) return;
431 compareOneSize(1, raw("\x9a\0\0\0\1") + data, '[' + expected + ']');
432 if (compareFailed) return;
433 compareOneSize(1, raw("\x9b\0\0\0\0\0\0\0\1") + data, '[' + expected + ']');
434 if (compareFailed) return;
436 // medium-sized array: 32 elements (1 << 5)
438 for (int i = 0; i < 5; ++i) {
440 expected += expected;
442 expected.chop(2); // remove the last ", "
443 compareOneSize(32, "\x98\x20" + data, '[' + expected + ']');
444 if (compareFailed) return;
446 // large array: 256 elements (32 << 3)
448 for (int i = 0; i < 3; ++i) {
450 expected += expected;
452 expected.chop(2); // remove the last ", "
453 compareOneSize(256, raw("\x99\1\0") + data, '[' + expected + ']');
454 if (compareFailed) return;
457 void tst_Parser::undefLengthArrays()
459 QFETCH(QByteArray, data);
460 QFETCH(QString, expected);
462 compareOne("\x9f" + data + "\xff", "[_ " + expected + ']');
463 if (compareFailed) return;
465 compareOne("\x9f" + data + data + "\xff", "[_ " + expected + ", " + expected + ']');
468 void tst_Parser::nestedArrays()
470 QFETCH(QByteArray, data);
471 QFETCH(QString, expected);
473 compareOneSize(1, "\x81\x81" + data, "[[" + expected + "]]");
474 if (compareFailed) return;
476 compareOneSize(1, "\x81\x81\x81" + data, "[[[" + expected + "]]]");
477 if (compareFailed) return;
479 compareOneSize(1, "\x81\x82" + data + data, "[[" + expected + ", " + expected + "]]");
480 if (compareFailed) return;
482 compareOneSize(2, "\x82\x81" + data + data, "[[" + expected + "], " + expected + "]");
483 if (compareFailed) return;
485 compareOneSize(2, "\x82\x81" + data + '\x81' + data, "[[" + expected + "], [" + expected + "]]");
486 if (compareFailed) return;
489 compareOneSize(-1, "\x9f\x9f" + data + data + "\xff\xff", "[_ [_ " + expected + ", " + expected + "]]");
490 if (compareFailed) return;
492 compareOneSize(-1, "\x9f\x9f" + data + "\xff\x9f" + data + "\xff\xff", "[_ [_ " + expected + "], [_ " + expected + "]]");
493 if (compareFailed) return;
495 compareOneSize(-1, "\x9f\x9f" + data + data + "\xff\x9f" + data + "\xff\xff",
496 "[_ [_ " + expected + ", " + expected + "], [_ " + expected + "]]");
497 if (compareFailed) return;
500 compareOneSize(1, "\x81\x9f" + data + "\xff", "[[_ " + expected + "]]");
501 if (compareFailed) return;
503 compareOneSize(-1, "\x9f\x81" + data + "\xff", "[_ [" + expected + "]]");
506 void tst_Parser::maps_data()
511 void tst_Parser::maps()
513 QFETCH(QByteArray, data);
514 QFETCH(QString, expected);
517 compareOneSize(1, "\xa1\1" + data, "{1: " + expected + '}');
518 if (compareFailed) return;
521 compareOneSize(1, "\xa1\x65" "Hello" + data, "{\"Hello\": " + expected + '}');
522 if (compareFailed) return;
525 compareOneSize(1, "\xa1" + data + data, '{' + expected + ": " + expected + '}');
526 if (compareFailed) return;
529 compareOneSize(2, "\xa2\1" + data + "\2" + data, "{1: " + expected + ", 2: " + expected + '}');
530 if (compareFailed) return;
532 // OneSize integer and OneSize string key
533 compareOneSize(2, "\xa2\1" + data + "\x65" "Hello" + data, "{1: " + expected + ", \"Hello\": " + expected + '}');
534 if (compareFailed) return;
537 void tst_Parser::undefLengthMaps()
539 QFETCH(QByteArray, data);
540 QFETCH(QString, expected);
543 compareOne("\xbf\1" + data + '\xff', "{_ 1: " + expected + '}');
544 if (compareFailed) return;
546 compareOne("\xbf\1" + data + '\2' + data + '\xff', "{_ 1: " + expected + ", 2: " + expected + '}');
547 if (compareFailed) return;
549 compareOne("\xbf\1" + data + "\x65Hello" + data + '\xff', "{_ 1: " + expected + ", \"Hello\": " + expected + '}');
550 if (compareFailed) return;
552 compareOne("\xbf\x65Hello" + data + '\1' + data + '\xff', "{_ \"Hello\": " + expected + ", 1: " + expected + '}');
555 void tst_Parser::nestedMaps()
557 QFETCH(QByteArray, data);
558 QFETCH(QString, expected);
560 // nested maps as values
561 compareOneSize(1, "\xa1\1\xa1\2" + data, "{1: {2: " + expected + "}}");
562 if (compareFailed) return;
564 compareOneSize(1, "\xa1\x65Hello\xa1\2" + data, "{\"Hello\": {2: " + expected + "}}");
565 if (compareFailed) return;
567 compareOneSize(1, "\xa1\1\xa2\2" + data + '\x20' + data, "{1: {2: " + expected + ", -1: " + expected + "}}");
568 if (compareFailed) return;
570 compareOneSize(2, "\xa2\1\xa1\2" + data + "\2\xa1\x20" + data, "{1: {2: " + expected + "}, 2: {-1: " + expected + "}}");
571 if (compareFailed) return;
573 // nested maps as keys
574 compareOneSize(1, "\xa1\xa1\xf4" + data + "\xf5", "{{false: " + expected + "}: true}");
575 if (compareFailed) return;
577 compareOneSize(1, "\xa1\xa1" + data + data + "\xa1" + data + data,
578 "{{" + expected + ": " + expected + "}: {" + expected + ": " + expected + "}}");
579 if (compareFailed) return;
582 compareOneSize(-1, "\xbf\1\xbf\2" + data + "\xff\xff", "{_ 1: {_ 2: " + expected + "}}");
583 if (compareFailed) return;
585 compareOneSize(-1, "\xbf\1\xbf\2" + data + '\x20' + data + "\xff\xff", "{_ 1: {_ 2: " + expected + ", -1: " + expected + "}}");
586 if (compareFailed) return;
588 compareOneSize(-1, "\xbf\1\xbf\2" + data + "\xff\2\xbf\x20" + data + "\xff\xff",
589 "{_ 1: {_ 2: " + expected + "}, 2: {_ -1: " + expected + "}}");
590 if (compareFailed) return;
592 compareOneSize(-1, "\xbf\xbf" + data + data + "\xff\xbf" + data + data + "\xff\xff",
593 "{_ {_ " + expected + ": " + expected + "}: {_ " + expected + ": " + expected + "}}");
594 if (compareFailed) return;
597 compareOneSize(1, "\xa1\1\xbf\2" + data + "\xff", "{1: {_ 2: " + expected + "}}");
598 if (compareFailed) return;
600 compareOneSize(-1, "\xbf\1\xa1\2" + data + "\xff", "{_ 1: {2: " + expected + "}}");
601 if (compareFailed) return;
604 void addMapMixedData()
606 QTest::newRow("map-0-24") << raw("\xa1\0\x18\x18") << "{0: 24}" << 1;
607 QTest::newRow("map-0*1-24") << raw("\xa1\x18\0\x18\x18") << "{0: 24}" << 1;
608 QTest::newRow("map-0*1-24*2") << raw("\xa1\x18\0\x19\0\x18") << "{0: 24}" << 1;
609 QTest::newRow("map-0*4-24*2") << raw("\xa1\x1a\0\0\0\0\x19\0\x18") << "{0: 24}" << 1;
610 QTest::newRow("map-24-0") << raw("\xa1\x18\x18\0") << "{24: 0}" << 1;
611 QTest::newRow("map-24-0*1") << raw("\xa1\x18\x18\0") << "{24: 0}" << 1;
612 QTest::newRow("map-255-65535") << raw("\xa1\x18\xff\x19\xff\xff") << "{255: 65535}" << 1;
614 QTest::newRow("_map-0-24") << raw("\xbf\0\x18\x18\xff") << "{_ 0: 24}" << 1;
615 QTest::newRow("_map-0*1-24") << raw("\xbf\x18\0\x18\x18\xff") << "{_ 0: 24}" << 1;
616 QTest::newRow("_map-0*1-24*2") << raw("\xbf\x18\0\x19\0\x18\xff") << "{_ 0: 24}" << 1;
617 QTest::newRow("_map-0*4-24*2") << raw("\xbf\x1a\0\0\0\0\x19\0\x18\xff") << "{_ 0: 24}" << 1;
618 QTest::newRow("_map-24-0") << raw("\xbf\x18\x18\0\xff") << "{_ 24: 0}" << 1;
619 QTest::newRow("_map-24-0*1") << raw("\xbf\x18\x18\0\xff") << "{_ 24: 0}" << 1;
620 QTest::newRow("_map-255-65535") << raw("\xbf\x18\xff\x19\xff\xff\xff") << "{_ 255: 65535}" << 1;
623 void tst_Parser::mapMixed_data()
629 void tst_Parser::mapsAndArrays()
631 QFETCH(QByteArray, data);
632 QFETCH(QString, expected);
635 compareOneSize(1, "\x81\xa1\1" + data, "[{1: " + expected + "}]");
636 if (compareFailed) return;
638 compareOneSize(2, "\x82\xa1\1" + data + "\xa1\2" + data, "[{1: " + expected + "}, {2: " + expected + "}]");
639 if (compareFailed) return;
641 compareOneSize(1, "\x81\xa2\1" + data + "\2" + data, "[{1: " + expected + ", 2: " + expected + "}]");
642 if (compareFailed) return;
644 compareOneSize(-1, "\x9f\xa1\1" + data + "\xff", "[_ {1: " + expected + "}]");
645 if (compareFailed) return;
647 compareOneSize(1, "\x81\xbf\1" + data + "\xff", "[{_ 1: " + expected + "}]");
648 if (compareFailed) return;
650 compareOneSize(-1, "\x9f\xbf\1" + data + "\xff\xff", "[_ {_ 1: " + expected + "}]");
651 if (compareFailed) return;
654 compareOneSize(1, "\xa1\1\x81" + data, "{1: [" + expected + "]}");
655 if (compareFailed) return;
657 compareOneSize(1, "\xa1\1\x82" + data + data, "{1: [" + expected + ", " + expected + "]}");
658 if (compareFailed) return;
660 compareOneSize(2, "\xa2\1\x81" + data + "\x65Hello\x81" + data, "{1: [" + expected + "], \"Hello\": [" + expected + "]}");
661 if (compareFailed) return;
663 compareOneSize(1, "\xa1\1\x9f" + data + "\xff", "{1: [_ " + expected + "]}");
664 if (compareFailed) return;
666 compareOneSize(1, "\xa1\1\x9f" + data + data + "\xff", "{1: [_ " + expected + ", " + expected + "]}");
667 if (compareFailed) return;
669 compareOneSize(-1, "\xbf\1\x81" + data + "\xff", "{_ 1: [" + expected + "]}");
670 if (compareFailed) return;
672 compareOneSize(-1, "\xbf\1\x9f" + data + "\xff\xff", "{_ 1: [_ " + expected + "]}");
673 if (compareFailed) return;
675 compareOneSize(-1, "\xbf\1\x9f" + data + data + "\xff\xff", "{_ 1: [_ " + expected + ", " + expected + "]}");
676 if (compareFailed) return;
678 // mixed with indeterminate length strings
679 compareOneSize(-1, "\xbf\1\x9f" + data + "\xff\x65Hello\xbf" + data + "\x7f\xff\xff\xff",
680 "{_ 1: [_ " + expected + "], \"Hello\": {_ " + expected + ": \"\"}}");
683 void tst_Parser::stringLength_data()
685 QTest::addColumn<QByteArray>("data");
686 QTest::addColumn<int>("expected");
688 QTest::newRow("emptybytestring") << raw("\x40") << 0;
689 QTest::newRow("bytestring1") << raw("\x41 ") << 1;
690 QTest::newRow("bytestring1-nul") << raw("\x41\0") << 1;
691 QTest::newRow("bytestring5") << raw("\x45Hello") << 5;
692 QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234") << 24;
693 QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3') << 256;
696 QTest::newRow("emptytextstring") << raw("\x60") << 0;
697 QTest::newRow("textstring1") << raw("\x61 ") << 1;
698 QTest::newRow("textstring1-nul") << raw("\x61\0") << 1;
699 QTest::newRow("textstring5") << raw("\x65Hello") << 5;
700 QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234") << 24;
701 QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3') << 256;
703 // strings with overlong length
704 QTest::newRow("emptybytestring*1") << raw("\x58\x00") << 0;
705 QTest::newRow("emptytextstring*1") << raw("\x78\x00") << 0;
706 QTest::newRow("emptybytestring*2") << raw("\x59\x00\x00") << 0;
707 QTest::newRow("emptytextstring*2") << raw("\x79\x00\x00") << 0;
708 QTest::newRow("emptybytestring*4") << raw("\x5a\0\0\0\0") << 0;
709 QTest::newRow("emptytextstring*4") << raw("\x7a\0\0\0\0") << 0;
710 QTest::newRow("emptybytestring*8") << raw("\x5b\0\0\0\0\0\0\0\0") << 0;
711 QTest::newRow("emptytextstring*8") << raw("\x7b\0\0\0\0\0\0\0\0") << 0;
712 QTest::newRow("bytestring5*1") << raw("\x58\x05Hello") << 5;
713 QTest::newRow("textstring5*1") << raw("\x78\x05Hello") << 5;
714 QTest::newRow("bytestring5*2") << raw("\x59\0\5Hello") << 5;
715 QTest::newRow("textstring5*2") << raw("\x79\0\x05Hello") << 5;
716 QTest::newRow("bytestring5*4") << raw("\x5a\0\0\0\5Hello") << 5;
717 QTest::newRow("textstring5*4") << raw("\x7a\0\0\0\x05Hello") << 5;
718 QTest::newRow("bytestring5*8") << raw("\x5b\0\0\0\0\0\0\0\5Hello") << 5;
719 QTest::newRow("textstring5*8") << raw("\x7b\0\0\0\0\0\0\0\x05Hello") << 5;
721 // strings with undefined length
722 QTest::newRow("_emptybytestring") << raw("\x5f\xff") << 0;
723 QTest::newRow("_emptytextstring") << raw("\x7f\xff") << 0;
724 QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << 0;
725 QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << 0;
726 QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << 0;
727 QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << 0;
728 QTest::newRow("_bytestring5*2") << raw("\x5f\x43Hel\x42lo\xff") << 5;
729 QTest::newRow("_textstring5*2") << raw("\x7f\x63Hel\x62lo\xff") << 5;
730 QTest::newRow("_bytestring5*5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << 5;
731 QTest::newRow("_textstring5*5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << 5;
732 QTest::newRow("_bytestring5*6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << 5;
733 QTest::newRow("_textstring5*6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << 5;
736 void tst_Parser::stringLength()
738 QFETCH(QByteArray, data);
739 QFETCH(int, expected);
743 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
744 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
747 err = cbor_value_calculate_string_length(&value, &result);
748 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
749 QCOMPARE(result, size_t(expected));
752 void tst_Parser::stringCompare_data()
754 QTest::addColumn<QByteArray>("data");
755 QTest::addColumn<QString>("string");
756 QTest::addColumn<bool>("expected");
758 // compare empty to empty
759 QTest::newRow("empty-empty") << raw("\x60") << QString() << true;
760 QTest::newRow("_empty-empty") << raw("\x7f\xff") << QString() << true;
761 QTest::newRow("_empty*1-empty") << raw("\x7f\x60\xff") << QString() << true;
762 QTest::newRow("_empty*2-empty") << raw("\x7f\x60\x60\xff") << QString() << true;
764 // compare empty to non-empty
765 QTest::newRow("empty-nonempty") << raw("\x60") << "Hello" << false;
766 QTest::newRow("_empty-nonempty") << raw("\x7f\xff") << "Hello" << false;
767 QTest::newRow("_empty*1-nonempty") << raw("\x7f\x60\xff") << "Hello" << false;
768 QTest::newRow("_empty*2-nonempty") << raw("\x7f\x60\x60\xff") << "Hello" << false;
770 // compare same strings
771 QTest::newRow("same-short-short") << raw("\x65Hello") << "Hello" << true;
772 QTest::newRow("same-_short*1-short") << raw("\x7f\x65Hello\xff") << "Hello" << true;
773 QTest::newRow("same-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "Hello" << true;
774 QTest::newRow("same-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "Hello" << true;
775 QTest::newRow("same-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "Hello" << true;
776 QTest::newRow("same-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
777 << "Good morning, good afternoon and goodnight" << true;
778 QTest::newRow("same-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
779 << "Good morning, good afternoon and goodnight" << true;
780 QTest::newRow("same-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
781 << "Good morning, good afternoon and goodnight" << true;
783 // compare different strings (same length)
784 QTest::newRow("diff-same-length-short-short") << raw("\x65Hello") << "World" << false;
785 QTest::newRow("diff-same-length-_short*1-short") << raw("\x7f\x65Hello\xff") << "World" << false;
786 QTest::newRow("diff-same-length-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "World" << false;
787 QTest::newRow("diff-same-length-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "World" << false;
788 QTest::newRow("diff-same-length-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "World" << false;
789 QTest::newRow("diff-same-length-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
790 << "Good morning, good afternoon and goodnight, world" << false;
791 QTest::newRow("diff-same-length-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
792 << "Good morning, good afternoon and goodnight, world" << false;
793 QTest::newRow("diff-same-length-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
794 << "Good morning, good afternoon and goodnight, world" << false;
796 // compare different strings (different length)
797 QTest::newRow("diff-diff-length-short-short") << raw("\x65Hello") << "Hello World" << false;
798 QTest::newRow("diff-diff-length-_short*1-short") << raw("\x7f\x65Hello\xff") << "Hello World" << false;
799 QTest::newRow("diff-diff-length-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "Hello World" << false;
800 QTest::newRow("diff-diff-length-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "Hello World" << false;
801 QTest::newRow("diff-diff-length-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "Hello World" << false;
802 QTest::newRow("diff-diff-length-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
803 << "Good morning, good afternoon and goodnight World" << false;
804 QTest::newRow("diff-diff-length-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
805 << "Good morning, good afternoon and goodnight World" << false;
806 QTest::newRow("diff-diff-length-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
807 << "Good morning, good afternoon and goodnight World" << false;
809 // compare against non-strings
810 QTest::newRow("unsigned") << raw("\0") << "0" << false;
811 QTest::newRow("negative") << raw("\x20") << "-1" << false;
812 QTest::newRow("emptybytestring") << raw("\x40") << "" << false;
813 QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "" << false;
814 QTest::newRow("shortbytestring") << raw("\x45Hello") << "Hello" << false;
815 QTest::newRow("longbytestring") << raw("\x58\x2aGood morning, good afternoon and goodnight")
816 << "Good morning, good afternoon and goodnight" << false;
817 QTest::newRow("emptyarray") << raw("\x80") << "" << false;
818 QTest::newRow("emptymap") << raw("\xa0") << "" << false;
819 QTest::newRow("array") << raw("\x81\x65Hello") << "Hello" << false;
820 QTest::newRow("map") << raw("\xa1\x65Hello\x65World") << "Hello World" << false;
821 QTest::newRow("false") << raw("\xf4") << "false" << false;
822 QTest::newRow("true") << raw("\xf5") << "true" << false;
823 QTest::newRow("null") << raw("\xf6") << "null" << false;
826 void compareOneString(const QByteArray &data, const QString &string, bool expected, int line)
828 compareFailed = true;
832 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
833 QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
836 err = cbor_value_text_string_equals(&value, string.toUtf8().constData(), &result);
837 QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
838 QCOMPARE(result, expected);
840 compareFailed = false;
842 #define compareOneString(data, string, expected) compareOneString(data, string, expected, __LINE__)
844 void tst_Parser::stringCompare()
846 QFETCH(QByteArray, data);
847 QFETCH(QString, string);
848 QFETCH(bool, expected);
850 compareOneString(data, string, expected);
851 if (compareFailed) return;
854 compareOneString("\xc1" + data, string, expected);
855 if (compareFailed) return;
857 compareOneString("\xc1\xc2" + data, string, expected);
860 void tst_Parser::mapFind_data()
863 // we are searching for string "needle"
864 // if present, the value should be the string "haystack" (with tag 42)
866 QTest::addColumn<QByteArray>("data");
867 QTest::addColumn<bool>("expected");
869 QTest::newRow("emptymap") << raw("\xa0") << false;
870 QTest::newRow("_emptymap") << raw("\xbf\xff") << false;
872 // maps not containing our items
873 QTest::newRow("absent-unsigned-unsigned") << raw("\xa1\0\0") << false;
874 QTest::newRow("absent-taggedunsigned-unsigned") << raw("\xa1\xc0\0\0") << false;
875 QTest::newRow("absent-unsigned-taggedunsigned") << raw("\xa1\0\xc0\0") << false;
876 QTest::newRow("absent-taggedunsigned-taggedunsigned") << raw("\xa1\xc0\0\xc0\0") << false;
877 QTest::newRow("absent-string-unsigned") << raw("\xa1\x68haystack\0") << false;
878 QTest::newRow("absent-taggedstring-unsigned") << raw("\xa1\xc0\x68haystack\0") << false;
879 QTest::newRow("absent-string-taggedunsigned") << raw("\xa1\x68haystack\xc0\0") << false;
880 QTest::newRow("absent-taggedstring-taggedunsigned") << raw("\xa1\xc0\x68haystack\xc0\0") << false;
881 QTest::newRow("absent-string-string") << raw("\xa1\x68haystack\x66needle") << false;
882 QTest::newRow("absent-string-taggedstring") << raw("\xa1\x68haystack\xc0\x66needle") << false;
883 QTest::newRow("absent-taggedstring-string") << raw("\xa1\xc0\x68haystack\x66needle") << false;
884 QTest::newRow("absent-string-taggedstring") << raw("\xa1\xc0\x68haystack\xc0\x66needle") << false;
886 QTest::newRow("absent-string-emptyarray") << raw("\xa1\x68haystack\x80") << false;
887 QTest::newRow("absent-string-_emptyarray") << raw("\xa1\x68haystack\x9f\xff") << false;
888 QTest::newRow("absent-string-array1") << raw("\xa1\x68haystack\x81\0") << false;
889 QTest::newRow("absent-string-array2") << raw("\xa1\x68haystack\x85\0\1\2\3\4") << false;
890 QTest::newRow("absent-string-array3") << raw("\xa1\x68haystack\x85\x63one\x63two\x65three\x64""four\x64""five") << false;
892 QTest::newRow("absent-string-emptymap") << raw("\xa1\x68haystack\xa0") << false;
893 QTest::newRow("absent-string-_emptymap") << raw("\xa1\x68haystack\xbf\xff") << false;
894 QTest::newRow("absent-string-map") << raw("\xa1\x68haystack\xa1\x68haystack\x66needle") << false;
895 QTest::newRow("absent-string-map2") << raw("\xa1\x68haystack\xa1\x68haystack\x66needle\61z\62yx") << false;
897 // maps containing our items
898 QTest::newRow("alone") << raw("\xa1\x66needle\xd8\x2a\x68haystack") << true;
899 QTest::newRow("tagged") << raw("\xa1\xc1\x66needle\xd8\x2a\x68haystack") << true;
900 QTest::newRow("doubletagged") << raw("\xa1\xc1\xc2\x66needle\xd8\x2a\x68haystack") << true;
901 QTest::newRow("chunked") << raw("\xa1\x7f\x66needle\xff\xd8\x2a\x68haystack") << true;
902 QTest::newRow("chunked*2") << raw("\xa1\x7f\x60\x66needle\xff\xd8\x2a\x68haystack") << true;
903 QTest::newRow("chunked*2bis") << raw("\xa1\x7f\x66needle\x60\xff\xd8\x2a\x68haystack") << true;
904 QTest::newRow("chunked*3") << raw("\xa1\x7f\x62ne\x62""ed\x62le\xff\xd8\x2a\x68haystack") << true;
905 QTest::newRow("chunked*8") << raw("\xa1\x7f\x61n\x61""e\x60\x61""e\x61""d\x60\x62le\x60\xff\xd8\x2a\x68haystack") << true;
907 QTest::newRow("1before") << raw("\xa2\x68haystack\x66needle\x66needle\xd8\x2a\x68haystack") << true;
908 QTest::newRow("tagged-1before") << raw("\xa2\xc1\x68haystack\x66needle\xc1\x66needle\xd8\x2a\x68haystack") << true;
909 QTest::newRow("doubletagged-1before2") << raw("\xa2\xc1\xc2\x68haystack\x66needle\xc1\xc2\x66needle\xd8\x2a\x68haystack") << true;
911 QTest::newRow("arraybefore") << raw("\xa2\x61z\x80\x66needle\xd8\x2a\x68haystack") << true;
912 QTest::newRow("nestedarraybefore") << raw("\xa2\x61z\x81\x81\0\x66needle\xd8\x2a\x68haystack") << true;
913 QTest::newRow("arrayarraybefore") << raw("\xa2\x82\1\2\x80\x66needle\xd8\x2a\x68haystack") << true;
915 QTest::newRow("mapbefore") << raw("\xa2\x61z\xa0\x66needle\xd8\x2a\x68haystack") << true;
916 QTest::newRow("nestedmapbefore") << raw("\xa2\x61z\xa1\0\x81\0\x66needle\xd8\x2a\x68haystack") << true;
917 QTest::newRow("mapmapbefore") << raw("\xa2\xa1\1\2\xa0\x66needle\xd8\x2a\x68haystack") << true;
920 void tst_Parser::mapFind()
922 QFETCH(QByteArray, data);
923 QFETCH(bool, expected);
927 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
928 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
931 err = cbor_value_map_find_value(&value, "needle", &element);
932 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
935 QCOMPARE(int(element.type), int(CborTagType));
938 err = cbor_value_get_tag(&element, &tag);
939 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
940 QCOMPARE(int(tag), 42);
943 err = cbor_value_text_string_equals(&element, "haystack", &equals);
944 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
947 QCOMPARE(int(element.type), int(CborInvalidType));
951 void tst_Parser::validation_data()
953 QTest::addColumn<QByteArray>("data");
954 QTest::addColumn<int>("flags"); // future
955 QTest::addColumn<CborError>("expectedError");
956 QTest::addColumn<int>("offset");
958 // illegal numbers are future extension points
959 QTest::newRow("illegal-number-in-unsigned-1") << raw("\x81\x1c") << 0 << CborErrorIllegalNumber << 1;
960 QTest::newRow("illegal-number-in-unsigned-2") << raw("\x81\x1d") << 0 << CborErrorIllegalNumber << 1;
961 QTest::newRow("illegal-number-in-unsigned-3") << raw("\x81\x1e") << 0 << CborErrorIllegalNumber << 1;
962 QTest::newRow("illegal-number-in-unsigned-4") << raw("\x81\x1f") << 0 << CborErrorIllegalNumber << 1;
963 QTest::newRow("illegal-number-in-negative-1") << raw("\x81\x3c") << 0 << CborErrorIllegalNumber << 1;
964 QTest::newRow("illegal-number-in-negative-2") << raw("\x81\x3d") << 0 << CborErrorIllegalNumber << 1;
965 QTest::newRow("illegal-number-in-negative-3") << raw("\x81\x3e") << 0 << CborErrorIllegalNumber << 1;
966 QTest::newRow("illegal-number-in-negative-4") << raw("\x81\x3f") << 0 << CborErrorIllegalNumber << 1;
967 QTest::newRow("illegal-number-in-bytearray-length-1") << raw("\x81\x5c") << 0 << CborErrorIllegalNumber << 1;
968 QTest::newRow("illegal-number-in-bytearray-length-2") << raw("\x81\x5d") << 0 << CborErrorIllegalNumber << 1;
969 QTest::newRow("illegal-number-in-bytearray-length-3") << raw("\x81\x5e") << 0 << CborErrorIllegalNumber << 1;
970 QTest::newRow("illegal-number-in-string-length-1") << raw("\x81\x7c") << 0 << CborErrorIllegalNumber << 1;
971 QTest::newRow("illegal-number-in-string-length-2") << raw("\x81\x7d") << 0 << CborErrorIllegalNumber << 1;
972 QTest::newRow("illegal-number-in-string-length-3") << raw("\x81\x7e") << 0 << CborErrorIllegalNumber << 1;
973 QTest::newRow("illegal-number-in-array-length-1") << raw("\x81\x9c") << 0 << CborErrorIllegalNumber << 1;
974 QTest::newRow("illegal-number-in-array-length-2") << raw("\x81\x9d") << 0 << CborErrorIllegalNumber << 1;
975 QTest::newRow("illegal-number-in-array-length-3") << raw("\x81\x9e") << 0 << CborErrorIllegalNumber << 1;
976 QTest::newRow("illegal-number-in-map-length-1") << raw("\x81\xbc") << 0 << CborErrorIllegalNumber << 1;
977 QTest::newRow("illegal-number-in-map-length-2") << raw("\x81\xbd") << 0 << CborErrorIllegalNumber << 1;
978 QTest::newRow("illegal-number-in-map-length-3") << raw("\x81\xbe") << 0 << CborErrorIllegalNumber << 1;
980 QTest::newRow("number-too-short-1-0") << raw("\x81\x18") << 0 << CborErrorUnexpectedEOF << 1; // requires 1 byte, 0 given
981 QTest::newRow("number-too-short-2-0") << raw("\x81\x19") << 0 << CborErrorUnexpectedEOF << 1; // requires 2 bytes, 0 given
982 QTest::newRow("number-too-short-2-1") << raw("\x81\x19\x01") << 0 << CborErrorUnexpectedEOF << 1; // etc
983 QTest::newRow("number-too-short-4-0") << raw("\x81\x1a") << 0 << CborErrorUnexpectedEOF << 1;
984 QTest::newRow("number-too-short-4-3") << raw("\x81\x1a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
985 QTest::newRow("number-too-short-8-0") << raw("\x81\x1b") << 0 << CborErrorUnexpectedEOF << 1;
986 QTest::newRow("number-too-short-8-7") << raw("\x81\x1b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
987 QTest::newRow("bytearray-length-too-short-1-0") << raw("\x81\x38") << 0 << CborErrorUnexpectedEOF << 1;
988 QTest::newRow("bytearray-length-too-short-2-0") << raw("\x81\x39") << 0 << CborErrorUnexpectedEOF << 1;
989 QTest::newRow("bytearray-length-too-short-2-1") << raw("\x81\x39\x01") << 0 << CborErrorUnexpectedEOF << 1;
990 QTest::newRow("bytearray-length-too-short-4-0") << raw("\x81\x3a") << 0 << CborErrorUnexpectedEOF << 1;
991 QTest::newRow("bytearray-length-too-short-4-3") << raw("\x81\x3a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
992 QTest::newRow("bytearray-length-too-short-8-0") << raw("\x81\x3b") << 0 << CborErrorUnexpectedEOF << 1;
993 QTest::newRow("bytearray-length-too-short-8-7") << raw("\x81\x3b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
994 QTest::newRow("string-length-too-short-1-0") << raw("\x81\x58") << 0 << CborErrorUnexpectedEOF << 1;
995 QTest::newRow("string-length-too-short-2-0") << raw("\x81\x59") << 0 << CborErrorUnexpectedEOF << 1;
996 QTest::newRow("string-length-too-short-2-1") << raw("\x81\x59\x01") << 0 << CborErrorUnexpectedEOF << 1;
997 QTest::newRow("string-length-too-short-4-0") << raw("\x81\x5a") << 0 << CborErrorUnexpectedEOF << 1;
998 QTest::newRow("string-length-too-short-4-3") << raw("\x81\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
999 QTest::newRow("string-length-too-short-8-0") << raw("\x81\x5b") << 0 << CborErrorUnexpectedEOF << 1;
1000 QTest::newRow("string-length-too-short-8-7") << raw("\x81\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
1001 QTest::newRow("array-length-too-short-1-0") << raw("\x81\x98") << 0 << CborErrorUnexpectedEOF << 1;
1002 QTest::newRow("array-length-too-short-2-0") << raw("\x81\x99") << 0 << CborErrorUnexpectedEOF << 1;
1003 QTest::newRow("array-length-too-short-2-1") << raw("\x81\x99\x01") << 0 << CborErrorUnexpectedEOF << 1;
1004 QTest::newRow("array-length-too-short-4-0") << raw("\x81\x9a") << 0 << CborErrorUnexpectedEOF << 1;
1005 QTest::newRow("array-length-too-short-4-3") << raw("\x81\x9a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
1006 QTest::newRow("array-length-too-short-8-0") << raw("\x81\x9b") << 0 << CborErrorUnexpectedEOF << 1;
1007 QTest::newRow("array-length-too-short-8-7") << raw("\x81\x9b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
1008 QTest::newRow("map-length-too-short-1-0") << raw("\x81\xb8") << 0 << CborErrorUnexpectedEOF << 1;
1009 QTest::newRow("map-length-too-short-2-0") << raw("\x81\xb9") << 0 << CborErrorUnexpectedEOF << 1;
1010 QTest::newRow("map-length-too-short-2-1") << raw("\x81\xb9\x01") << 0 << CborErrorUnexpectedEOF << 1;
1011 QTest::newRow("map-length-too-short-4-0") << raw("\x81\xba") << 0 << CborErrorUnexpectedEOF << 1;
1012 QTest::newRow("map-length-too-short-4-3") << raw("\x81\xba\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
1013 QTest::newRow("map-length-too-short-8-0") << raw("\x81\xbb") << 0 << CborErrorUnexpectedEOF << 1;
1014 QTest::newRow("map-length-too-short-8-7") << raw("\x81\xbb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
1015 QTest::newRow("tag-too-short-1-0") << raw("\x81\xd8") << 0 << CborErrorUnexpectedEOF << 1;
1016 QTest::newRow("tag-too-short-2-0") << raw("\x81\xd9") << 0 << CborErrorUnexpectedEOF << 1;
1017 QTest::newRow("tag-too-short-2-1") << raw("\x81\xd9\x01") << 0 << CborErrorUnexpectedEOF << 1;
1018 QTest::newRow("tag-too-short-4-0") << raw("\x81\xda") << 0 << CborErrorUnexpectedEOF << 1;
1019 QTest::newRow("tag-too-short-4-3") << raw("\x81\xda\x01\x02\x03") << 0 << CborErrorUnexpectedEOF << 1;
1020 QTest::newRow("tag-too-short-8-0") << raw("\x81\xdb") << 0 << CborErrorUnexpectedEOF << 1;
1021 QTest::newRow("tag-too-short-8-7") << raw("\x81\xdb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF << 1;
1023 QTest::newRow("bytearray-too-short1") << raw("\x81\x41") << 0 << CborErrorUnexpectedEOF << 1;
1024 QTest::newRow("bytearray-too-short2") << raw("\x81\x58") << 0 << CborErrorUnexpectedEOF << 1;
1025 QTest::newRow("bytearray-too-short3") << raw("\x81\x58\x01") << 0 << CborErrorUnexpectedEOF << 1;
1026 QTest::newRow("bytearray-too-short4") << raw("\x81\x59") << 0 << CborErrorUnexpectedEOF << 1;
1027 QTest::newRow("bytearray-too-short5") << raw("\x81\x5a\0\0\0\1") << 0 << CborErrorUnexpectedEOF << 1;
1028 QTest::newRow("bytearray-too-short6") << raw("\x81\x5b\0\0\0\0\0\0\0\1") << 0 << CborErrorUnexpectedEOF << 1;
1029 QTest::newRow("string-too-short1") << raw("\x81\x61") << 0 << CborErrorUnexpectedEOF << 1;
1030 QTest::newRow("string-too-short2") << raw("\x81\x78") << 0 << CborErrorUnexpectedEOF << 1;
1031 QTest::newRow("string-too-short3") << raw("\x81\x78\x01") << 0 << CborErrorUnexpectedEOF << 1;
1032 QTest::newRow("string-too-short4") << raw("\x81\x79") << 0 << CborErrorUnexpectedEOF << 1;
1033 QTest::newRow("string-too-short5") << raw("\x81\x7a\0\0\0\1") << 0 << CborErrorUnexpectedEOF << 1;
1034 QTest::newRow("string-too-short6") << raw("\x81\x7b\0\0\0\0\0\0\0\1") << 0 << CborErrorUnexpectedEOF << 1;
1035 QTest::newRow("fp16-too-short1") << raw("\x81\xf9") << 0 << CborErrorUnexpectedEOF << 1;
1036 QTest::newRow("fp16-too-short2") << raw("\x81\xf9\x00") << 0 << CborErrorUnexpectedEOF << 1;
1037 QTest::newRow("float-too-short1") << raw("\x81\xfa") << 0 << CborErrorUnexpectedEOF << 1;
1038 QTest::newRow("float-too-short2") << raw("\x81\xfa\0\0\0") << 0 << CborErrorUnexpectedEOF << 1;
1039 QTest::newRow("double-too-short1") << raw("\x81\xfb") << 0 << CborErrorUnexpectedEOF << 1;
1040 QTest::newRow("double-too-short2") << raw("\x81\xfb\0\0\0\0\0\0\0") << 0 << CborErrorUnexpectedEOF << 1;
1042 // check for pointer additions wrapping over the limit of the address space
1043 CborError tooLargeOn32bit = (sizeof(void *) == 4) ? CborErrorDataTooLarge : CborErrorUnexpectedEOF;
1044 // on 32-bit systems, this is a -1
1045 QTest::newRow("bytearray-wraparound1") << raw("\x81\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF << 1;
1046 QTest::newRow("string-wraparound1") << raw("\x81\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF << 1;
1047 // on 32-bit systems, a 4GB addition could be dropped
1048 QTest::newRow("bytearray-wraparound2") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit << 1;
1049 QTest::newRow("string-wraparound2") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit << 1;
1050 // on 64-bit systems, this could be a -1
1051 QTest::newRow("bytearray-wraparound3") << raw("\x81\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit << 1;
1052 QTest::newRow("string-wraparound3") << raw("\x81\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit << 1;
1055 QTest::newRow("bytearray-chunk-wraparound1") << raw("\x81\x5f\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF << 1;
1056 QTest::newRow("string-chunk-wraparound1") << raw("\x81\x7f\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF << 1;
1057 // on 32-bit systems, a 4GB addition could be dropped
1058 QTest::newRow("bytearray-chunk-wraparound2") << raw("\x81\x5f\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit << 1;
1059 QTest::newRow("string-chunk-wraparound2") << raw("\x81\x7f\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit << 1;
1060 // on 64-bit systems, this could be a -1
1061 QTest::newRow("bytearray-chunk-wraparound3") << raw("\x81\x5f\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit << 1;
1062 QTest::newRow("string-chunk-wraparound3") << raw("\x81\x7f\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit << 1;
1064 QTest::newRow("eof-after-array") << raw("\x81") << 0 << CborErrorUnexpectedEOF << 1;
1065 QTest::newRow("eof-after-array2") << raw("\x81\x78\x20") << 0 << CborErrorUnexpectedEOF << 1;
1066 QTest::newRow("eof-after-array-element") << raw("\x81\x82\x01") << 0 << CborErrorUnexpectedEOF << 3;
1067 QTest::newRow("eof-after-object") << raw("\x81\xa1") << 0 << CborErrorUnexpectedEOF << 2;
1068 QTest::newRow("eof-after-object2") << raw("\x81\xb8\x20") << 0 << CborErrorUnexpectedEOF << 3;
1069 QTest::newRow("eof-after-object-key") << raw("\x81\xa1\x01") << 0 << CborErrorUnexpectedEOF << 3;
1070 QTest::newRow("eof-after-object-value") << raw("\x81\xa2\x01\x01") << 0 << CborErrorUnexpectedEOF << 4;
1071 QTest::newRow("eof-after-tag") << raw("\x81\xc0") << 0 << CborErrorUnexpectedEOF << 2;
1072 QTest::newRow("eof-after-tag2") << raw("\x81\xd8\x20") << 0 << CborErrorUnexpectedEOF << 3;
1074 // major type 7 has future types
1075 QTest::newRow("future-type-28") << raw("\x81\xfc") << 0 << CborErrorUnknownType << 1;
1076 QTest::newRow("future-type-29") << raw("\x81\xfd") << 0 << CborErrorUnknownType << 1;
1077 QTest::newRow("future-type-30") << raw("\x81\xfe") << 0 << CborErrorUnknownType << 1;
1078 QTest::newRow("unexpected-break") << raw("\x81\xff") << 0 << CborErrorUnexpectedBreak << 1;
1079 QTest::newRow("illegal-simple-0") << raw("\x81\xf8\0") << 0 << CborErrorIllegalSimpleType << 1;
1080 QTest::newRow("illegal-simple-31") << raw("\x81\xf8\x1f") << 0 << CborErrorIllegalSimpleType << 1;
1082 // not only too big (UINT_MAX or UINT_MAX+1 in size), but also incomplete
1083 if (sizeof(size_t) < sizeof(uint64_t)) {
1084 QTest::newRow("bytearray-too-big1") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1085 QTest::newRow("string-too-big1") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1087 QTest::newRow("array-too-big1") << raw("\x81\x9a\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1088 QTest::newRow("array-too-big2") << raw("\x81\x9b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1089 QTest::newRow("object-too-big1") << raw("\x81\xba\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1090 QTest::newRow("object-too-big2") << raw("\x81\xbb\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge << 1;
1092 QTest::newRow("no-break-for-array0") << raw("\x81\x9f") << 0 << CborErrorUnexpectedEOF << 2;
1093 QTest::newRow("no-break-for-array1") << raw("\x81\x9f\x01") << 0 << CborErrorUnexpectedEOF << 3;
1094 QTest::newRow("no-break-string0") << raw("\x81\x7f") << 0 << CborErrorUnexpectedEOF << 1;
1095 QTest::newRow("no-break-string1") << raw("\x81\x7f\x61Z") << 0 << CborErrorUnexpectedEOF << 1;
1097 QTest::newRow("nested-indefinite-length-bytearrays") << raw("\x81\x5f\x5f\xff\xff") << 0 << CborErrorIllegalNumber << 1;
1098 QTest::newRow("nested-indefinite-length-strings") << raw("\x81\x5f\x5f\xff\xff") << 0 << CborErrorIllegalNumber << 1;
1100 QTest::newRow("string-chunk-unsigned") << raw("\x81\x7f\0\xff") << 0 << CborErrorIllegalType << 1;
1101 QTest::newRow("string-chunk-bytearray") << raw("\x81\x7f\x40\xff") << 0 << CborErrorIllegalType << 1;
1102 QTest::newRow("string-chunk-array") << raw("\x81\x7f\x80\xff") << 0 << CborErrorIllegalType << 1;
1103 QTest::newRow("bytearray-chunk-unsigned") << raw("\x81\x5f\0\xff") << 0 << CborErrorIllegalType << 1;
1104 QTest::newRow("bytearray-chunk-string") << raw("\x81\x5f\x60\xff") << 0 << CborErrorIllegalType << 1;
1105 QTest::newRow("bytearray-chunk-array") << raw("\x81\x5f\x80\xff") << 0 << CborErrorIllegalType << 1;
1108 void tst_Parser::validation()
1110 QFETCH(QByteArray, data);
1112 QFETCH(CborError, expectedError);
1113 QFETCH(int, offset);
1118 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), flags, &parser, &first);
1119 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
1121 err = parseOne(&first, &decoded);
1122 QCOMPARE(int(err), int(expectedError));
1123 QCOMPARE(int(first.ptr - reinterpret_cast<const quint8 *>(data.constBegin())), offset);
1126 void tst_Parser::resumeParsing_data()
1135 void tst_Parser::resumeParsing()
1137 QFETCH(QByteArray, data);
1138 QFETCH(QString, expected);
1140 for (int len = 0; len < data.length() - 1; ++len) {
1143 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), len, 0, &parser, &first);
1146 err = parseOne(&first, &decoded);
1148 if (err != CborErrorUnexpectedEOF)
1149 qDebug() << "Length is" << len;
1150 QCOMPARE(int(err), int(CborErrorUnexpectedEOF));
1154 void tst_Parser::endPointer_data()
1156 QTest::addColumn<QByteArray>("data");
1157 QTest::addColumn<int>("offset");
1159 QTest::newRow("number1") << raw("\x81\x01\x01") << 2;
1160 QTest::newRow("number24") << raw("\x81\x18\x18\x01") << 3;
1161 QTest::newRow("string") << raw("\x81\x61Z\x01") << 3;
1162 QTest::newRow("indefinite-string") << raw("\x81\x7f\x61Z\xff\x01") << 5;
1163 QTest::newRow("array") << raw("\x81\x02\x01") << 2;
1164 QTest::newRow("indefinite-array") << raw("\x81\x9f\x02\xff\x01") << 4;
1165 QTest::newRow("object") << raw("\x81\xa1\x03\x02\x01") << 4;
1166 QTest::newRow("indefinite-object") << raw("\x81\xbf\x03\x02\xff\x01") << 5;
1169 void tst_Parser::endPointer()
1171 QFETCH(QByteArray, data);
1172 QFETCH(int, offset);
1177 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
1178 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
1180 err = parseOne(&first, &decoded);
1181 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
1182 QCOMPARE(int(first.ptr - reinterpret_cast<const quint8 *>(data.constBegin())), offset);
1185 void tst_Parser::recursionLimit_data()
1187 static const int recursions = CBOR_PARSER_MAX_RECURSIONS + 2;
1188 QTest::addColumn<QByteArray>("data");
1190 QTest::newRow("array") << QByteArray(recursions, '\x81') + '\x20';
1191 QTest::newRow("_array") << QByteArray(recursions, '\x9f') + '\x20' + QByteArray(recursions, '\xff');
1194 for (int i = 0; i < recursions; ++i)
1195 data += "\xa1\x65Hello";
1197 QTest::newRow("map-recursive-values") << data;
1200 for (int i = 0; i < recursions; ++i)
1201 data += "\xbf\x65World";
1203 for (int i = 0; i < recursions; ++i)
1205 QTest::newRow("_map-recursive-values") << data;
1207 data = QByteArray(recursions, '\xa1');
1209 for (int i = 0; i < recursions; ++i)
1210 data += "\x7f\x64quux\xff";
1211 QTest::newRow("map-recursive-keys") << data;
1213 data = QByteArray(recursions, '\xbf');
1215 for (int i = 0; i < recursions; ++i)
1217 QTest::newRow("_map-recursive-keys") << data;
1220 for (int i = 0; i < recursions / 2; ++i)
1221 data += "\x81\xa1\1";
1223 QTest::newRow("mixed") << data;
1226 void tst_Parser::recursionLimit()
1228 QFETCH(QByteArray, data);
1232 CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
1233 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
1235 // check that it is valid:
1236 CborValue it = first;
1239 err = parseOne(&it, &dummy);
1240 QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
1244 err = cbor_value_advance(&it);
1245 QCOMPARE(int(err), int(CborErrorNestingTooDeep));
1248 if (cbor_value_is_map(&it)) {
1250 err = cbor_value_map_find_value(&it, "foo", &dummy);
1251 QCOMPARE(int(err), int(CborErrorNestingTooDeep));
1255 QTEST_MAIN(tst_Parser)
1256 #include "tst_parser.moc"