1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 Intel Corporation.
4 ** Copyright (C) 2019 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #define CBOR_NO_ENCODER_API
42 #define CBOR_NO_PARSER_API
43 #include "qcborcommon_p.h"
44 
45 #include <QtCore/qdatastream.h>
46 
47 QT_BEGIN_NAMESPACE
48 
49 #include <cborerrorstrings.c>
50 
51 /*!
52    \headerfile <QtCborCommon>
53 
54    \brief The <QtCborCommon> header contains definitions common to both the
55    streaming classes (QCborStreamReader and QCborStreamWriter) and to
56    QCborValue.
57 
58    \sa QCborError
59  */
60 
61 /*!
62    \enum QCborSimpleType
63    \relates <QtCborCommon>
64 
65    This enum contains the possible "Simple Types" for CBOR. Simple Types range
66    from 0 to 255 and are types that carry no further value.
67 
68    The following values are currently known:
69 
70    \value False             A "false" boolean.
71    \value True              A "true" boolean.
72    \value Null              Absence of value (null).
73    \value Undefined         Missing or deleted value, usually an error.
74 
75    Qt CBOR API supports encoding and decoding any Simple Type, whether one of
76    those above or any other value.
77 
78    Applications should only use further values if a corresponding specification
79    has been published, otherwise interpretation and validation by the remote
80    may fail. Values 24 to 31 are reserved and must not be used.
81 
82    The current authoritative list is maintained by IANA in the
83    \l{https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xml}{Simple
84    Values registry}.
85 
86    \sa QCborStreamWriter::append(QCborSimpleType), QCborStreamReader::isSimpleType(),
87        QCborStreamReader::toSimpleType(), QCborValue::isSimpleType(), QCborValue::toSimpleType()
88  */
89 
90 #if !defined(QT_NO_DATASTREAM)
operator <<(QDataStream & ds,QCborSimpleType st)91 QDataStream &operator<<(QDataStream &ds, QCborSimpleType st)
92 {
93     return ds << quint8(st);
94 }
95 
operator >>(QDataStream & ds,QCborSimpleType & st)96 QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st)
97 {
98     quint8 v;
99     ds >> v;
100     st = QCborSimpleType(v);
101     return ds;
102 }
103 #endif
104 
105 /*!
106    \enum QCborTag
107    \relates <QtCborCommon>
108 
109    This enum contains no enumeration and is used only to provide type-safe
110    access to a CBOR tag.
111 
112    CBOR tags are 64-bit numbers that are attached to generic CBOR types to
113    provide further semantic meaning. QCborTag may be constructed from an
114    enumeration found in QCborKnownTags or directly by providing the numeric
115    representation.
116 
117    For example, the following creates a QCborValue containing a byte array
118    tagged with a tag 2.
119 
120    \snippet code/src_corelib_serialization_qcborstream.cpp 0
121 
122    \sa QCborKnownTags, QCborStreamWriter::append(QCborTag),
123        QCborStreamReader::isTag(), QCborStreamReader::toTag(),
124        QCborValue::isTag(), QCborValue::tag()
125  */
126 
127 /*!
128    \enum QCborKnownTags
129    \relates <QtCborCommon>
130 
131    This enum contains a list of CBOR tags, known at the time of the Qt
132    implementation. This list is not meant to be complete and contains only
133    tags that are either backed by an RFC or specifically used by the Qt
134    implementation.
135 
136    The authoritative list is maintained by IANA in the
137    \l{https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml}{CBOR tag
138    registry}.
139 
140    \value DateTimeString        A date and time string, formatted according to RFC 3339, as refined
141                                 by RFC 4287. It is the same format as Qt::ISODate and
142                                 Qt::ISODateWithMs.
143    \value UnixTime_t            A numerical representation of seconds elapsed since
144                                 1970-01-01T00:00Z.
145    \value PositiveBignum        A positive number of arbitrary length, encoded as a byte array in
146                                 network byte order. For example, the number 2\sup{64} is represented by
147                                 a byte array containing the byte value 0x01 followed by 8 zero bytes.
148    \value NegativeBignum        A negative number of arbirary length, encoded as the absolute value
149                                 of that number, minus one. For example, a byte array containing
150                                 byte value 0x02 followed by 8 zero bytes represents the number
151                                 -2\sup{65} - 1.
152    \value Decimal               A decimal fraction, encoded as an array of two integers: the first
153                                 is the exponent of the power of 10, the second the integral
154                                 mantissa. The value 273.15 would be encoded as array \c{[-2, 27315]}.
155    \value Bigfloat              Similar to Decimal, but the exponent is a power of 2 instead.
156    \value COSE_Encrypt0         An \c Encrypt0 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
157                                 (CBOR Object Signing and Encryption).
158    \value COSE_Mac0             A \c Mac0 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
159                                 (CBOR Object Signing and Encryption).
160    \value COSE_Sign1            A \c Sign1 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
161                                 (CBOR Object Signing and Encryption).
162    \value ExpectedBase64url     Indicates that the byte array should be encoded using Base64url
163                                 if the stream is converted to JSON.
164    \value ExpectedBase64        Indicates that the byte array should be encoded using Base64
165                                 if the stream is converted to JSON.
166    \value ExpectedBase16        Indicates that the byte array should be encoded using Base16 (hex)
167                                 if the stream is converted to JSON.
168    \value EncodedCbor           Indicates that the byte array contains a CBOR stream.
169    \value Url                   Indicates that the string contains a URL.
170    \value Base64url             Indicates that the string contains data encoded using Base64url.
171    \value Base64                Indicates that the string contains data encoded using Base64.
172    \value RegularExpression     Indicates that the string contains a Perl-Compatible Regular
173                                 Expression pattern.
174    \value MimeMessage           Indicates that the string contains a MIME message (according to
175                                 \l{https://tools.ietf.org/html/rfc2045}){RFC 2045}.
176    \value Uuid                  Indicates that the byte array contains a UUID.
177    \value COSE_Encrypt          An \c Encrypt map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
178                                 (CBOR Object Signing and Encryption).
179    \value COSE_Mac              A \c Mac map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
180                                 (CBOR Object Signing and Encryption).
181    \value COSE_Sign             A \c Sign map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
182                                 (CBOR Object Signing and Encryption).
183    \value Signature             No change in interpretation; this tag can be used as the outermost
184                                 tag in a CBOR stream as the file header.
185 
186    The following tags are interpreted by QCborValue during decoding and will
187    produce objects with extended Qt types, and it will use those tags when
188    encoding the same extended types.
189 
190    \value DateTimeString        \l QDateTime
191    \value UnixTime_t            \l QDateTime (only in decoding)
192    \value Url                   \l QUrl
193    \value Uuid                  \l QUuid
194 
195    Additionally, if a QCborValue containing a QByteArray is tagged using one of
196    \c ExpectedBase64url, \c ExpectedBase64 or \c ExpectedBase16, QCborValue
197    will use the expected encoding when converting to JSON (see
198    QCborValue::toJsonValue).
199 
200    \sa QCborTag, QCborStreamWriter::append(QCborTag),
201        QCborStreamReader::isTag(), QCborStreamReader::toTag(),
202        QCborValue::isTag(), QCborValue::tag()
203  */
204 
205 /*!
206    \class QCborError
207    \inmodule QtCore
208    \inheaderfile QtCborCommon
209    \reentrant
210    \since 5.12
211 
212    \brief The QCborError class holds the error condition found while parsing or
213    validating a CBOR stream.
214 
215    \sa QCborStreamReader, QCborValue, QCborParserError
216  */
217 
218 /*!
219    \enum QCborError::Code
220 
221    This enum contains the possible error condition codes.
222 
223    \value NoError           No error was detected.
224    \value UnknownError      An unknown error occurred and no further details are available.
225    \value AdvancePastEnd    QCborStreamReader::next() was called but there are no more elements in
226                             the current context.
227    \value InputOutputError  An I/O error with the QIODevice occurred.
228    \value GarbageAtEnd      Data was found in the input stream after the last element.
229    \value EndOfFile         The end of the input stream was unexpectedly reached while processing an
230                             element.
231    \value UnexpectedBreak   The CBOR stream contains a Break where it is not allowed (data is
232                             corrupt and the error is not recoverable).
233    \value UnknownType       The CBOR stream contains an unknown/unparseable Type (data is corrupt
234                             and the and the error is not recoverable).
235    \value IllegalType       The CBOR stream contains a known type in a position it is not allowed
236                             to exist (data is corrupt and the error is not recoverable).
237    \value IllegalNumber     The CBOR stream appears to be encoding a number larger than 64-bit
238                             (data is corrupt and the error is not recoverable).
239    \value IllegalSimpleType The CBOR stream contains a Simple Type encoded incorrectly (data is
240                             corrupt and the error is not recoverable).
241    \value InvalidUtf8String The CBOR stream contains a text string that does not decode properly
242                             as UTF-8 (data is corrupt and the error is not recoverable).
243    \value DataTooLarge      CBOR string, map or array is too big and cannot be parsed by Qt
244                             (internal limitation, but the error is not recoverable).
245    \value NestingTooDeep    Too many levels of arrays or maps encountered while processing the
246                             input (internal limitation, but the error is not recoverable).
247    \value UnsupportedType   The CBOR stream contains a known type that the implementation does not
248                             support (internal limitation, but the error is not recoverable).
249  */
250 
251 /*!
252    \variable QCborError::c
253    \internal
254  */
255 
256 /*!
257    \fn QCborError::operator Code() const
258 
259    Returns the error code that this QCborError object stores.
260  */
261 
262 /*!
263    Returns a text string that matches the error code in this QCborError object.
264 
265    Note: the string is not translated. Applications whose interface allow users
266    to parse CBOR streams need to provide their own, translated strings.
267 
268    \sa QCborError::Code
269  */
toString() const270 QString QCborError::toString() const
271 {
272     switch (c) {
273     case NoError:
274         Q_STATIC_ASSERT(int(NoError) == int(CborNoError));
275         return QString();
276 
277     case UnknownError:
278         Q_STATIC_ASSERT(int(UnknownError) == int(CborUnknownError));
279         return QStringLiteral("Unknown error");
280     case AdvancePastEnd:
281         Q_STATIC_ASSERT(int(AdvancePastEnd) == int(CborErrorAdvancePastEOF));
282         return QStringLiteral("Read past end of buffer (more bytes needed)");
283     case InputOutputError:
284         Q_STATIC_ASSERT(int(InputOutputError) == int(CborErrorIO));
285         return QStringLiteral("Input/Output error");
286     case GarbageAtEnd:
287         Q_STATIC_ASSERT(int(GarbageAtEnd) == int(CborErrorGarbageAtEnd));
288         return QStringLiteral("Data found after the end of the stream");
289     case EndOfFile:
290         Q_STATIC_ASSERT(int(EndOfFile) == int(CborErrorUnexpectedEOF));
291         return QStringLiteral("Unexpected end of input data (more bytes needed)");
292     case UnexpectedBreak:
293         Q_STATIC_ASSERT(int(UnexpectedBreak) == int(CborErrorUnexpectedBreak));
294         return QStringLiteral("Invalid CBOR stream: unexpected 'break' byte");
295     case UnknownType:
296         Q_STATIC_ASSERT(int(UnknownType) == int(CborErrorUnknownType));
297         return QStringLiteral("Invalid CBOR stream: unknown type");
298     case IllegalType:
299         Q_STATIC_ASSERT(int(IllegalType) == int(CborErrorIllegalType));
300         return QStringLiteral("Invalid CBOR stream: illegal type found");
301     case IllegalNumber:
302         Q_STATIC_ASSERT(int(IllegalNumber) == int(CborErrorIllegalNumber));
303         return QStringLiteral("Invalid CBOR stream: illegal number encoding (future extension)");
304     case IllegalSimpleType:
305         Q_STATIC_ASSERT(int(IllegalSimpleType) == int(CborErrorIllegalSimpleType));
306         return QStringLiteral("Invalid CBOR stream: illegal simple type");
307     case InvalidUtf8String:
308         Q_STATIC_ASSERT(int(InvalidUtf8String) == int(CborErrorInvalidUtf8TextString));
309         return QStringLiteral("Invalid CBOR stream: invalid UTF-8 text string");
310     case DataTooLarge:
311         Q_STATIC_ASSERT(int(DataTooLarge) == int(CborErrorDataTooLarge));
312         return QStringLiteral("Internal limitation: data set too large");
313     case NestingTooDeep:
314         Q_STATIC_ASSERT(int(NestingTooDeep) == int(CborErrorNestingTooDeep));
315         return QStringLiteral("Internal limitation: data nesting too deep");
316     case UnsupportedType:
317         Q_STATIC_ASSERT(int(UnsupportedType) == int(CborErrorUnsupportedType));
318         return QStringLiteral("Internal limitation: unsupported type");
319     }
320 
321     // get the error string from TinyCBOR
322     CborError err = CborError(int(c));
323     return QString::fromLatin1(cbor_error_string(err));
324 }
325 
326 QT_END_NAMESPACE
327 
328 #ifndef QT_BOOTSTRAPPED
329 #include "moc_qcborcommon.cpp"
330 #endif
331