This method allows for writing raw data directly to the encoding buffer. This can be useful if you have something stored as CBOR encoded data.
Fixes#162.
Signed-off-by: Tofik Sonono <tofiksonono@msn.com>
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
We were returning from the function with the memory we had allocated and
freed, if the second iteration over the string produced a failure that
didn't happen on the first one. This can't happen with pure memory
buffers, but can happen with an external data source that fails to
produce the same contents twice.
I'm documenting that the values in all error conditions except for OOM
are undefined, so one mustn't attempt to use them, even to free. This
does not change behaviour of the library, just documents.
But this commit does make it clear the OOM condition will return a valid
`*buflen` and `next`, the latter of which is new behaviour with this
commit.
Fixes#258.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
There's a discussion in the C and C++ communities whether you're allowed
to use the values of pointers that have been deallocated, if you don't
dereference them. Some argue that it is Undefined Behaviour in spite of
the numeric value stored in the variable not having changed.
Instead of arguing, let's just make sure we don't use the pointers after
they have become dangling. We only needed the offset of how far we've
written into the buffer to restore the state and we have a function that
returns exactly that.
Seen while debugging #259.
Drive-by keep the `buffersize` global variable unchanged until after
`realloc()` has returned with success.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
We hadn't bothered, as this was just example-like code to show how one
could convert from CBOR to JSON. But as it was added to the library (no
extra dependency), we should Do The Right Thing (DTRT) and escape.
This patch could have used cbor_value_to_pretty() to print the string,
which has better support for UTF-8 escaping and thus checks for UTF-8
correctness, but that would make map_to_json()'s metadata functionality
much more complex, especially since we cannot rely on open_memstream()
always being available. Therefore, we are partially duplicating
cborpretty.c's utf8EscapedDump().
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
1024 levels will probably be good enough for everyone, like
cborparser.c. For those for whom it isn't, they can set the limit during
the build.
We already had this for the plain parser, so TinyCBOR wouldn't cause a
stack overflow in case of a malformed stream (intentionally or not) when
simply parsing and advancing over the stream. This same protection
wasn't applied to the content converting from CBOR to JSON.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Coverity complains that, when CBOR_ENCODER_WRITE_FUNCTION is defined,
enc.data is read in cbor_encoder_create_map() when
cbor_encoder_init_writer() didn't write to it.
While 'data' is merely copied in cbor_encoder_create_map(), Coverity
is right, though: reading an uninitialized value is UB.
Fix by setting data.writer to nullptr (abstracting the difference
between C and C++ behind a new macro).
`Q_ASSERT()` disappears in release mode, leading Clang to print a static
analysis warning about an impossible condition:
```
tst_parser.cpp:251:16: warning: variable 'err' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
251 | } else if (ourType == CborTextStringType) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tst_parser.cpp:263:12: note: uninitialized use occurs here
263 | return err;
| ^~~
tst_parser.cpp:251:12: note: remove the 'if' if its condition is always true
```
`Q_UNREACHABLE()` becomes a plain `__builtin_unreachable()` in release
mode.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
The /* fallthrough */ comment isn't always handled, causing some
compilers to complain about falling through.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Follow the same "pattern" as for the rest of the #if directive: first
test if a macro is defined, then test the value. Otherwise the code
triggers a -Wundef warning (e.g. when building in C++).
Homebrew no longer carries precompiled versions of Qt for macos-11, so
switch to macos-13, the last on x86 CPUs (so we can still run
Valgrind). It's also going away after the end of June.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
We don't support this any more.
```
../../src/cbor.h:255:69: error: '_Bool' is a C99 extension [-Werror,-Wc99-extensions]
CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
^
```
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
It doesn't know -Wdiscarded-qualifiers. Reported by @pjonsson on #247.
I really need to switch to CMake - #242
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
The Qt uses test batching and potentially encoder/data.cpp
and parser/data.cpp can end up in the same translation unit.
This can be problematic as they declare symbols with the
same names.
Change both files to use internal linkage in order to avoid
symbols clashing.
Qt is defaulting to QT_NO_FOREACH these days, so make sure we
integrate nicely with downstream and fix the single Q_FOREACH/foreach
user, in tst_encoder.cpp.
Unfortunately, the container's initialization code doesn't exactly
lend itself to making the container const (not even IILE
(Immediately-Invoked Lambda Expression) would help here, due to the
interdependency with `len`), so the idiomatic solution would be to use
std::as_const()/qAsConst().
The former is available from C++17, which we don't require, yet, and
the latter is not available under QT_NO_AS_CONST (the default for Qt
these days), so grab the nettle and implement a t17::as_const() that
switches between a manual implementation of std::as_const and the real
thing, depending on __cpp_lib_as_const. The `t17` here mimicks the qNN
(q20::remove_cvref_t/q23::forward_like/etc) mechanism used in Qt
itself for backports, with s/q/t/ because ... _T_inyCbor.
The t17 implementation is local to tst_encoder.cpp, but can easily be
extracted into a separate header once more users emerge.
Recently I was working on a project where I had to define CBOR_PARSER_ADVANCE_BYTES_FUNCTION and CBOR_PARSER_TRANSFER_STRING_FUNCTION macros. Unfortunately the library doesn't include any external config file and building system I am using provides only possibility to add simple preprocessor definitions (like definition = value) on building script level. Adding macros is not possible. For this reason I am asking if we can add above change - if I add simple definition CBOR_EXTERNAL_CFG by build system then cbor will require cbor_cfg.h file where I can add needed macros.
We had tests for cbor_validate* API for the errors it would find, but not
that it did correctly reported CborNoError where no errors were
expected.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Allow the user to disable -Werror to avoid the following build failure
with gcc 4.8 raised since version 0.6.0 and
https://github.com/intel/tinycbor/commit/e2a4ed135c4d9101c4df83f2dd033cd249b6ef07:
/home/buildroot/autobuild/instance-1/output-1/host/bin/arm-none-linux-gnueabi-gcc -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I./src -std=gnu99 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1 -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion -fPIC -c -o src/cborerrorstrings.pic.o src/cborerrorstrings.c
cc1: error: -Werror=incompatible-pointer-types: no option -Wincompatible-pointer-types
cc1: error: -Werror=int-conversion: no option -Wint-conversion
Fixes:
- http://autobuild.buildroot.org/results/a9f/a9fe64c42bb96f9e7b4af3050464f6570c1c00fa
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Instead of just one function (_cbor_value_get_string_chunk), we now have
_cbor_value_begin_string_iteration, _cbor_value_finish_string_iteration,
_cbor_value_get_string_chunk_size, and _cbor_value_get_string_chunk.
The "begin" function positions the pointer at the first chunk. That's
what makes "get_size" possible, since it doesn't need to check for any
state. The "finish" funcntion allows the caller to distinguish an error
parsing the string from an error parsing the next value.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
We need to re-parse if the input buffer was too short to read the
current element's information. When that happens, the current element
will be CborInvalidType, so we can't easily resume.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>