diff options
author | David McCann <mccannd@uk.ibm.com> | 2021-05-13 06:34:10 +0100 |
---|---|---|
committer | David McCann <mccannd@uk.ibm.com> | 2021-05-13 06:34:10 +0100 |
commit | 00098efc966ee4551255ab5841d83e2e5345a3ad (patch) | |
tree | f26ead399be5306a7a19c7ca39e02e6ecaf06ce8 | |
parent | 9b53c92ea398c479f59f77b2cbd24d2ccf1fc29a (diff) | |
parent | cd7109f767a6d9f20caa9d10fbf4eab9c5262e7a (diff) | |
download | json-c-00098efc966ee4551255ab5841d83e2e5345a3ad.tar.gz |
Merge branch 'json-c:master' into master
50 files changed, 2427 insertions, 1360 deletions
@@ -70,6 +70,7 @@ # It's not good practice to build directly in the source tree # but ignore cmake auto-generated files anyway: /json_config.h +/json.h /config.h /json-c.pc /Makefile @@ -83,7 +84,7 @@ /Testing/ # ...and build artifacts. -/doc +/doc/html /libjson-c.a /libjson-c.so /libjson-c.so.* @@ -7,8 +7,13 @@ Christopher Head <chead@chead.ca> Chris Wolfe <chriswwolfe@gmail.com> C. Watford (christopher.watford@gmail.com) Darjan Krijan <darjan_krijan@gmx.de> +David McCann <mccannd@uk.ibm.com> +dota17 <chenguopingdota@163.com> +Eric Haszlakiewicz <erh+git@nimenees.com> Eric Hawicz <erh+git@nimenees.com> +Gianluigi Tiesi <sherpya@netfarm.it> grdowns <grdowns@microsoft.com> +hofnarr <hofnarr@hofnarr.fi> Ivan Romanov <drizt@land.ru> Jaap Keuter <jaap.keuter@xs4all.nl> janczer <menshikov.ivn@gmail.com> @@ -18,13 +23,19 @@ Jonathan Wiens <j.wiens@teles.com> Jose Bollo <jose.bollo@iot.bzh> Keith Holman <keith.holman@windriver.com> Liang, Gao <liang.gao@intel.com> +Marc <34656315+MarcT512@users.noreply.github.com> max <mpano91@gmail.com> +Micah Snyder <micasnyd@cisco.com> Michael Clark <michael@metaparadigm.com> myd7349 <myd7349@gmail.com> +Pascal Cuoq <cuoq@trust-in-soft.com> Pierce Lopez <pierce.lopez@gmail.com> Po-Chuan Hsieh <sunpoet@sunpoet.net> Ramiro Polla <ramiro.polla@gmail.com> Rikard Falkeborn <rikard.falkeborn@gmail.com> Robert <roby_p97@yahoo.com> Rubasri Kalidas <rubasri.kalidas@intel.com> +Simon McVittie <smcv@collabora.com> +Tobias Stoeckmann <tobias@stoeckmann.org> +Tudor Brindus <me@tbrindus.ca> Unmanned Player <36690541+unmanned-player@users.noreply.github.com> diff --git a/CMakeLists.txt b/CMakeLists.txt index 254d324..e870cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,15 @@ if(POLICY CMP0048) endif() # JSON-C library is C only project. -project(json-c LANGUAGES C VERSION 0.14.99) +if (CMAKE_VERSION VERSION_LESS 3.0) + project(json-c) + set(PROJECT_VERSION_MAJOR "0") + set(PROJECT_VERSION_MINOR "15") + set(PROJECT_VERSION_PATCH "99") + set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +else() + project(json-c LANGUAGES C VERSION 0.15.99) +endif() # If we've got 3.0 then it's good, let's provide support. Otherwise, leave it be. if(POLICY CMP0038) @@ -71,6 +79,10 @@ include(CMakePackageConfigHelpers) option(BUILD_SHARED_LIBS "Default to building shared libraries" ON) option(BUILD_STATIC_LIBS "Default to building static libraries" ON) +if (BUILD_SHARED_LIBS) + add_definitions(-D JSON_C_DLL) +endif() + # Generate a release merge and test it to verify the correctness of republishing the package. ADD_CUSTOM_TARGET(distcheck COMMAND make package_source @@ -83,10 +95,15 @@ COMMAND make package_source ) # Enable or disable features. By default, all features are turned off. -option(ENABLE_RDRAND "Enable RDRAND Hardware RNG Hash Seed" OFF) -option(ENABLE_THREADING "Enable partial threading support." OFF) -option(DISABLE_WERROR "Avoid treating compiler warnings as fatal errors" OFF) -option(DISABLE_BSYMBOLIC "Avoid linking with -Bsymbolic-function" OFF) +option(DISABLE_BSYMBOLIC "Avoid linking with -Bsymbolic-function." OFF) +option(DISABLE_THREAD_LOCAL_STORAGE "Disable using Thread-Local Storage (HAVE___THREAD)." OFF) +option(DISABLE_WERROR "Avoid treating compiler warnings as fatal errors." OFF) +option(ENABLE_RDRAND "Enable RDRAND Hardware RNG Hash Seed." OFF) +option(ENABLE_THREADING "Enable partial threading support." OFF) +option(OVERRIDE_GET_RANDOM_SEED "Override json_c_get_random_seed() with custom code." OFF) +option(DISABLE_EXTRA_LIBS "Avoid linking against extra libraries, such as libbsd." OFF) +option(DISABLE_JSON_POINTER "Disable JSON pointer (RFC6901) support." OFF) + if (UNIX OR MINGW OR CYGWIN) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) @@ -101,6 +118,14 @@ if (MSVC) list(APPEND CMAKE_REQUIRED_FLAGS /wd4996) endif() +if (NOT DISABLE_STATIC_FPIC) + # Use '-fPIC'/'-fPIE' option. + # This will allow other libraries to statically link in libjson-c.a + # which in turn prevents crashes in downstream apps that may use + # a different JSON library with identical symbol names. + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + check_include_file("fcntl.h" HAVE_FCNTL_H) check_include_file("inttypes.h" HAVE_INTTYPES_H) check_include_file(stdarg.h HAVE_STDARG_H) @@ -125,6 +150,7 @@ check_include_file(stdint.h HAVE_STDINT_H) check_include_file(stdlib.h HAVE_STDLIB_H) check_include_file(sys/cdefs.h HAVE_SYS_CDEFS_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H) +check_include_file(sys/random.h HAVE_SYS_RANDOM_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(xlocale.h HAVE_XLOCALE_H) @@ -150,6 +176,17 @@ check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) check_symbol_exists(vprintf "stdio.h" HAVE_VPRINTF) +check_symbol_exists(arc4random "stdlib.h" HAVE_ARC4RANDOM) +if (NOT HAVE_ARC4RANDOM AND DISABLE_EXTRA_LIBS STREQUAL "OFF") + check_include_file(bsd/stdlib.h HAVE_BSD_STDLIB_H) + if (HAVE_BSD_STDLIB_H) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-lbsd") + link_libraries(bsd) + unset(HAVE_ARC4RANDOM CACHE) + check_symbol_exists(arc4random "bsd/stdlib.h" HAVE_ARC4RANDOM) + endif() +endif() + if (HAVE_FCNTL_H) check_symbol_exists(open "fcntl.h" HAVE_OPEN) endif() @@ -171,6 +208,9 @@ endif() if (HAVE_SYSLOG_H) check_symbol_exists(vsyslog "syslog.h" HAVE_VSYSLOG) endif() +if (HAVE_SYS_RANDOM_H) + check_symbol_exists(getrandom "sys/random.h" HAVE_GETRANDOM) +endif() if (HAVE_SYS_RESOURCE_H) check_symbol_exists(getrusage "sys/resource.h" HAVE_GETRUSAGE) endif() @@ -204,27 +244,35 @@ check_type_size(int64_t SIZEOF_INT64_T) check_type_size(long SIZEOF_LONG) check_type_size("long long" SIZEOF_LONG_LONG) check_type_size("size_t" SIZEOF_SIZE_T) +if (MSVC) +list(APPEND CMAKE_EXTRA_INCLUDE_FILES BaseTsd.h) +check_type_size("SSIZE_T" SIZEOF_SSIZE_T) +else() +check_type_size("ssize_t" SIZEOF_SSIZE_T) +endif() check_c_source_compiles( -[=[ +" extern void json_object_get(); -__asm__(".section .gnu.json_object_get\\n\\t.ascii \\"Please link against libjson-c instead of libjson\\"\\n\\t.text"); +__asm__(\".section .gnu.json_object_get\\n\\t.ascii \\\"Please link against libjson-c instead of libjson\\\"\\n\\t.text\"); int main(int c, char *v) { return 0;} -]=] +" HAS_GNU_WARNING_LONG) check_c_source_compiles( "int main() { int i, x = 0; i = __sync_add_and_fetch(&x,1); return x; }" HAVE_ATOMIC_BUILTINS) -check_c_source_compiles( - "__thread int x = 0; int main() { return 0; }" - HAVE___THREAD) +if (NOT DISABLE_THREAD_LOCAL_STORAGE) + check_c_source_compiles( + "__thread int x = 0; int main() { return 0; }" + HAVE___THREAD) -if (HAVE___THREAD) - set(SPEC___THREAD __thread) -elseif (MSVC) - set(SPEC___THREAD __declspec(thread)) + if (HAVE___THREAD) + set(SPEC___THREAD __thread) + elseif (MSVC) + set(SPEC___THREAD __declspec(thread)) + endif() endif() # Hardware random number is not available on Windows? Says, config.h.win32. Best to preserve compatibility. @@ -234,11 +282,11 @@ endif() # Once we've done basic symbol/header searches let's add them in. configure_file(${PROJECT_SOURCE_DIR}/cmake/config.h.in ${PROJECT_BINARY_DIR}/config.h) -message(STATUS "Written ${PROJECT_BINARY_DIR}/config.h") +message(STATUS "Wrote ${PROJECT_BINARY_DIR}/config.h") configure_file(${PROJECT_SOURCE_DIR}/cmake/json_config.h.in ${PROJECT_BINARY_DIR}/json_config.h) -message(STATUS "Written ${PROJECT_BINARY_DIR}/json_config.h") +message(STATUS "Wrote ${PROJECT_BINARY_DIR}/json_config.h") -if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") +if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") if ("${DISABLE_WERROR}" STREQUAL "OFF") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") @@ -267,7 +315,7 @@ endif() if (NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")) check_c_source_compiles( - [=[ + " /* uClibc toolchains without threading barf when _REENTRANT is defined */ #define _REENTRANT 1 #include <sys/types.h> @@ -275,7 +323,7 @@ if (NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")) { return 0; } - ]=] + " REENTRANT_WORKS ) if (REENTRANT_WORKS) @@ -286,12 +334,12 @@ if (NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")) # Others may not support it, too. list(APPEND CMAKE_REQUIRED_LIBRARIES "-Wl,-Bsymbolic-functions") check_c_source_compiles( - [=[ + " int main (void) { return 0; } - ]=] + " BSYMBOLIC_WORKS ) list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "-Wl,-Bsymbolic-functions") @@ -300,6 +348,22 @@ if (NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")) # XXX need cmake>=3.13 for this: #add_link_options("-Wl,-Bsymbolic-functions") endif() + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/check-version-script.sym" "TEST { global: *; };") + list(APPEND CMAKE_REQUIRED_LIBRARIES "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/check-version-script.sym") + check_c_source_compiles( + " + int main (void) + { + return 0; + } + " + VERSION_SCRIPT_WORKS + ) + list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/check-version-script.sym") + if (VERSION_SCRIPT_WORKS) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/json-c.sym") + endif() endif() if ($ENV{VALGRIND}) @@ -311,14 +375,13 @@ set(JSON_C_PUBLIC_HEADERS # Note: config.h is _not_ included here ${PROJECT_BINARY_DIR}/json_config.h - ${PROJECT_SOURCE_DIR}/json.h + ${PROJECT_BINARY_DIR}/json.h ${PROJECT_SOURCE_DIR}/arraylist.h ${PROJECT_SOURCE_DIR}/debug.h ${PROJECT_SOURCE_DIR}/json_c_version.h ${PROJECT_SOURCE_DIR}/json_inttypes.h ${PROJECT_SOURCE_DIR}/json_object.h ${PROJECT_SOURCE_DIR}/json_object_iterator.h - ${PROJECT_SOURCE_DIR}/json_pointer.h ${PROJECT_SOURCE_DIR}/json_tokener.h ${PROJECT_SOURCE_DIR}/json_types.h ${PROJECT_SOURCE_DIR}/json_util.h @@ -345,7 +408,6 @@ set(JSON_C_SOURCES ${PROJECT_SOURCE_DIR}/json_c_version.c ${PROJECT_SOURCE_DIR}/json_object.c ${PROJECT_SOURCE_DIR}/json_object_iterator.c - ${PROJECT_SOURCE_DIR}/json_pointer.c ${PROJECT_SOURCE_DIR}/json_tokener.c ${PROJECT_SOURCE_DIR}/json_util.c ${PROJECT_SOURCE_DIR}/json_visit.c @@ -355,26 +417,20 @@ set(JSON_C_SOURCES ${PROJECT_SOURCE_DIR}/strerror_override.c ) -include_directories(${PROJECT_SOURCE_DIR}) -include_directories(${PROJECT_BINARY_DIR}) - -# generate doxygen documentation for json-c API - -find_package(Doxygen) -option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation(requires Doxygen)" ${DOXYGEN_FOUND}) - -if (DOXYGEN_FOUND) +if (NOT DISABLE_JSON_POINTER) + set(JSON_C_PUBLIC_HEADERS ${JSON_C_PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/json_pointer.h) + set(JSON_C_SOURCES ${JSON_C_SOURCES} ${PROJECT_SOURCE_DIR}/json_pointer.c) + set(JSON_H_JSON_POINTER "#include \"json_pointer.h\"") +else() + set(JSON_H_JSON_POINTER "") +endif() - add_custom_target(doc - COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_SOURCE_DIR}/Doxyfile - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) +configure_file(json.h.cmakein ${PROJECT_BINARY_DIR}/json.h @ONLY) - # request to configure the file - configure_file(Doxyfile Doxyfile) +include_directories(${PROJECT_SOURCE_DIR}) +include_directories(${PROJECT_BINARY_DIR}) -else (DOXYGEN_FOUND) - message("Warning: doxygen not found, the 'doc' target will not be included") -endif(DOXYGEN_FOUND) +add_subdirectory(doc) # uninstall add_custom_target(uninstall @@ -390,7 +446,7 @@ add_library(${PROJECT_NAME} ${JSON_C_HEADERS} ) set_target_properties(${PROJECT_NAME} PROPERTIES - VERSION 5.0.0 + VERSION 5.1.0 SOVERSION 5) list(APPEND CMAKE_TARGETS ${PROJECT_NAME}) # If json-c is used as subroject it set to target correct interface -I flags and allow @@ -1,17 +1,76 @@ -Next Release 0.15 +Next Release 0.16 ===================== +...no changes yet... + + +*** + +0.15 (up to commit 870965e, 2020/07/26) +======================================== + Deprecated and removed features: -------------------------------- -...none yet... +* Deprecate `array_list_new()` in favor of `array_list_new2()` +* Remove the THIS_FUNCTION_IS_DEPRECATED define. +* Remove config.h.win32 + +New features +------------ +* Add a `JSON_TOKENER_ALLOW_TRAILING_CHARS` flag to allow multiple objects + to be parsed even when `JSON_TOKENER_STRICT` is set. +* Add `json_object_new_array_ext(int)` and `array_list_new_2(int)` to allow + arrays to be allocated with the exact size needed, when known. +* Add `json_object_array_shrink()` (and `array_list_shrink()`) and use it in + json_tokener to minimize the amount of memory used. +* Add a json_parse binary, for use in testing changes (not installed, but + available in the apps directory). + +Build changes +------------- +* #639/#621 - Add symbol versions to all exported symbols +* #508/#634 - Always enable -fPIC to allow use of the json-c static library in + other libraries +* Build both static and shared libraries at the same time. +* #626 - Restore compatibility with cmake 2.8 +* #471 - Always create directories with mode 0755, regardless of umask. +* #606/#604 - Improve support for OSes like AIX and IBM i, as well as for + MINGW32 and old versions of MSVC +* #451/#617 - Add a DISABLE_THREAD_LOCAL_STORAGE cmake option to disable + the use of thread-local storage. + +Significant changes and bug fixes +--------------------------------- +* Split the internal json_object structure into several sub-types, one for + each json_type (json_object_object, json_object_string, etc...). + This improves memory usage and speed, with the benchmark under + bench/ report 5.8% faster test time and 6%(max RSS)-12%(peak heap) + less memory usage. + Memory used just for json_object structures decreased 27%, so use cases + with fewer arrays and/or strings would benefit more. +* Minimize memory usage in array handling in json_tokener by shrinking + arrays to the exact number of elements parsed. On bench/ benchmark: + 9% faster test time, 39%(max RSS)-50%(peak heap) less memory usage. + Add json_object_array_shrink() and array_list_shrink() functions. +* #616 - Parsing of surrogate pairs in unicode escapes now properly handles + incremental parsing. +* Fix incremental parsing of numbers, especially those with exponents, e.g. + so parsing "[0", "e+", "-]" now properly returns an error. + Strict mode now rejects missing exponents ("0e"). +* Successfully return number objects at the top level even when they are + followed by a "-", "." or "e". This makes parsing things like "123-45" + behave consistently with things like "123xyz". Other changes --------------- -* Add a json_parse binary, for use in testing changes (not installed). -* Issue #471: always create directories with mode 0755, regardless of umask. -* Added a JSON_TOKENER_ALLOW_TRAILING_CHARS flag to allow multiple objects - to be parsed even when JSON_TOKENER_STRICT is set. +------------- +* #589 - Detect broken RDRAND during initialization; also, fix segfault + in the CPUID check. +* #592 - Fix integer overflows to prevert out of bounds write on large input. +* Protect against division by zero in linkhash, when creaed with zero size. +* #602 - Fix json_parse_uint64() internal error checking, leaving the retval + untouched in more failure cases. +* #614 - Prevent truncation when custom double formatters insert extra \0's *** @@ -1,3 +1,5 @@ +\mainpage + `json-c` ======== @@ -35,7 +37,7 @@ Home page for json-c: https://github.com/json-c/json-c/wiki - `gcc`, `clang`, or another C compiler - - cmake>=2.8, >=3.16 recommended + - `cmake>=2.8`, `>=3.16` recommended To generate docs you'll also need: - `doxygen>=1.8.13` @@ -78,7 +80,7 @@ $ make install ### Generating documentation with Doxygen: -The libray documentation can be generated directly from the source codes using Doxygen tool: +The library documentation can be generated directly from the source code using Doxygen tool: ```sh # in build directory @@ -93,16 +95,19 @@ CMake Options <a name="CMake"></a> The json-c library is built with [CMake](https://cmake.org/cmake-tutorial/), which can take a few options. -Variable | Type | Description ----------------------|--------|-------------- -CMAKE_INSTALL_PREFIX | String | The install location. -CMAKE_BUILD_TYPE | String | Defaults to "debug" -BUILD_SHARED_LIBS | Bool | The default build generates a dynamic (dll/so) library. Set this to OFF to create a static library only. -BUILD_STATIC_LIBS | Bool | The default build generates a static (lib/a) library. Set this to OFF to create a shared library only. -ENABLE_RDRAND | Bool | Enable RDRAND Hardware RNG Hash Seed -ENABLE_THREADING | Bool | Enable partial threading support -DISABLE_WERROR | Bool | Disable use of -Werror -DISABLE_BSYMBOLIC | Bool | Disable use of -Bsymbolic-functions +Variable | Type | Description +-----------------------------|--------|-------------- +CMAKE_INSTALL_PREFIX | String | The install location. +CMAKE_BUILD_TYPE | String | Defaults to "debug". +BUILD_SHARED_LIBS | Bool | The default build generates a dynamic (dll/so) library. Set this to OFF to create a static library only. +BUILD_STATIC_LIBS | Bool | The default build generates a static (lib/a) library. Set this to OFF to create a shared library only. +DISABLE_STATIC_FPIC | Bool | The default builds position independent code. Set this to OFF to create a shared library only. +DISABLE_BSYMBOLIC | Bool | Disable use of -Bsymbolic-functions. +DISABLE_THREAD_LOCAL_STORAGE | Bool | Disable use of Thread-Local Storage (HAVE___THREAD). +DISABLE_WERROR | Bool | Disable use of -Werror. +ENABLE_RDRAND | Bool | Enable RDRAND Hardware RNG Hash Seed. +ENABLE_THREADING | Bool | Enable partial threading support. +OVERRIDE_GET_RANDOM_SEED | String | A block of code to use instead of the default implementation of json_c_get_random_seed(), e.g. on embedded platforms where not even the fallback to time() works. Must be a single line. Pass these options as `-D` on CMake's command-line. @@ -234,8 +239,38 @@ following more specific header files: * json_tokener.h - Methods for parsing and serializing json-c object trees. * json_pointer.h - JSON Pointer (RFC 6901) implementation for retrieving objects from a json-c object tree. -* json_object_iterator.h - Methods for iterating over single json_object instances. +* json_object_iterator.h - Methods for iterating over single json_object instances. (See also `json_object_object_foreach()` in json_object.h) * json_visit.h - Methods for walking a tree of json-c objects. -* json_util.h - Miscelleanous utility functions. +* json_util.h - Miscellaneous utility functions. + +For a full list of headers see [files.html](http://json-c.github.io/json-c/json-c-current-release/doc/html/files.html) + +The primary type in json-c is json_object. It describes a reference counted +tree of json objects which are created by either parsing text with a +json_tokener (i.e. `json_tokener_parse_ex()`), or by creating +(with `json_object_new_object()`, `json_object_new_int()`, etc...) and adding +(with `json_object_object_add()`, `json_object_array_add()`, etc...) them +individually. +Typically, every object in the tree will have one reference, from its parent. +When you are done with the tree of objects, you call json_object_put() on just +the root object to free it, which recurses down through any child objects +calling json_object_put() on each one of those in turn. + +You can get a reference to a single child +(`json_object_object_get()` or `json_object_array_get_idx()`) +and use that object as long as its parent is valid. +If you need a child object to live longer than its parent, you can +increment the child's refcount (`json_object_get()`) to allow it to survive +the parent being freed or it being removed from its parent +(`json_object_object_del()` or `json_object_array_del_idx()`) + +When parsing text, the json_tokener object is independent from the json_object +that it returns. It can be allocated (`json_tokener_new()`) +used one or multiple times (`json_tokener_parse_ex()`, and +freed (`json_tokener_free()`) while the json_object objects live on. + +A json_object tree can be serialized back into a string with +`json_object_to_json_string_ext()`. The string that is returned +is only valid until the next "to_json_string" call on that same object. +Also, it is freed when the json_object is freed. -For a full list of headers see [files.html](http://json-c.github.io/json-c/json-c-0.13.1/doc/html/files.html) diff --git a/RELEASE_CHECKLIST.txt b/RELEASE_CHECKLIST.txt index 94f5307..9f6b6db 100644 --- a/RELEASE_CHECKLIST.txt +++ b/RELEASE_CHECKLIST.txt @@ -18,7 +18,15 @@ * https://github.com/lvc/abi-compliance-checker * If the new release is not backwards compatible, then this is a MAJOR release. * Mention removed features in ChangeLog + * Consider re-adding backwards compatible support, through symbol + aliases and appropriate entries in json-c.sym + * Be sure any new symbols are listed in json-c.sym as part of + the _new_ release version. * Update the AUTHORS file + + git log -r 31ab57ca..HEAD | grep Author: | sed -e's/Author: //' ; cat AUTHORS ) | sort -u > A1 + mv A1 AUTHORS + * Exclude mentioning changes that have already been included in a point release of the previous release branch. @@ -31,14 +39,14 @@ ## Release creation Start creating the new release: - release=0.15 + release=0.16 git clone https://github.com/json-c/json-c json-c-${release} mkdir distcheck cd distcheck # Note, the build directory *must* be entirely separate from # the source tree for distcheck to work properly. - cmake ../json-c-${release} + cmake -DCMAKE_BUILD_TYPE=Release ../json-c-${release} make distcheck cd .. @@ -52,9 +60,7 @@ Make any fixes/changes *before* branching. Using ${release}: Update the version in json_c_version.h - Update the version in Doxyfile (PROJECT_NUMBER) Update the version in CMakeLists.txt (VERSION in the project(...) line) - Update the version in config.h.win32 (several places) Update the set_target_properties() line in CmakeLists.txt to set the shared library version. Generally, unless we're doing a major release, change: @@ -64,13 +70,20 @@ to git commit -a -m "Bump version to ${release}" +If we're doing a major release (SONAME bump), also bump the version + of ALL symbols in json-c.sym. + See explanation at https://github.com/json-c/json-c/issues/621 + More info at: https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf + ------------ Generate the doxygen documentation: - doxygen + (cd ../distcheck && make doc) + cp -r -p ../distcheck/doc/{html,Doxyfile} doc/. + rm doc/Doxyfile # Remove generated file w/ hardcoded paths git add -f doc - git commit doc + git commit doc -m "Generate docs for the ${release} release" ------------ @@ -80,7 +93,7 @@ Create the release tarballs: echo .git > excludes tar -czf json-c-${release}.tar.gz -X excludes json-c-${release} - echo doc >> excludes + echo 'doc/*' >> excludes tar -czf json-c-${release}-nodoc.tar.gz -X excludes json-c-${release} ------------ @@ -98,7 +111,7 @@ Tag the branch: Go to Amazon S3 service at: https://console.aws.amazon.com/s3/ -Upload the two tarballs in the json-c_releases folder. +Upload the two tarballs in the json-c_releases/releases folder. When uploading, use "Standard" storage class, and make the uploaded files publicly accessible. Logout of Amazon S3, and verify that the files are visible. @@ -114,15 +127,15 @@ Add new section to ChangeLog for ${release}+1 Use ${release}.99 to indicate a version "newer" than anything on the branch: Update the version in json_c_version.h - Update the version in Doxyfile Update the version in CMakeLists.txt - Update the version in config.h.win32 Update RELEASE_CHECKLIST.txt, set release=${release}+1 +Add a new empty section to the json-c.sym file, for ${release}+1 + Update the set_target_properties() line in CmakeLists.txt to match the release branch. - git commit -a -m "Update the master branch to version 0.${release}.99" + git commit -a -m "Update the master branch to version ${release}.99" git push ------------ @@ -138,6 +151,8 @@ Update the gh-pages branch with new docs: mkdir json-c-${release} cp -R ../json-c-${release}/doc json-c-${release}/. git add json-c-${release} + rm json-c-current-release + ln -s json-c-${release} json-c-current-release git commit -a -m "Add the ${release} docs." vi index.html diff --git a/apps/json_parse.c b/apps/json_parse.c index bba4622..72b31a8 100644 --- a/apps/json_parse.c +++ b/apps/json_parse.c @@ -82,7 +82,8 @@ static int parseit(int fd, int (*callback)(struct json_object *)) int parse_end = json_tokener_get_parse_end(tok); if (obj == NULL && jerr != json_tokener_continue) { - char *aterr = &buf[start_pos + parse_end]; + char *aterr = (start_pos + parse_end < sizeof(buf)) ? + &buf[start_pos + parse_end] : ""; fflush(stdout); int fail_offset = total_read - ret + start_pos + parse_end; fprintf(stderr, "Failed at offset %d: %s %c\n", fail_offset, diff --git a/arraylist.c b/arraylist.c index e5524ac..d8e12d1 100644 --- a/arraylist.c +++ b/arraylist.c @@ -38,15 +38,22 @@ struct array_list *array_list_new(array_list_free_fn *free_fn) { + return array_list_new2(free_fn, ARRAY_LIST_DEFAULT_SIZE); +} + +struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size) +{ struct array_list *arr; - arr = (struct array_list *)calloc(1, sizeof(struct array_list)); + if (initial_size < 0 || (size_t)initial_size >= SIZE_T_MAX / sizeof(void *)) + return NULL; + arr = (struct array_list *)malloc(sizeof(struct array_list)); if (!arr) return NULL; - arr->size = ARRAY_LIST_DEFAULT_SIZE; + arr->size = initial_size; arr->length = 0; arr->free_fn = free_fn; - if (!(arr->array = (void **)calloc(arr->size, sizeof(void *)))) + if (!(arr->array = (void **)malloc(arr->size * sizeof(void *)))) { free(arr); return NULL; @@ -92,11 +99,33 @@ static int array_list_expand_internal(struct array_list *arr, size_t max) if (!(t = realloc(arr->array, new_size * sizeof(void *)))) return -1; arr->array = (void **)t; - (void)memset(arr->array + arr->size, 0, (new_size - arr->size) * sizeof(void *)); arr->size = new_size; return 0; } +int array_list_shrink(struct array_list *arr, size_t empty_slots) +{ + void *t; + size_t new_size; + + if (empty_slots >= SIZE_T_MAX / sizeof(void *) - arr->length) + return -1; + new_size = arr->length + empty_slots; + if (new_size == arr->size) + return 0; + if (new_size > arr->size) + return array_list_expand_internal(arr, new_size); + if (new_size == 0) + new_size = 1; + + if (!(t = realloc(arr->array, new_size * sizeof(void *)))) + return -1; + arr->array = (void **)t; + arr->size = new_size; + return 0; +} + +//static inline int _array_list_put_idx(struct array_list *arr, size_t idx, void *data) int array_list_put_idx(struct array_list *arr, size_t idx, void *data) { if (idx > SIZE_T_MAX - 1) @@ -106,6 +135,17 @@ int array_list_put_idx(struct array_list *arr, size_t idx, void *data) if (idx < arr->length && arr->array[idx]) arr->free_fn(arr->array[idx]); arr->array[idx] = data; + if (idx > arr->length) + { + /* Zero out the arraylist slots in between the old length + and the newly added entry so we know those entries are + empty. + e.g. when setting array[7] in an array that used to be + only 5 elements longs, array[5] and array[6] need to be + set to 0. + */ + memset(arr->array + arr->length, 0, (idx - arr->length) * sizeof(void *)); + } if (arr->length <= idx) arr->length = idx + 1; return 0; @@ -113,7 +153,17 @@ int array_list_put_idx(struct array_list *arr, size_t idx, void *data) int array_list_add(struct array_list *arr, void *data) { - return array_list_put_idx(arr, arr->length, data); + /* Repeat some of array_list_put_idx() so we can skip several + checks that we know are unnecessary when appending at the end + */ + size_t idx = arr->length; + if (idx > SIZE_T_MAX - 1) + return -1; + if (array_list_expand_internal(arr, idx + 1)) + return -1; + arr->array[idx] = data; + arr->length++; + return 0; } void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *)) @@ -144,6 +194,8 @@ int array_list_del_idx(struct array_list *arr, size_t idx, size_t count) return -1; for (i = idx; i < stop; ++i) { + // Because put_idx can skip entries, we need to check if + // there's actually anything in each slot we're erasing. if (arr->array[i]) arr->free_fn(arr->array[i]); } diff --git a/arraylist.h b/arraylist.h index 3c4b1b2..1b18756 100644 --- a/arraylist.h +++ b/arraylist.h @@ -37,8 +37,27 @@ struct array_list }; typedef struct array_list array_list; +/** + * Allocate an array_list of the default size (32). + * @deprecated Use array_list_new2() instead. + */ extern struct array_list *array_list_new(array_list_free_fn *free_fn); +/** + * Allocate an array_list of the desired size. + * + * If possible, the size should be chosen to closely match + * the actual number of elements expected to be used. + * If the exact size is unknown, there are tradeoffs to be made: + * - too small - the array_list code will need to call realloc() more + * often (which might incur an additional memory copy). + * - too large - will waste memory, but that can be mitigated + * by calling array_list_shrink() once the final size is known. + * + * @see array_list_shrink + */ +extern struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size); + extern void array_list_free(struct array_list *al); extern void *array_list_get_idx(struct array_list *al, size_t i); @@ -56,6 +75,12 @@ extern void *array_list_bsearch(const void **key, struct array_list *arr, extern int array_list_del_idx(struct array_list *arr, size_t idx, size_t count); +/** + * Shrink the array list to just enough to fit the number of elements in it, + * plus empty_slots. + */ +extern int array_list_shrink(struct array_list *arr, size_t empty_slots); + #ifdef __cplusplus } #endif diff --git a/cmake-configure b/cmake-configure index c8e44ae..dc695e5 100755 --- a/cmake-configure +++ b/cmake-configure @@ -30,6 +30,7 @@ $0 [<configure_options>] [-- [<cmake options>]] --enable-static build static libraries [default=yes] --disable-Bsymbolic Avoid linking with -Bsymbolic-function --disable-werror Avoid treating compiler warnings as fatal errors + --disable-extra-libs Avoid linking against extra libraries, such as libbsd EOF exit @@ -73,6 +74,9 @@ while [ $# -gt 0 ] ; do --disable-werror) FLAGS+=(-DDISABLE_WERROR=ON) ;; + --disable-extra-libs) + FLAGS+=(-DDISABLE_EXTRA_LIBS=ON) + ;; --) shift break diff --git a/cmake/config.h.in b/cmake/config.h.in index 456c26a..be0202a 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -2,6 +2,9 @@ /* Enable RDRAND Hardware RNG Hash Seed */ #cmakedefine ENABLE_RDRAND "@ENABLE_RDRAND@" +/* Override json_c_get_random_seed() with custom code */ +#cmakedefine OVERRIDE_GET_RANDOM_SEED @OVERRIDE_GET_RANDOM_SEED@ + /* Enable partial threading support */ #cmakedefine ENABLE_THREADING "@@" @@ -53,6 +56,9 @@ /* Define to 1 if you have the <sys/param.h> header file. */ #cmakedefine HAVE_SYS_PARAM_H @HAVE_SYS_PARAM_H@ +/* Define to 1 if you have the <sys/random.h> header file. */ +#cmakedefine HAVE_SYS_RANDOM_H + /* Define to 1 if you have the <sys/resource.h> header file. */ #cmakedefine HAVE_SYS_RESOURCE_H @@ -68,6 +74,12 @@ /* Define to 1 if you have the <xlocale.h> header file. */ #cmakedefine HAVE_XLOCALE_H +/* Define to 1 if you have the <bsd/stdlib.h> header file. */ +#cmakedefine HAVE_BSD_STDLIB_H + +/* Define to 1 if you have `arc4random' */ +#cmakedefine HAVE_ARC4RANDOM + /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #cmakedefine HAVE_DOPRNT @@ -137,6 +149,9 @@ /* Define to 1 if you have the `vsyslog' function. */ #cmakedefine HAVE_VSYSLOG @HAVE_VSYSLOG@ +/* Define if you have the `getrandom' function. */ +#cmakedefine HAVE_GETRANDOM + /* Define if you have the `getrusage' function. */ #cmakedefine HAVE_GETRUSAGE @@ -194,6 +209,9 @@ /* The number of bytes in type size_t */ #cmakedefine SIZEOF_SIZE_T @SIZEOF_SIZE_T@ +/* The number of bytes in type ssize_t */ +#cmakedefine SIZEOF_SSIZE_T @SIZEOF_SSIZE_T@ + /* Specifier for __thread */ #cmakedefine SPEC___THREAD @SPEC___THREAD@ diff --git a/config.h.win32 b/config.h.win32 deleted file mode 100644 index 130378e..0000000 --- a/config.h.win32 +++ /dev/null @@ -1,207 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Enable RDRANR Hardware RNG Hash Seed */ -#undef ENABLE_RDRAND - -/* Define if .gnu.warning accepts long strings. */ -#undef HAS_GNU_WARNING_LONG - -/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you - don't. */ -#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) -#define HAVE_DECL_INFINITY 1 -#endif - -/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. - */ -#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) -#define HAVE_DECL_ISINF 1 -#endif - -/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. - */ -#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) -#define HAVE_DECL_ISNAN 1 -#endif - -/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */ -#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) -#define HAVE_DECL_NAN 1 -#endif - -/* Define to 1 if you have the declaration of `_finite', and to 0 if you - don't. */ -#define HAVE_DECL__FINITE 1 - -/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't. - */ -#define HAVE_DECL__ISNAN 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#define HAVE_DOPRNT 1 - -/* Define to 1 if you have the <endian.h> header file. */ -#undef HAVE_ENDIAN_H - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <locale.h> header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `open' function. */ -#define HAVE_OPEN 1 - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define HAVE_REALLOC 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `snprintf' function. */ -#if defined(__MINGW32__) -#define HAVE_SNPRINTF 1 -#else -#undef HAVE_SNPRINTF -#endif - -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 0 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strncasecmp' function. */ -#if defined(__MINGW32__) -#define HAVE_STRNCASECMP 1 -#else -#undef HAVE_STRNCASECMP -#endif - -#cmakedefine HAVE_STRTOLL -#cmakedefine strtoll @cmake_strtoll@ -#cmakedefine HAVE_STRTOULL -#cmakedefine strtoull @cmake_strtoull@ - -/* Define to 1 if you have the <syslog.h> header file. */ -#undef HAVE_SYSLOG_H - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#if defined(__MINGW32__) -#define HAVE_SYS_PARAM_H 1 -#else -#undef HAVE_SYS_PARAM_H -#endif - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#if defined(__MINGW32__) -#define HAVE_UNISTD_H 1 -#else -#undef HAVE_UNISTD_H -#endif - -/* Define to 1 if you have the `vasprintf' function. */ -#if defined(__MINGW32__) -#define HAVE_VASPRINTF 1 -#else -#undef HAVE_VASPRINTF -#endif - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF 1 - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the `vsyslog' function. */ -#undef HAVE_VSYSLOG - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "json-c" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "json-c@googlegroups.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "JSON C Library" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "JSON C Library 0.14.99" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "json-c" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "https://github.com/json-c/json-c" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.14.99" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.14.99" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ @@ -24,7 +24,7 @@ extern "C" { #endif #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..4872d8e --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,16 @@ +# generate doxygen documentation for json-c API + +find_package(Doxygen) + +if (DOXYGEN_FOUND) + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + message(STATUS "Wrote ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") + + add_custom_target(doc + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + +else (DOXYGEN_FOUND) + message("Warning: doxygen not found, the 'doc' target will not be included") +endif(DOXYGEN_FOUND) diff --git a/Doxyfile b/doc/Doxyfile.in index 06d54e6..e411023 100644 --- a/Doxyfile +++ b/doc/Doxyfile.in @@ -38,7 +38,7 @@ PROJECT_NAME = json-c # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.14.99 +PROJECT_NUMBER = @PROJECT_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doc +OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -753,7 +753,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = +INPUT = @CMAKE_SOURCE_DIR@ @CMAKE_BINARY_DIR@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -805,7 +805,13 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = \ + */json_object_private.h \ + */debug.h \ + */*config.h \ + */random_seed.h \ + */strerror_*h \ + */*compat.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -816,7 +822,11 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = \ + _json_c_* \ + _LH_* \ + _printbuf_* \ + __STRING # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -859,7 +869,7 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. -INPUT_FILTER = +INPUT_FILTER = @CMAKE_CURRENT_SOURCE_DIR@/fixup_markdown.sh # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the diff --git a/doc/fixup_markdown.sh b/doc/fixup_markdown.sh new file mode 100755 index 0000000..452eb78 --- /dev/null +++ b/doc/fixup_markdown.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# +# Doxygen markdown doesn't support triple-backticks like github does. +# Convert all of those to space-prefixed blocks instead. +# +awk '/```/ { prefix=!prefix; print ""; next; } { if (prefix) { printf " "; } print $0; } ' "$@" diff --git a/issues_closed_for_0.13.md b/issues_closed_for_0.13.md index c2b8f2d..f3e932c 100644 --- a/issues_closed_for_0.13.md +++ b/issues_closed_for_0.13.md @@ -16,255 +16,255 @@ Issues and Pull Requests closed for the 0.13 release (since commit f84d9c, the 0.12 branch point, 2014-04-10) -[Issue #61](https://github.com/json-c/json-c/issues/61) - Make json_object_object_add() indicate success or failure, test fix \ -[Issue #113](https://github.com/json-c/json-c/issues/113) - Build fixes (make dist and make distcheck) \ -[Issue #124](https://github.com/json-c/json-c/issues/124) - Fixing build \ -[Issue #125](https://github.com/json-c/json-c/issues/125) - Fix compile error(variable size set but not used) on g++4.6 \ -[Issue #126](https://github.com/json-c/json-c/issues/126) - Removed unused size variable. \ -[Issue #127](https://github.com/json-c/json-c/issues/127) - remove unused `size` variable \ -[Issue #128](https://github.com/json-c/json-c/issues/128) - Remove unused variable from json_tokenizer.c \ -[Issue #130](https://github.com/json-c/json-c/issues/130) - Failed to compile under Ubuntu 13.10 32bit \ -[Issue #131](https://github.com/json-c/json-c/issues/131) - undefined symbol: __sync_val_compare_and_swap_4 \ -[Issue #132](https://github.com/json-c/json-c/issues/132) - Remove unused variable 'size' \ -[Issue #133](https://github.com/json-c/json-c/issues/133) - Update and rename README to README.md \ -[Issue #134](https://github.com/json-c/json-c/issues/134) - Must remove variable size... \ -[Issue #135](https://github.com/json-c/json-c/issues/135) - bits.h uses removed json_tokener_errors\[error\] \ -[Issue #136](https://github.com/json-c/json-c/issues/136) - Error when running make check \ -[Issue #137](https://github.com/json-c/json-c/issues/137) - config.h.in should not be in git \ -[Issue #138](https://github.com/json-c/json-c/issues/138) - Can't build on RHEL 6.5 due to dependency on automake-1.14 \ -[Issue #140](https://github.com/json-c/json-c/issues/140) - Code bug in random_test.c evaluating same expression twice \ -[Issue #141](https://github.com/json-c/json-c/issues/141) - Removed duplicate check in random_seed test - bug #140 \ -[Issue #142](https://github.com/json-c/json-c/issues/142) - Please undeprecate json_object_object_get \ -[Issue #144](https://github.com/json-c/json-c/issues/144) - Introduce json_object_from_fd \ -[Issue #145](https://github.com/json-c/json-c/issues/145) - Handle % character properly \ -[Issue #146](https://github.com/json-c/json-c/issues/146) - TAGS rename \ -[Issue #148](https://github.com/json-c/json-c/issues/148) - Bump the soname \ -[Issue #149](https://github.com/json-c/json-c/issues/149) - SONAME bump \ -[Issue #150](https://github.com/json-c/json-c/issues/150) - Fix build using MinGW. \ -[Issue #151](https://github.com/json-c/json-c/issues/151) - Remove json_type enum trailing comma \ -[Issue #152](https://github.com/json-c/json-c/issues/152) - error while compiling json-c library version 0.11 \ -[Issue #153](https://github.com/json-c/json-c/issues/153) - improve doc for json_object_to_json_string() \ -[Issue #154](https://github.com/json-c/json-c/issues/154) - double precision \ -[Issue #155](https://github.com/json-c/json-c/issues/155) - add bsearch for arrays \ -[Issue #156](https://github.com/json-c/json-c/issues/156) - Remove trailing whitespaces \ -[Issue #157](https://github.com/json-c/json-c/issues/157) - JSON-C shall not exit on calloc fail. \ -[Issue #158](https://github.com/json-c/json-c/issues/158) - while using json-c 0.11, I am facing strange crash issue in json_object_put. \ -[Issue #159](https://github.com/json-c/json-c/issues/159) - json_tokener.c compile error \ -[Issue #160](https://github.com/json-c/json-c/issues/160) - missing header file on windows?? \ -[Issue #161](https://github.com/json-c/json-c/issues/161) - Is there a way to append to file? \ -[Issue #162](https://github.com/json-c/json-c/issues/162) - json_util: add directory check for POSIX distros \ -[Issue #163](https://github.com/json-c/json-c/issues/163) - Fix Win32 build problems \ -[Issue #164](https://github.com/json-c/json-c/issues/164) - made it compile and link on Widnows (as static library) \ -[Issue #165](https://github.com/json-c/json-c/issues/165) - json_object_to_json_string_ext length \ -[Issue #167](https://github.com/json-c/json-c/issues/167) - Can't build on Windows with Visual Studio 2010 \ -[Issue #168](https://github.com/json-c/json-c/issues/168) - Tightening the number parsing algorithm \ -[Issue #169](https://github.com/json-c/json-c/issues/169) - Doesn't compile on ubuntu 14.04, 64bit \ -[Issue #170](https://github.com/json-c/json-c/issues/170) - Generated files in repository \ -[Issue #171](https://github.com/json-c/json-c/issues/171) - Update configuration for VS2010 and win64 \ -[Issue #172](https://github.com/json-c/json-c/issues/172) - Adding support for parsing octal numbers \ -[Issue #173](https://github.com/json-c/json-c/issues/173) - json_parse_int64 doesn't work correctly at illumos \ -[Issue #174](https://github.com/json-c/json-c/issues/174) - Adding JSON_C_TO_STRING_PRETTY_TAB flag \ -[Issue #175](https://github.com/json-c/json-c/issues/175) - make check fails 4 tests with overflows when built with ASAN \ -[Issue #176](https://github.com/json-c/json-c/issues/176) - Possible to delete an array element at a given idx ? \ -[Issue #177](https://github.com/json-c/json-c/issues/177) - Fix compiler warnings \ -[Issue #178](https://github.com/json-c/json-c/issues/178) - Unable to compile on CentOS5 \ -[Issue #179](https://github.com/json-c/json-c/issues/179) - Added array_list_del_idx and json_object_array_del_idx \ -[Issue #180](https://github.com/json-c/json-c/issues/180) - Enable silent build by default \ -[Issue #181](https://github.com/json-c/json-c/issues/181) - json_tokener_parse_ex accepts invalid JSON \ -[Issue #182](https://github.com/json-c/json-c/issues/182) - Link against libm when needed \ -[Issue #183](https://github.com/json-c/json-c/issues/183) - Apply compile warning fix to master branch \ -[Issue #184](https://github.com/json-c/json-c/issues/184) - Use only GCC-specific flags when compiling with GCC \ -[Issue #185](https://github.com/json-c/json-c/issues/185) - compile error \ -[Issue #186](https://github.com/json-c/json-c/issues/186) - Syntax error \ -[Issue #187](https://github.com/json-c/json-c/issues/187) - array_list_get_idx and negative indexes. \ -[Issue #188](https://github.com/json-c/json-c/issues/188) - json_object_object_foreach warnings \ -[Issue #189](https://github.com/json-c/json-c/issues/189) - noisy json_object_from_file: error opening file \ -[Issue #190](https://github.com/json-c/json-c/issues/190) - warning: initialization discards const qualifier from pointer target type \[enabled by default\] \ -[Issue #192](https://github.com/json-c/json-c/issues/192) - json_tokener_parse accepts invalid JSON {"key": "value" , } \ -[Issue #193](https://github.com/json-c/json-c/issues/193) - Make serialization format of doubles configurable \ -[Issue #194](https://github.com/json-c/json-c/issues/194) - Add utility function for comparing json_objects \ -[Issue #195](https://github.com/json-c/json-c/issues/195) - Call uselocale instead of setlocale \ -[Issue #196](https://github.com/json-c/json-c/issues/196) - Performance improvements \ -[Issue #197](https://github.com/json-c/json-c/issues/197) - Time for a new release? \ -[Issue #198](https://github.com/json-c/json-c/issues/198) - Fix possible memory leak and remove superfluous NULL checks before free() \ -[Issue #199](https://github.com/json-c/json-c/issues/199) - Fix build in Visual Studio \ -[Issue #200](https://github.com/json-c/json-c/issues/200) - Add build scripts for CI platforms \ -[Issue #201](https://github.com/json-c/json-c/issues/201) - disable forward-slash escaping? \ -[Issue #202](https://github.com/json-c/json-c/issues/202) - Array with objects support \ -[Issue #203](https://github.com/json-c/json-c/issues/203) - Add source position/coordinates to API \ -[Issue #204](https://github.com/json-c/json-c/issues/204) - json-c/json.h not found \ -[Issue #205](https://github.com/json-c/json-c/issues/205) - json-c Compiled with Visual Studios \ -[Issue #206](https://github.com/json-c/json-c/issues/206) - what do i use in place of json_object_object_get? \ -[Issue #207](https://github.com/json-c/json-c/issues/207) - Add support for property pairs directly added to arrays \ -[Issue #208](https://github.com/json-c/json-c/issues/208) - Performance enhancements (mainly) to json_object_to_json_string() \ -[Issue #209](https://github.com/json-c/json-c/issues/209) - fix regression from 2d549662be832da838aa063da2efa78ee3b99668 \ -[Issue #210](https://github.com/json-c/json-c/issues/210) - Use size_t for arrays \ -[Issue #211](https://github.com/json-c/json-c/issues/211) - Atomic updates for the refcount \ -[Issue #212](https://github.com/json-c/json-c/issues/212) - Refcount doesn't work between threads \ -[Issue #213](https://github.com/json-c/json-c/issues/213) - fix to compile with microsoft visual c++ 2010 \ -[Issue #214](https://github.com/json-c/json-c/issues/214) - Some non-GNU systems support __sync_val_compare_and_swap \ -[Issue #215](https://github.com/json-c/json-c/issues/215) - Build json-c for window 64 bit. \ -[Issue #216](https://github.com/json-c/json-c/issues/216) - configure: check realloc with AC_CHECK_FUNCS() to fix cross-compilation. \ -[Issue #217](https://github.com/json-c/json-c/issues/217) - Checking for functions in float.h \ -[Issue #218](https://github.com/json-c/json-c/issues/218) - Use a macro to indicate C99 to the compiler \ -[Issue #219](https://github.com/json-c/json-c/issues/219) - Fix various potential null ptr deref and int32 overflows \ -[Issue #220](https://github.com/json-c/json-c/issues/220) - Add utility function for comparing json_objects \ -[Issue #221](https://github.com/json-c/json-c/issues/221) - JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \ -[Issue #222](https://github.com/json-c/json-c/issues/222) - Fix issue #221: JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \ -[Issue #223](https://github.com/json-c/json-c/issues/223) - Clarify json_object_get_string documentation of NULL handling & return \ -[Issue #224](https://github.com/json-c/json-c/issues/224) - json_tokener.c - all warnings being treated as errors \ -[Issue #225](https://github.com/json-c/json-c/issues/225) - Hi, will you support clib as a "registry"? \ -[Issue #227](https://github.com/json-c/json-c/issues/227) - Bump SOVERSION to 3 \ -[Issue #228](https://github.com/json-c/json-c/issues/228) - avoid double slashes from json \ -[Issue #229](https://github.com/json-c/json-c/issues/229) - configure fails: checking size of size_t... configure: error: cannot determine a size for size_t \ -[Issue #230](https://github.com/json-c/json-c/issues/230) - Use stdint.h to check for size_t size \ -[Issue #231](https://github.com/json-c/json-c/issues/231) - Fix size_t size check for first-time builds \ -[Issue #232](https://github.com/json-c/json-c/issues/232) - tests/tests1: fix printf format for size_t arguments \ -[Issue #233](https://github.com/json-c/json-c/issues/233) - Include stddef.h in json_object.h \ -[Issue #234](https://github.com/json-c/json-c/issues/234) - Add public API to use userdata independently of custom serializer \ -[Issue #235](https://github.com/json-c/json-c/issues/235) - Undefined symbols Error for architecture x86_64 on Mac \ -[Issue #236](https://github.com/json-c/json-c/issues/236) - Building a project which uses json-c with flag -Wcast-qual causes compilation errors \ -[Issue #237](https://github.com/json-c/json-c/issues/237) - handle escaped utf-8 \ -[Issue #238](https://github.com/json-c/json-c/issues/238) - linkhash.c: optimised the table_free path \ -[Issue #239](https://github.com/json-c/json-c/issues/239) - initialize null terminator of new printbuf \ -[Issue #240](https://github.com/json-c/json-c/issues/240) - Compile error: Variable set but not used \ -[Issue #241](https://github.com/json-c/json-c/issues/241) - getting error in date string 19\/07\/2016, fixed for error 19/07/2016 \ -[Issue #242](https://github.com/json-c/json-c/issues/242) - json_tokener_parse error \ -[Issue #243](https://github.com/json-c/json-c/issues/243) - Fix #165 \ -[Issue #244](https://github.com/json-c/json-c/issues/244) - Error while compiling source from RHEL5, could you please help me to fix this \ -[Issue #245](https://github.com/json-c/json-c/issues/245) - json-c compile in window xp \ -[Issue #246](https://github.com/json-c/json-c/issues/246) - Mac: uselocale failed to build \ -[Issue #247](https://github.com/json-c/json-c/issues/247) - json_object_array_del_idx function has segment fault error? \ -[Issue #248](https://github.com/json-c/json-c/issues/248) - Minor changes in C source code \ -[Issue #249](https://github.com/json-c/json-c/issues/249) - Improving README \ -[Issue #250](https://github.com/json-c/json-c/issues/250) - Improving .gitignore \ -[Issue #251](https://github.com/json-c/json-c/issues/251) - Adding a file for EditorConfig \ -[Issue #252](https://github.com/json-c/json-c/issues/252) - Very minor changes not related to C source code \ -[Issue #253](https://github.com/json-c/json-c/issues/253) - Adding a test with cppcheck for Travis CI \ -[Issue #254](https://github.com/json-c/json-c/issues/254) - Very minor changes to some tests \ -[Issue #255](https://github.com/json-c/json-c/issues/255) - Minor changes in C source code \ -[Issue #256](https://github.com/json-c/json-c/issues/256) - Mailing list dead? \ -[Issue #257](https://github.com/json-c/json-c/issues/257) - Defining a coding style \ -[Issue #258](https://github.com/json-c/json-c/issues/258) - Enable CI services \ -[Issue #259](https://github.com/json-c/json-c/issues/259) - Fails to parse valid json \ -[Issue #260](https://github.com/json-c/json-c/issues/260) - Adding an object to itself \ -[Issue #261](https://github.com/json-c/json-c/issues/261) - Lack of proper documentation \ -[Issue #262](https://github.com/json-c/json-c/issues/262) - Add Cmakefile and fix compiler warning. \ -[Issue #263](https://github.com/json-c/json-c/issues/263) - Compiler Warnings with VS2015 \ -[Issue #264](https://github.com/json-c/json-c/issues/264) - successed in simple test while failed in my project \ -[Issue #265](https://github.com/json-c/json-c/issues/265) - Conformance report for reference \ -[Issue #266](https://github.com/json-c/json-c/issues/266) - crash perhaps related to reference counting \ -[Issue #267](https://github.com/json-c/json-c/issues/267) - Removes me as Win32 maintainer, because I'm not. \ -[Issue #268](https://github.com/json-c/json-c/issues/268) - Documentation of json_object_to_json_string gives no information about memory management \ -[Issue #269](https://github.com/json-c/json-c/issues/269) - json_object_<type>_set(json_object *o,<type> value) API for value setting in json object private structure \ -[Issue #270](https://github.com/json-c/json-c/issues/270) - new API json_object_new_double_f(doubel d,const char * fmt); \ -[Issue #271](https://github.com/json-c/json-c/issues/271) - Cannot compile using CMake on macOS \ -[Issue #273](https://github.com/json-c/json-c/issues/273) - fixed wrong object name in json_object_all_values_equal \ -[Issue #274](https://github.com/json-c/json-c/issues/274) - Support for 64 bit pointers on Windows \ -[Issue #275](https://github.com/json-c/json-c/issues/275) - Out-of-bounds read in json_tokener_parse_ex \ -[Issue #276](https://github.com/json-c/json-c/issues/276) - ./configure for centos release 6.7(final) failure \ -[Issue #277](https://github.com/json-c/json-c/issues/277) - Json object set xxx \ -[Issue #278](https://github.com/json-c/json-c/issues/278) - Serialization of double with no fractional component drops trailing zero \ -[Issue #279](https://github.com/json-c/json-c/issues/279) - Segmentation fault in array_list_length() \ -[Issue #280](https://github.com/json-c/json-c/issues/280) - Should json_object_array_get_idx check whether input obj is array? \ -[Issue #281](https://github.com/json-c/json-c/issues/281) - how to pretty print json-c? \ -[Issue #282](https://github.com/json-c/json-c/issues/282) - ignore temporary files \ -[Issue #283](https://github.com/json-c/json-c/issues/283) - json_pointer: add first revision based on RFC 6901 \ -[Issue #284](https://github.com/json-c/json-c/issues/284) - Resusing json_tokener object \ -[Issue #285](https://github.com/json-c/json-c/issues/285) - Revert "compat/strdup.h: move common compat check for strdup() to own \ -[Issue #286](https://github.com/json-c/json-c/issues/286) - json_tokener_parse_ex() returns json_tokener_continue on zero-length string \ -[Issue #287](https://github.com/json-c/json-c/issues/287) - json_pointer: extend setter & getter with printf() style arguments \ -[Issue #288](https://github.com/json-c/json-c/issues/288) - Fix _GNU_SOURCE define for vasprintf \ -[Issue #289](https://github.com/json-c/json-c/issues/289) - bugfix: floating point representaion without fractional part \ -[Issue #290](https://github.com/json-c/json-c/issues/290) - duplicate an json_object \ -[Issue #291](https://github.com/json-c/json-c/issues/291) - isspace assert error \ -[Issue #292](https://github.com/json-c/json-c/issues/292) - configure error "./configure: line 13121: syntax error near unexpected token `-Wall'" \ -[Issue #293](https://github.com/json-c/json-c/issues/293) - how to make with bitcode for ios \ -[Issue #294](https://github.com/json-c/json-c/issues/294) - Adding UTF-8 validation. Fixes #122 \ -[Issue #295](https://github.com/json-c/json-c/issues/295) - cross compile w/ mingw \ -[Issue #296](https://github.com/json-c/json-c/issues/296) - Missing functions header in json_object.h \ -[Issue #297](https://github.com/json-c/json-c/issues/297) - could not parse string to Json object? Like string str=\"helloworld;E\\test\\log\\;end\" \ -[Issue #298](https://github.com/json-c/json-c/issues/298) - Building using CMake doesn't work \ -[Issue #299](https://github.com/json-c/json-c/issues/299) - Improve json_object -> string performance \ -[Issue #300](https://github.com/json-c/json-c/issues/300) - Running tests with MinGW build \ -[Issue #301](https://github.com/json-c/json-c/issues/301) - How to deep copy json_object in C++ ? \ -[Issue #302](https://github.com/json-c/json-c/issues/302) - json_tokener_parse_ex doesn't parse JSON values \ -[Issue #303](https://github.com/json-c/json-c/issues/303) - fix doc in tokener header file \ -[Issue #304](https://github.com/json-c/json-c/issues/304) - (.text+0x72846): undefined reference to `is_error' \ -[Issue #305](https://github.com/json-c/json-c/issues/305) - Fix compilation without C-99 option \ -[Issue #306](https://github.com/json-c/json-c/issues/306) - ./configure: line 12748 -error=deprecated-declarations \ -[Issue #307](https://github.com/json-c/json-c/issues/307) - Memory leak in json_tokener_parse \ -[Issue #308](https://github.com/json-c/json-c/issues/308) - AM_PROG_LIBTOOL not found on Linux \ -[Issue #309](https://github.com/json-c/json-c/issues/309) - GCC 7 reports various -Wimplicit-fallthrough= errors \ -[Issue #310](https://github.com/json-c/json-c/issues/310) - Add FALLTHRU comment to handle GCC7 warnings. \ -[Issue #311](https://github.com/json-c/json-c/issues/311) - Fix error C3688 when compiling on Visual Studio 2015 \ -[Issue #312](https://github.com/json-c/json-c/issues/312) - Fix CMake Build process improved for MinGW and MSYS2 \ -[Issue #313](https://github.com/json-c/json-c/issues/313) - VERBOSE=1 make check; tests/test_util_file.test.c and tests/test_util_file.expected out of sync \ -[Issue #315](https://github.com/json-c/json-c/issues/315) - Passing -1 to json_tokener_parse_ex is possibly unsafe \ -[Issue #316](https://github.com/json-c/json-c/issues/316) - Memory Returned by json_object_to_json_string not freed \ -[Issue #317](https://github.com/json-c/json-c/issues/317) - json_object_get_string gives segmentation error \ -[Issue #318](https://github.com/json-c/json-c/issues/318) - PVS-Studio static analyzer analyze results \ -[Issue #319](https://github.com/json-c/json-c/issues/319) - Windows: Fix dynamic library build with Visual Studio \ -[Issue #320](https://github.com/json-c/json-c/issues/320) - Can't compile in Mac OS X El Capitan \ -[Issue #321](https://github.com/json-c/json-c/issues/321) - build,cmake: fix vasprintf implicit definition and generate both static & shared libs \ -[Issue #322](https://github.com/json-c/json-c/issues/322) - can not link with libjson-c.a \ -[Issue #323](https://github.com/json-c/json-c/issues/323) - implicit fallthrough detected by gcc 7.1 \ -[Issue #324](https://github.com/json-c/json-c/issues/324) - JsonPath like function? \ -[Issue #325](https://github.com/json-c/json-c/issues/325) - Fix stack buffer overflow in json_object_double_to_json_string_format() \ -[Issue #327](https://github.com/json-c/json-c/issues/327) - why json-c so hard to compile \ -[Issue #328](https://github.com/json-c/json-c/issues/328) - json_object: implement json_object_deep_copy() function \ -[Issue #329](https://github.com/json-c/json-c/issues/329) - build,cmake: build,cmake: rename libjson-c-static.a to libjson-c.a \ -[Issue #330](https://github.com/json-c/json-c/issues/330) - tests: symlink basic tests to a single file that has the common code \ -[Issue #331](https://github.com/json-c/json-c/issues/331) - Safe use of snprintf() / vsnprintf() for Visual studio, and thread-safety fix \ -[Issue #332](https://github.com/json-c/json-c/issues/332) - Valgrind: invalid read after json_object_array_del_idx. \ -[Issue #333](https://github.com/json-c/json-c/issues/333) - Replace obsolete AM_PROG_LIBTOOL \ -[Issue #335](https://github.com/json-c/json-c/issues/335) - README.md: show build status tag from travis-ci.org \ -[Issue #336](https://github.com/json-c/json-c/issues/336) - tests: fix tests in travis-ci.org \ -[Issue #337](https://github.com/json-c/json-c/issues/337) - Synchronize "potentially racy" random seed in lh_char_hash() \ -[Issue #338](https://github.com/json-c/json-c/issues/338) - implement json_object_int_inc(json_object *, int64_t) \ -[Issue #339](https://github.com/json-c/json-c/issues/339) - Json schema validation \ -[Issue #340](https://github.com/json-c/json-c/issues/340) - strerror_override: add extern "C" and JSON_EXPORT specifiers for Visual C++ compilers \ -[Issue #341](https://github.com/json-c/json-c/issues/341) - character "/" parse as "\/" \ -[Issue #342](https://github.com/json-c/json-c/issues/342) - No such file or directory "/usr/include/json.h" \ -[Issue #343](https://github.com/json-c/json-c/issues/343) - Can't parse json \ -[Issue #344](https://github.com/json-c/json-c/issues/344) - Fix Mingw build \ -[Issue #345](https://github.com/json-c/json-c/issues/345) - Fix make dist and make distcheck \ -[Issue #346](https://github.com/json-c/json-c/issues/346) - Clamp double to int32 when narrowing in json_object_get_int. \ -[Issue #347](https://github.com/json-c/json-c/issues/347) - MSVC linker error json_c_strerror \ -[Issue #348](https://github.com/json-c/json-c/issues/348) - why \ -[Issue #349](https://github.com/json-c/json-c/issues/349) - `missing` is missing? \ -[Issue #350](https://github.com/json-c/json-c/issues/350) - stderror-override and disable-shared \ -[Issue #351](https://github.com/json-c/json-c/issues/351) - SIZE_T_MAX redefined from limits.h \ -[Issue #352](https://github.com/json-c/json-c/issues/352) - `INSTALL` overrides an automake script. \ -[Issue #353](https://github.com/json-c/json-c/issues/353) - Documentation issues \ -[Issue #354](https://github.com/json-c/json-c/issues/354) - Fixes #351 #352 #353 \ -[Issue #355](https://github.com/json-c/json-c/issues/355) - 1.make it can been compiled with Visual Studio 2010 by modify the CMakeList.txt and others \ -[Issue #356](https://github.com/json-c/json-c/issues/356) - VS2008 test test_util_file.cpp err! \ -[Issue #357](https://github.com/json-c/json-c/issues/357) - __json_c_strerror incompatibility with link-time optimization \ -[Issue #358](https://github.com/json-c/json-c/issues/358) - make issue \ -[Issue #359](https://github.com/json-c/json-c/issues/359) - update CMakeLists.txt for compile with visual studio at least 2010 \ -[Issue #360](https://github.com/json-c/json-c/issues/360) - Use strtoll() to parse ints \ -[Issue #361](https://github.com/json-c/json-c/issues/361) - Fix double to int cast overflow in json_object_get_int64. \ -[Issue #362](https://github.com/json-c/json-c/issues/362) - CMake Package Config \ -[Issue #363](https://github.com/json-c/json-c/issues/363) - Issue #338, add json_object_add_int functions \ -[Issue #364](https://github.com/json-c/json-c/issues/364) - Cmake is Errir \ -[Issue #365](https://github.com/json-c/json-c/issues/365) - added fallthrough for gcc7 \ -[Issue #366](https://github.com/json-c/json-c/issues/366) - how to check the json string,crash! \ -[Issue #367](https://github.com/json-c/json-c/issues/367) - Is json-c support "redirect" semantic? \ -[Issue #368](https://github.com/json-c/json-c/issues/368) - Add examples \ -[Issue #369](https://github.com/json-c/json-c/issues/369) - How to build json-c library for android? \ -[Issue #370](https://github.com/json-c/json-c/issues/370) - Compiling using clang-cl \ -[Issue #371](https://github.com/json-c/json-c/issues/371) - Invalid parsing for Infinity with json-c 0.12 \ -[Issue #372](https://github.com/json-c/json-c/issues/372) - Json-c 0.12: Fixed Infinity bug \ -[Issue #373](https://github.com/json-c/json-c/issues/373) - build: fix build on appveyor CI \ -[Issue #374](https://github.com/json-c/json-c/issues/374) - Undefined symbols for architecture x86_64: \ -[Issue #375](https://github.com/json-c/json-c/issues/375) - what would happened when json_object_object_add add the same key \ -[Issue #376](https://github.com/json-c/json-c/issues/376) - Eclipse error \ -[Issue #377](https://github.com/json-c/json-c/issues/377) - on gcc 7.2.0 on my linux distribution with json-c 2013-04-02 source \ -[Issue #378](https://github.com/json-c/json-c/issues/378) - Eclipse: library (libjson-c) not found, but configured \ -[Issue #379](https://github.com/json-c/json-c/issues/379) - error: this statement may fall through \[-Werror=implicit-fallthrough=\] \ -[Issue #380](https://github.com/json-c/json-c/issues/380) - Build on Windows \ -[Issue #381](https://github.com/json-c/json-c/issues/381) - Fix makedist \ -[Issue #382](https://github.com/json-c/json-c/issues/382) - Memory leak for json_tokener_parse_ex for version 0.12.1 \ -[Issue #383](https://github.com/json-c/json-c/issues/383) - Fix a compiler warning. \ -[Issue #384](https://github.com/json-c/json-c/issues/384) - Fix a VS 2015 compiler warnings. \ +* [Issue #61](https://github.com/json-c/json-c/issues/61) - Make json_object_object_add() indicate success or failure, test fix \ +* [Issue #113](https://github.com/json-c/json-c/issues/113) - Build fixes (make dist and make distcheck) \ +* [Issue #124](https://github.com/json-c/json-c/issues/124) - Fixing build \ +* [Issue #125](https://github.com/json-c/json-c/issues/125) - Fix compile error(variable size set but not used) on g++4.6 \ +* [Issue #126](https://github.com/json-c/json-c/issues/126) - Removed unused size variable. \ +* [Issue #127](https://github.com/json-c/json-c/issues/127) - remove unused `size` variable \ +* [Issue #128](https://github.com/json-c/json-c/issues/128) - Remove unused variable from json_tokenizer.c \ +* [Issue #130](https://github.com/json-c/json-c/issues/130) - Failed to compile under Ubuntu 13.10 32bit \ +* [Issue #131](https://github.com/json-c/json-c/issues/131) - undefined symbol: __sync_val_compare_and_swap_4 \ +* [Issue #132](https://github.com/json-c/json-c/issues/132) - Remove unused variable 'size' \ +* [Issue #133](https://github.com/json-c/json-c/issues/133) - Update and rename README to README.md \ +* [Issue #134](https://github.com/json-c/json-c/issues/134) - Must remove variable size... \ +* [Issue #135](https://github.com/json-c/json-c/issues/135) - bits.h uses removed json_tokener_errors\[error\] \ +* [Issue #136](https://github.com/json-c/json-c/issues/136) - Error when running make check \ +* [Issue #137](https://github.com/json-c/json-c/issues/137) - config.h.in should not be in git \ +* [Issue #138](https://github.com/json-c/json-c/issues/138) - Can't build on RHEL 6.5 due to dependency on automake-1.14 \ +* [Issue #140](https://github.com/json-c/json-c/issues/140) - Code bug in random_test.c evaluating same expression twice \ +* [Issue #141](https://github.com/json-c/json-c/issues/141) - Removed duplicate check in random_seed test - bug #140 \ +* [Issue #142](https://github.com/json-c/json-c/issues/142) - Please undeprecate json_object_object_get \ +* [Issue #144](https://github.com/json-c/json-c/issues/144) - Introduce json_object_from_fd \ +* [Issue #145](https://github.com/json-c/json-c/issues/145) - Handle % character properly \ +* [Issue #146](https://github.com/json-c/json-c/issues/146) - TAGS rename \ +* [Issue #148](https://github.com/json-c/json-c/issues/148) - Bump the soname \ +* [Issue #149](https://github.com/json-c/json-c/issues/149) - SONAME bump \ +* [Issue #150](https://github.com/json-c/json-c/issues/150) - Fix build using MinGW. \ +* [Issue #151](https://github.com/json-c/json-c/issues/151) - Remove json_type enum trailing comma \ +* [Issue #152](https://github.com/json-c/json-c/issues/152) - error while compiling json-c library version 0.11 \ +* [Issue #153](https://github.com/json-c/json-c/issues/153) - improve doc for json_object_to_json_string() \ +* [Issue #154](https://github.com/json-c/json-c/issues/154) - double precision \ +* [Issue #155](https://github.com/json-c/json-c/issues/155) - add bsearch for arrays \ +* [Issue #156](https://github.com/json-c/json-c/issues/156) - Remove trailing whitespaces \ +* [Issue #157](https://github.com/json-c/json-c/issues/157) - JSON-C shall not exit on calloc fail. \ +* [Issue #158](https://github.com/json-c/json-c/issues/158) - while using json-c 0.11, I am facing strange crash issue in json_object_put. \ +* [Issue #159](https://github.com/json-c/json-c/issues/159) - json_tokener.c compile error \ +* [Issue #160](https://github.com/json-c/json-c/issues/160) - missing header file on windows?? \ +* [Issue #161](https://github.com/json-c/json-c/issues/161) - Is there a way to append to file? \ +* [Issue #162](https://github.com/json-c/json-c/issues/162) - json_util: add directory check for POSIX distros \ +* [Issue #163](https://github.com/json-c/json-c/issues/163) - Fix Win32 build problems \ +* [Issue #164](https://github.com/json-c/json-c/issues/164) - made it compile and link on Widnows (as static library) \ +* [Issue #165](https://github.com/json-c/json-c/issues/165) - json_object_to_json_string_ext length \ +* [Issue #167](https://github.com/json-c/json-c/issues/167) - Can't build on Windows with Visual Studio 2010 \ +* [Issue #168](https://github.com/json-c/json-c/issues/168) - Tightening the number parsing algorithm \ +* [Issue #169](https://github.com/json-c/json-c/issues/169) - Doesn't compile on ubuntu 14.04, 64bit \ +* [Issue #170](https://github.com/json-c/json-c/issues/170) - Generated files in repository \ +* [Issue #171](https://github.com/json-c/json-c/issues/171) - Update configuration for VS2010 and win64 \ +* [Issue #172](https://github.com/json-c/json-c/issues/172) - Adding support for parsing octal numbers \ +* [Issue #173](https://github.com/json-c/json-c/issues/173) - json_parse_int64 doesn't work correctly at illumos \ +* [Issue #174](https://github.com/json-c/json-c/issues/174) - Adding JSON_C_TO_STRING_PRETTY_TAB flag \ +* [Issue #175](https://github.com/json-c/json-c/issues/175) - make check fails 4 tests with overflows when built with ASAN \ +* [Issue #176](https://github.com/json-c/json-c/issues/176) - Possible to delete an array element at a given idx ? \ +* [Issue #177](https://github.com/json-c/json-c/issues/177) - Fix compiler warnings \ +* [Issue #178](https://github.com/json-c/json-c/issues/178) - Unable to compile on CentOS5 \ +* [Issue #179](https://github.com/json-c/json-c/issues/179) - Added array_list_del_idx and json_object_array_del_idx \ +* [Issue #180](https://github.com/json-c/json-c/issues/180) - Enable silent build by default \ +* [Issue #181](https://github.com/json-c/json-c/issues/181) - json_tokener_parse_ex accepts invalid JSON \ +* [Issue #182](https://github.com/json-c/json-c/issues/182) - Link against libm when needed \ +* [Issue #183](https://github.com/json-c/json-c/issues/183) - Apply compile warning fix to master branch \ +* [Issue #184](https://github.com/json-c/json-c/issues/184) - Use only GCC-specific flags when compiling with GCC \ +* [Issue #185](https://github.com/json-c/json-c/issues/185) - compile error \ +* [Issue #186](https://github.com/json-c/json-c/issues/186) - Syntax error \ +* [Issue #187](https://github.com/json-c/json-c/issues/187) - array_list_get_idx and negative indexes. \ +* [Issue #188](https://github.com/json-c/json-c/issues/188) - json_object_object_foreach warnings \ +* [Issue #189](https://github.com/json-c/json-c/issues/189) - noisy json_object_from_file: error opening file \ +* [Issue #190](https://github.com/json-c/json-c/issues/190) - warning: initialization discards const qualifier from pointer target type \[enabled by default\] \ +* [Issue #192](https://github.com/json-c/json-c/issues/192) - json_tokener_parse accepts invalid JSON {"key": "value" , } \ +* [Issue #193](https://github.com/json-c/json-c/issues/193) - Make serialization format of doubles configurable \ +* [Issue #194](https://github.com/json-c/json-c/issues/194) - Add utility function for comparing json_objects \ +* [Issue #195](https://github.com/json-c/json-c/issues/195) - Call uselocale instead of setlocale \ +* [Issue #196](https://github.com/json-c/json-c/issues/196) - Performance improvements \ +* [Issue #197](https://github.com/json-c/json-c/issues/197) - Time for a new release? \ +* [Issue #198](https://github.com/json-c/json-c/issues/198) - Fix possible memory leak and remove superfluous NULL checks before free() \ +* [Issue #199](https://github.com/json-c/json-c/issues/199) - Fix build in Visual Studio \ +* [Issue #200](https://github.com/json-c/json-c/issues/200) - Add build scripts for CI platforms \ +* [Issue #201](https://github.com/json-c/json-c/issues/201) - disable forward-slash escaping? \ +* [Issue #202](https://github.com/json-c/json-c/issues/202) - Array with objects support \ +* [Issue #203](https://github.com/json-c/json-c/issues/203) - Add source position/coordinates to API \ +* [Issue #204](https://github.com/json-c/json-c/issues/204) - json-c/json.h not found \ +* [Issue #205](https://github.com/json-c/json-c/issues/205) - json-c Compiled with Visual Studios \ +* [Issue #206](https://github.com/json-c/json-c/issues/206) - what do i use in place of json_object_object_get? \ +* [Issue #207](https://github.com/json-c/json-c/issues/207) - Add support for property pairs directly added to arrays \ +* [Issue #208](https://github.com/json-c/json-c/issues/208) - Performance enhancements (mainly) to json_object_to_json_string() \ +* [Issue #209](https://github.com/json-c/json-c/issues/209) - fix regression from 2d549662be832da838aa063da2efa78ee3b99668 \ +* [Issue #210](https://github.com/json-c/json-c/issues/210) - Use size_t for arrays \ +* [Issue #211](https://github.com/json-c/json-c/issues/211) - Atomic updates for the refcount \ +* [Issue #212](https://github.com/json-c/json-c/issues/212) - Refcount doesn't work between threads \ +* [Issue #213](https://github.com/json-c/json-c/issues/213) - fix to compile with microsoft visual c++ 2010 \ +* [Issue #214](https://github.com/json-c/json-c/issues/214) - Some non-GNU systems support __sync_val_compare_and_swap \ +* [Issue #215](https://github.com/json-c/json-c/issues/215) - Build json-c for window 64 bit. \ +* [Issue #216](https://github.com/json-c/json-c/issues/216) - configure: check realloc with AC_CHECK_FUNCS() to fix cross-compilation. \ +* [Issue #217](https://github.com/json-c/json-c/issues/217) - Checking for functions in float.h \ +* [Issue #218](https://github.com/json-c/json-c/issues/218) - Use a macro to indicate C99 to the compiler \ +* [Issue #219](https://github.com/json-c/json-c/issues/219) - Fix various potential null ptr deref and int32 overflows \ +* [Issue #220](https://github.com/json-c/json-c/issues/220) - Add utility function for comparing json_objects \ +* [Issue #221](https://github.com/json-c/json-c/issues/221) - JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \ +* [Issue #222](https://github.com/json-c/json-c/issues/222) - Fix issue #221: JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \ +* [Issue #223](https://github.com/json-c/json-c/issues/223) - Clarify json_object_get_string documentation of NULL handling & return \ +* [Issue #224](https://github.com/json-c/json-c/issues/224) - json_tokener.c - all warnings being treated as errors \ +* [Issue #225](https://github.com/json-c/json-c/issues/225) - Hi, will you support clib as a "registry"? \ +* [Issue #227](https://github.com/json-c/json-c/issues/227) - Bump SOVERSION to 3 \ +* [Issue #228](https://github.com/json-c/json-c/issues/228) - avoid double slashes from json \ +* [Issue #229](https://github.com/json-c/json-c/issues/229) - configure fails: checking size of size_t... configure: error: cannot determine a size for size_t \ +* [Issue #230](https://github.com/json-c/json-c/issues/230) - Use stdint.h to check for size_t size \ +* [Issue #231](https://github.com/json-c/json-c/issues/231) - Fix size_t size check for first-time builds \ +* [Issue #232](https://github.com/json-c/json-c/issues/232) - tests/tests1: fix printf format for size_t arguments \ +* [Issue #233](https://github.com/json-c/json-c/issues/233) - Include stddef.h in json_object.h \ +* [Issue #234](https://github.com/json-c/json-c/issues/234) - Add public API to use userdata independently of custom serializer \ +* [Issue #235](https://github.com/json-c/json-c/issues/235) - Undefined symbols Error for architecture x86_64 on Mac \ +* [Issue #236](https://github.com/json-c/json-c/issues/236) - Building a project which uses json-c with flag -Wcast-qual causes compilation errors \ +* [Issue #237](https://github.com/json-c/json-c/issues/237) - handle escaped utf-8 \ +* [Issue #238](https://github.com/json-c/json-c/issues/238) - linkhash.c: optimised the table_free path \ +* [Issue #239](https://github.com/json-c/json-c/issues/239) - initialize null terminator of new printbuf \ +* [Issue #240](https://github.com/json-c/json-c/issues/240) - Compile error: Variable set but not used \ +* [Issue #241](https://github.com/json-c/json-c/issues/241) - getting error in date string 19\/07\/2016, fixed for error 19/07/2016 \ +* [Issue #242](https://github.com/json-c/json-c/issues/242) - json_tokener_parse error \ +* [Issue #243](https://github.com/json-c/json-c/issues/243) - Fix #165 \ +* [Issue #244](https://github.com/json-c/json-c/issues/244) - Error while compiling source from RHEL5, could you please help me to fix this \ +* [Issue #245](https://github.com/json-c/json-c/issues/245) - json-c compile in window xp \ +* [Issue #246](https://github.com/json-c/json-c/issues/246) - Mac: uselocale failed to build \ +* [Issue #247](https://github.com/json-c/json-c/issues/247) - json_object_array_del_idx function has segment fault error? \ +* [Issue #248](https://github.com/json-c/json-c/issues/248) - Minor changes in C source code \ +* [Issue #249](https://github.com/json-c/json-c/issues/249) - Improving README \ +* [Issue #250](https://github.com/json-c/json-c/issues/250) - Improving .gitignore \ +* [Issue #251](https://github.com/json-c/json-c/issues/251) - Adding a file for EditorConfig \ +* [Issue #252](https://github.com/json-c/json-c/issues/252) - Very minor changes not related to C source code \ +* [Issue #253](https://github.com/json-c/json-c/issues/253) - Adding a test with cppcheck for Travis CI \ +* [Issue #254](https://github.com/json-c/json-c/issues/254) - Very minor changes to some tests \ +* [Issue #255](https://github.com/json-c/json-c/issues/255) - Minor changes in C source code \ +* [Issue #256](https://github.com/json-c/json-c/issues/256) - Mailing list dead? \ +* [Issue #257](https://github.com/json-c/json-c/issues/257) - Defining a coding style \ +* [Issue #258](https://github.com/json-c/json-c/issues/258) - Enable CI services \ +* [Issue #259](https://github.com/json-c/json-c/issues/259) - Fails to parse valid json \ +* [Issue #260](https://github.com/json-c/json-c/issues/260) - Adding an object to itself \ +* [Issue #261](https://github.com/json-c/json-c/issues/261) - Lack of proper documentation \ +* [Issue #262](https://github.com/json-c/json-c/issues/262) - Add Cmakefile and fix compiler warning. \ +* [Issue #263](https://github.com/json-c/json-c/issues/263) - Compiler Warnings with VS2015 \ +* [Issue #264](https://github.com/json-c/json-c/issues/264) - successed in simple test while failed in my project \ +* [Issue #265](https://github.com/json-c/json-c/issues/265) - Conformance report for reference \ +* [Issue #266](https://github.com/json-c/json-c/issues/266) - crash perhaps related to reference counting \ +* [Issue #267](https://github.com/json-c/json-c/issues/267) - Removes me as Win32 maintainer, because I'm not. \ +* [Issue #268](https://github.com/json-c/json-c/issues/268) - Documentation of json_object_to_json_string gives no information about memory management \ +* [Issue #269](https://github.com/json-c/json-c/issues/269) - json_object_<type>_set(json_object *o,<type> value) API for value setting in json object private structure \ +* [Issue #270](https://github.com/json-c/json-c/issues/270) - new API json_object_new_double_f(doubel d,const char * fmt); \ +* [Issue #271](https://github.com/json-c/json-c/issues/271) - Cannot compile using CMake on macOS \ +* [Issue #273](https://github.com/json-c/json-c/issues/273) - fixed wrong object name in json_object_all_values_equal \ +* [Issue #274](https://github.com/json-c/json-c/issues/274) - Support for 64 bit pointers on Windows \ +* [Issue #275](https://github.com/json-c/json-c/issues/275) - Out-of-bounds read in json_tokener_parse_ex \ +* [Issue #276](https://github.com/json-c/json-c/issues/276) - ./configure for centos release 6.7(final) failure \ +* [Issue #277](https://github.com/json-c/json-c/issues/277) - Json object set xxx \ +* [Issue #278](https://github.com/json-c/json-c/issues/278) - Serialization of double with no fractional component drops trailing zero \ +* [Issue #279](https://github.com/json-c/json-c/issues/279) - Segmentation fault in array_list_length() \ +* [Issue #280](https://github.com/json-c/json-c/issues/280) - Should json_object_array_get_idx check whether input obj is array? \ +* [Issue #281](https://github.com/json-c/json-c/issues/281) - how to pretty print json-c? \ +* [Issue #282](https://github.com/json-c/json-c/issues/282) - ignore temporary files \ +* [Issue #283](https://github.com/json-c/json-c/issues/283) - json_pointer: add first revision based on RFC 6901 \ +* [Issue #284](https://github.com/json-c/json-c/issues/284) - Resusing json_tokener object \ +* [Issue #285](https://github.com/json-c/json-c/issues/285) - Revert "compat/strdup.h: move common compat check for strdup() to own \ +* [Issue #286](https://github.com/json-c/json-c/issues/286) - json_tokener_parse_ex() returns json_tokener_continue on zero-length string \ +* [Issue #287](https://github.com/json-c/json-c/issues/287) - json_pointer: extend setter & getter with printf() style arguments \ +* [Issue #288](https://github.com/json-c/json-c/issues/288) - Fix _GNU_SOURCE define for vasprintf \ +* [Issue #289](https://github.com/json-c/json-c/issues/289) - bugfix: floating point representaion without fractional part \ +* [Issue #290](https://github.com/json-c/json-c/issues/290) - duplicate an json_object \ +* [Issue #291](https://github.com/json-c/json-c/issues/291) - isspace assert error \ +* [Issue #292](https://github.com/json-c/json-c/issues/292) - configure error "./configure: line 13121: syntax error near unexpected token `-Wall'" \ +* [Issue #293](https://github.com/json-c/json-c/issues/293) - how to make with bitcode for ios \ +* [Issue #294](https://github.com/json-c/json-c/issues/294) - Adding UTF-8 validation. Fixes #122 \ +* [Issue #295](https://github.com/json-c/json-c/issues/295) - cross compile w/ mingw \ +* [Issue #296](https://github.com/json-c/json-c/issues/296) - Missing functions header in json_object.h \ +* [Issue #297](https://github.com/json-c/json-c/issues/297) - could not parse string to Json object? Like string str=\"helloworld;E\\test\\log\\;end\" \ +* [Issue #298](https://github.com/json-c/json-c/issues/298) - Building using CMake doesn't work \ +* [Issue #299](https://github.com/json-c/json-c/issues/299) - Improve json_object -> string performance \ +* [Issue #300](https://github.com/json-c/json-c/issues/300) - Running tests with MinGW build \ +* [Issue #301](https://github.com/json-c/json-c/issues/301) - How to deep copy json_object in C++ ? \ +* [Issue #302](https://github.com/json-c/json-c/issues/302) - json_tokener_parse_ex doesn't parse JSON values \ +* [Issue #303](https://github.com/json-c/json-c/issues/303) - fix doc in tokener header file \ +* [Issue #304](https://github.com/json-c/json-c/issues/304) - (.text+0x72846): undefined reference to `is_error' \ +* [Issue #305](https://github.com/json-c/json-c/issues/305) - Fix compilation without C-99 option \ +* [Issue #306](https://github.com/json-c/json-c/issues/306) - ./configure: line 12748 -error=deprecated-declarations \ +* [Issue #307](https://github.com/json-c/json-c/issues/307) - Memory leak in json_tokener_parse \ +* [Issue #308](https://github.com/json-c/json-c/issues/308) - AM_PROG_LIBTOOL not found on Linux \ +* [Issue #309](https://github.com/json-c/json-c/issues/309) - GCC 7 reports various -Wimplicit-fallthrough= errors \ +* [Issue #310](https://github.com/json-c/json-c/issues/310) - Add FALLTHRU comment to handle GCC7 warnings. \ +* [Issue #311](https://github.com/json-c/json-c/issues/311) - Fix error C3688 when compiling on Visual Studio 2015 \ +* [Issue #312](https://github.com/json-c/json-c/issues/312) - Fix CMake Build process improved for MinGW and MSYS2 \ +* [Issue #313](https://github.com/json-c/json-c/issues/313) - VERBOSE=1 make check; tests/test_util_file.test.c and tests/test_util_file.expected out of sync \ +* [Issue #315](https://github.com/json-c/json-c/issues/315) - Passing -1 to json_tokener_parse_ex is possibly unsafe \ +* [Issue #316](https://github.com/json-c/json-c/issues/316) - Memory Returned by json_object_to_json_string not freed \ +* [Issue #317](https://github.com/json-c/json-c/issues/317) - json_object_get_string gives segmentation error \ +* [Issue #318](https://github.com/json-c/json-c/issues/318) - PVS-Studio static analyzer analyze results \ +* [Issue #319](https://github.com/json-c/json-c/issues/319) - Windows: Fix dynamic library build with Visual Studio \ +* [Issue #320](https://github.com/json-c/json-c/issues/320) - Can't compile in Mac OS X El Capitan \ +* [Issue #321](https://github.com/json-c/json-c/issues/321) - build,cmake: fix vasprintf implicit definition and generate both static & shared libs \ +* [Issue #322](https://github.com/json-c/json-c/issues/322) - can not link with libjson-c.a \ +* [Issue #323](https://github.com/json-c/json-c/issues/323) - implicit fallthrough detected by gcc 7.1 \ +* [Issue #324](https://github.com/json-c/json-c/issues/324) - JsonPath like function? \ +* [Issue #325](https://github.com/json-c/json-c/issues/325) - Fix stack buffer overflow in json_object_double_to_json_string_format() \ +* [Issue #327](https://github.com/json-c/json-c/issues/327) - why json-c so hard to compile \ +* [Issue #328](https://github.com/json-c/json-c/issues/328) - json_object: implement json_object_deep_copy() function \ +* [Issue #329](https://github.com/json-c/json-c/issues/329) - build,cmake: build,cmake: rename libjson-c-static.a to libjson-c.a \ +* [Issue #330](https://github.com/json-c/json-c/issues/330) - tests: symlink basic tests to a single file that has the common code \ +* [Issue #331](https://github.com/json-c/json-c/issues/331) - Safe use of snprintf() / vsnprintf() for Visual studio, and thread-safety fix \ +* [Issue #332](https://github.com/json-c/json-c/issues/332) - Valgrind: invalid read after json_object_array_del_idx. \ +* [Issue #333](https://github.com/json-c/json-c/issues/333) - Replace obsolete AM_PROG_LIBTOOL \ +* [Issue #335](https://github.com/json-c/json-c/issues/335) - README.md: show build status tag from travis-ci.org \ +* [Issue #336](https://github.com/json-c/json-c/issues/336) - tests: fix tests in travis-ci.org \ +* [Issue #337](https://github.com/json-c/json-c/issues/337) - Synchronize "potentially racy" random seed in lh_char_hash() \ +* [Issue #338](https://github.com/json-c/json-c/issues/338) - implement json_object_int_inc(json_object *, int64_t) \ +* [Issue #339](https://github.com/json-c/json-c/issues/339) - Json schema validation \ +* [Issue #340](https://github.com/json-c/json-c/issues/340) - strerror_override: add extern "C" and JSON_EXPORT specifiers for Visual C++ compilers \ +* [Issue #341](https://github.com/json-c/json-c/issues/341) - character "/" parse as "\/" \ +* [Issue #342](https://github.com/json-c/json-c/issues/342) - No such file or directory "/usr/include/json.h" \ +* [Issue #343](https://github.com/json-c/json-c/issues/343) - Can't parse json \ +* [Issue #344](https://github.com/json-c/json-c/issues/344) - Fix Mingw build \ +* [Issue #345](https://github.com/json-c/json-c/issues/345) - Fix make dist and make distcheck \ +* [Issue #346](https://github.com/json-c/json-c/issues/346) - Clamp double to int32 when narrowing in json_object_get_int. \ +* [Issue #347](https://github.com/json-c/json-c/issues/347) - MSVC linker error json_c_strerror \ +* [Issue #348](https://github.com/json-c/json-c/issues/348) - why \ +* [Issue #349](https://github.com/json-c/json-c/issues/349) - `missing` is missing? \ +* [Issue #350](https://github.com/json-c/json-c/issues/350) - stderror-override and disable-shared \ +* [Issue #351](https://github.com/json-c/json-c/issues/351) - SIZE_T_MAX redefined from limits.h \ +* [Issue #352](https://github.com/json-c/json-c/issues/352) - `INSTALL` overrides an automake script. \ +* [Issue #353](https://github.com/json-c/json-c/issues/353) - Documentation issues \ +* [Issue #354](https://github.com/json-c/json-c/issues/354) - Fixes #351 #352 #353 \ +* [Issue #355](https://github.com/json-c/json-c/issues/355) - 1.make it can been compiled with Visual Studio 2010 by modify the CMakeList.txt and others \ +* [Issue #356](https://github.com/json-c/json-c/issues/356) - VS2008 test test_util_file.cpp err! \ +* [Issue #357](https://github.com/json-c/json-c/issues/357) - __json_c_strerror incompatibility with link-time optimization \ +* [Issue #358](https://github.com/json-c/json-c/issues/358) - make issue \ +* [Issue #359](https://github.com/json-c/json-c/issues/359) - update CMakeLists.txt for compile with visual studio at least 2010 \ +* [Issue #360](https://github.com/json-c/json-c/issues/360) - Use strtoll() to parse ints \ +* [Issue #361](https://github.com/json-c/json-c/issues/361) - Fix double to int cast overflow in json_object_get_int64. \ +* [Issue #362](https://github.com/json-c/json-c/issues/362) - CMake Package Config \ +* [Issue #363](https://github.com/json-c/json-c/issues/363) - Issue #338, add json_object_add_int functions \ +* [Issue #364](https://github.com/json-c/json-c/issues/364) - Cmake is Errir \ +* [Issue #365](https://github.com/json-c/json-c/issues/365) - added fallthrough for gcc7 \ +* [Issue #366](https://github.com/json-c/json-c/issues/366) - how to check the json string,crash! \ +* [Issue #367](https://github.com/json-c/json-c/issues/367) - Is json-c support "redirect" semantic? \ +* [Issue #368](https://github.com/json-c/json-c/issues/368) - Add examples \ +* [Issue #369](https://github.com/json-c/json-c/issues/369) - How to build json-c library for android? \ +* [Issue #370](https://github.com/json-c/json-c/issues/370) - Compiling using clang-cl \ +* [Issue #371](https://github.com/json-c/json-c/issues/371) - Invalid parsing for Infinity with json-c 0.12 \ +* [Issue #372](https://github.com/json-c/json-c/issues/372) - Json-c 0.12: Fixed Infinity bug \ +* [Issue #373](https://github.com/json-c/json-c/issues/373) - build: fix build on appveyor CI \ +* [Issue #374](https://github.com/json-c/json-c/issues/374) - Undefined symbols for architecture x86_64: \ +* [Issue #375](https://github.com/json-c/json-c/issues/375) - what would happened when json_object_object_add add the same key \ +* [Issue #376](https://github.com/json-c/json-c/issues/376) - Eclipse error \ +* [Issue #377](https://github.com/json-c/json-c/issues/377) - on gcc 7.2.0 on my linux distribution with json-c 2013-04-02 source \ +* [Issue #378](https://github.com/json-c/json-c/issues/378) - Eclipse: library (libjson-c) not found, but configured \ +* [Issue #379](https://github.com/json-c/json-c/issues/379) - error: this statement may fall through \[-Werror=implicit-fallthrough=\] \ +* [Issue #380](https://github.com/json-c/json-c/issues/380) - Build on Windows \ +* [Issue #381](https://github.com/json-c/json-c/issues/381) - Fix makedist \ +* [Issue #382](https://github.com/json-c/json-c/issues/382) - Memory leak for json_tokener_parse_ex for version 0.12.1 \ +* [Issue #383](https://github.com/json-c/json-c/issues/383) - Fix a compiler warning. \ +* [Issue #384](https://github.com/json-c/json-c/issues/384) - Fix a VS 2015 compiler warnings. \ diff --git a/issues_closed_for_0.14.md b/issues_closed_for_0.14.md index bca934a..65096f0 100644 --- a/issues_closed_for_0.14.md +++ b/issues_closed_for_0.14.md @@ -14,189 +14,189 @@ sed -e's,^\[ *\(.*\)\](https://api.github.com/.*/\([0-9].*\)),[Issue #\2](https: Issues and Pull Requests closed for the 0.14 release (since commit d582d3a(2017-12-07) to a911439(2020-04-17)) -[Issue #122](https://github.com/json-c/json-c/issues/122) - Add utf-8 validation when parsing strings. \ -[Issue #139](https://github.com/json-c/json-c/issues/139) - json_object_from_file cannot accept max_depth \ -[Issue #143](https://github.com/json-c/json-c/issues/143) - RFE / enhancement for full 64-bit signed/unsigned support \ -[Issue #147](https://github.com/json-c/json-c/issues/147) - Please introduce soname bump if API changed \ -[Issue #166](https://github.com/json-c/json-c/issues/166) - Need a way to specify nesting depth when opening JSON file \ -[Issue #226](https://github.com/json-c/json-c/issues/226) - There is no json_object_new_null() \ -[Issue #314](https://github.com/json-c/json-c/issues/314) - new release ? \ -[Issue #326](https://github.com/json-c/json-c/issues/326) - Please extend api json_object_get_uint64 \ -[Issue #334](https://github.com/json-c/json-c/issues/334) - Switch json-c builds to use CMake \ -[Issue #386](https://github.com/json-c/json-c/issues/386) - Makefile: Add ACLOCAL_AMFLAGS \ -[Issue #387](https://github.com/json-c/json-c/issues/387) - doc: Use other doxygen feature to specify mainpage \ -[Issue #388](https://github.com/json-c/json-c/issues/388) - json_object: Add size_t json_object_sizeof() \ -[Issue #389](https://github.com/json-c/json-c/issues/389) - json_object: Avoid double free (and thus a segfault) when ref_count gets < 0 \ -[Issue #390](https://github.com/json-c/json-c/issues/390) - json_object: Add const size_t json_c_object_sizeof() \ -[Issue #391](https://github.com/json-c/json-c/issues/391) - Fix non-GNUC define for JSON_C_CONST_FUNCTION \ -[Issue #392](https://github.com/json-c/json-c/issues/392) - json_object: Avoid invalid free (and thus a segfault) when ref_count gets < 0 \ -[Issue #393](https://github.com/json-c/json-c/issues/393) - json_object_private: Use unsigned 32-bit integer type for refcount \ -[Issue #394](https://github.com/json-c/json-c/issues/394) - Problem serializing double \ -[Issue #395](https://github.com/json-c/json-c/issues/395) - Key gets modified if it contains "\" \ -[Issue #396](https://github.com/json-c/json-c/issues/396) - Build failure with no threads uClibc toolchain \ -[Issue #397](https://github.com/json-c/json-c/issues/397) - update json object with key. \ -[Issue #398](https://github.com/json-c/json-c/issues/398) - Build failed. \ -[Issue #399](https://github.com/json-c/json-c/issues/399) - Avoid uninitialized variable warnings \ -[Issue #400](https://github.com/json-c/json-c/issues/400) - How to generate static lib (.a) \ -[Issue #401](https://github.com/json-c/json-c/issues/401) - Warnings with Valgrind \ -[Issue #402](https://github.com/json-c/json-c/issues/402) - Add fuzzers from OSS-Fuzz \ -[Issue #403](https://github.com/json-c/json-c/issues/403) - Segmentation fault when double quotes is used \ -[Issue #404](https://github.com/json-c/json-c/issues/404) - valgrind: memory leak \ -[Issue #405](https://github.com/json-c/json-c/issues/405) - Missing API to determine an object is empty \ -[Issue #406](https://github.com/json-c/json-c/issues/406) - Undefine NDEBUG for tests \ -[Issue #407](https://github.com/json-c/json-c/issues/407) - json_tokener_parse is crash \ -[Issue #408](https://github.com/json-c/json-c/issues/408) - bug in array_list_del_idx when array_list_length()==1 \ -[Issue #410](https://github.com/json-c/json-c/issues/410) - Fixed typos \ -[Issue #411](https://github.com/json-c/json-c/issues/411) - Crash- signal SIGSEGV, Segmentation fault. ../sysdeps/x86_64/strlen.S: No such file or directory. \ -[Issue #412](https://github.com/json-c/json-c/issues/412) - json_type changes during inter process communication. \ -[Issue #413](https://github.com/json-c/json-c/issues/413) - how to read object of type `json_object *` in c++ \ -[Issue #414](https://github.com/json-c/json-c/issues/414) - [Question] How JSON-c stores the serialized data in memory? \ -[Issue #415](https://github.com/json-c/json-c/issues/415) - Resolve windows name conflict \ -[Issue #416](https://github.com/json-c/json-c/issues/416) - segmentation fault in json_tokener_parse \ -[Issue #417](https://github.com/json-c/json-c/issues/417) - json_tokener_parse json_object_object_get_ex with string value which is json string \ -[Issue #418](https://github.com/json-c/json-c/issues/418) - json_object_from_* return value documented incorrectly \ -[Issue #419](https://github.com/json-c/json-c/issues/419) - Suggestion: document (and define) that json_object_put() accepts NULL pointer to object \ -[Issue #420](https://github.com/json-c/json-c/issues/420) - arraylist: Fixed names of parameters for callback function \ -[Issue #421](https://github.com/json-c/json-c/issues/421) - install json_object_iterator.h header file \ -[Issue #422](https://github.com/json-c/json-c/issues/422) - json_object_get_double() does not set errno when there is no valid conversion \ -[Issue #423](https://github.com/json-c/json-c/issues/423) - memory leak \ -[Issue #424](https://github.com/json-c/json-c/issues/424) - Parse string contains "\" or "/" errors \ -[Issue #425](https://github.com/json-c/json-c/issues/425) - what this is? \ -[Issue #426](https://github.com/json-c/json-c/issues/426) - __deprecated not supported on clang. \ -[Issue #427](https://github.com/json-c/json-c/issues/427) - CMake: builds involving this target will not be correct \ -[Issue #430](https://github.com/json-c/json-c/issues/430) - json_object_object_del() and Segmentation fault \ -[Issue #431](https://github.com/json-c/json-c/issues/431) - cmake: Bump required version \ -[Issue #432](https://github.com/json-c/json-c/issues/432) - The real CMake support. \ -[Issue #433](https://github.com/json-c/json-c/issues/433) - The real CMake support. \ -[Issue #434](https://github.com/json-c/json-c/issues/434) - The real CMake support \ -[Issue #435](https://github.com/json-c/json-c/issues/435) - json_object_object_del() segmentation fault \ -[Issue #436](https://github.com/json-c/json-c/issues/436) - Improve pkgconfig setting \ -[Issue #437](https://github.com/json-c/json-c/issues/437) - Bad link in README.md \ -[Issue #438](https://github.com/json-c/json-c/issues/438) - Bad link in README.html \ -[Issue #439](https://github.com/json-c/json-c/issues/439) - reserved identifier violation \ -[Issue #440](https://github.com/json-c/json-c/issues/440) - Use of angle brackets around file names for include statements \ -[Issue #441](https://github.com/json-c/json-c/issues/441) - fix c flag loss during cmake building \ -[Issue #442](https://github.com/json-c/json-c/issues/442) - error in configure file \ -[Issue #443](https://github.com/json-c/json-c/issues/443) - remove pretty spaces when using pretty tabs \ -[Issue #444](https://github.com/json-c/json-c/issues/444) - Document refcount of json_tokener_parse_ex return \ -[Issue #445](https://github.com/json-c/json-c/issues/445) - Add missing "make check" target to cmake config \ -[Issue #446](https://github.com/json-c/json-c/issues/446) - Forward slashes get escaped \ -[Issue #448](https://github.com/json-c/json-c/issues/448) - Buffer overflow in json-c \ -[Issue #449](https://github.com/json-c/json-c/issues/449) - Need of json_type_int64 returned by json_object_get_type() \ -[Issue #450](https://github.com/json-c/json-c/issues/450) - Allow use json-c cmake as subproject \ -[Issue #452](https://github.com/json-c/json-c/issues/452) - Update README.md \ -[Issue #453](https://github.com/json-c/json-c/issues/453) - Fixed misalignment in JSON string due to space after \n being printed... \ -[Issue #454](https://github.com/json-c/json-c/issues/454) - json_object_private: save 8 bytes in struct json_object in 64-bit arc… \ -[Issue #455](https://github.com/json-c/json-c/issues/455) - index.html:fix dead link \ -[Issue #456](https://github.com/json-c/json-c/issues/456) - STYLE.txt:remove executable permissions \ -[Issue #457](https://github.com/json-c/json-c/issues/457) - .gitignore:add build directory \ -[Issue #458](https://github.com/json-c/json-c/issues/458) - README.md:fix dead "file.html" link \ -[Issue #459](https://github.com/json-c/json-c/issues/459) - README.html:fix link to Doxygen docs, remove WIN32 link \ -[Issue #460](https://github.com/json-c/json-c/issues/460) - No docs for json_object_new_string_len() \ -[Issue #461](https://github.com/json-c/json-c/issues/461) - json_object.c:set errno in json_object_get_double() \ -[Issue #462](https://github.com/json-c/json-c/issues/462) - json_object.h:document json_object_new_string_len() \ -[Issue #463](https://github.com/json-c/json-c/issues/463) - please check newlocale api first argument valuse. \ -[Issue #465](https://github.com/json-c/json-c/issues/465) - CMakeLists.txt doesn't contain json_object_iterator.h which json.h includes \ -[Issue #466](https://github.com/json-c/json-c/issues/466) - configure:3610: error: C compiler cannot create executables \ -[Issue #467](https://github.com/json-c/json-c/issues/467) - Fix compiler warnings \ -[Issue #468](https://github.com/json-c/json-c/issues/468) - Fix compiler warnings \ -[Issue #469](https://github.com/json-c/json-c/issues/469) - Build under alpine with pecl install & docker-php-ext-enable? \ -[Issue #470](https://github.com/json-c/json-c/issues/470) - cfuhash_foreach_remove doesn't upate cfuhash_num_entries \ -[Issue #472](https://github.com/json-c/json-c/issues/472) - Segmentation fault in json_object_iter_begin \ -[Issue #473](https://github.com/json-c/json-c/issues/473) - Convert ChangeLog to valid UTF-8 encoding. \ -[Issue #474](https://github.com/json-c/json-c/issues/474) - Installation directories empty with CMake in pkg-config. \ -[Issue #475](https://github.com/json-c/json-c/issues/475) - improvement proposal for json_object_object_foreach \ -[Issue #477](https://github.com/json-c/json-c/issues/477) - Hang/Crash with large strings \ -[Issue #478](https://github.com/json-c/json-c/issues/478) - json_object_get_string_len returns 0 when value is number \ -[Issue #479](https://github.com/json-c/json-c/issues/479) - I want to use it in iOS or Android but I can't compile \ -[Issue #480](https://github.com/json-c/json-c/issues/480) - json-c-0.12.1 failed making from source code \ -[Issue #481](https://github.com/json-c/json-c/issues/481) - error while loading shared libraries: libjson-c.so.4 \ -[Issue #482](https://github.com/json-c/json-c/issues/482) - Error "double free or corruption" after free() \ -[Issue #483](https://github.com/json-c/json-c/issues/483) - compatible with rarely-used Chinese characters in GBK charset \ -[Issue #485](https://github.com/json-c/json-c/issues/485) - Install CMake module files \ -[Issue #486](https://github.com/json-c/json-c/issues/486) - In the case of negative double value, it is formatted without including ".0" \ -[Issue #488](https://github.com/json-c/json-c/issues/488) - Some APIs are not exported when built as shared lib on Win32 \ -[Issue #489](https://github.com/json-c/json-c/issues/489) - Don't use -Werror by default \ -[Issue #490](https://github.com/json-c/json-c/issues/490) - do not compile with -Werror by default \ -[Issue #491](https://github.com/json-c/json-c/issues/491) - build: add option --disable-werror to configure \ -[Issue #492](https://github.com/json-c/json-c/issues/492) - lack some quick usage in readme \ -[Issue #494](https://github.com/json-c/json-c/issues/494) - Code generator? \ -[Issue #495](https://github.com/json-c/json-c/issues/495) - README.md:fix 2 typos \ -[Issue #496](https://github.com/json-c/json-c/issues/496) - json_pointer.h:suggest minor grammar improvement for pointer doc \ -[Issue #497](https://github.com/json-c/json-c/issues/497) - add common header for all tests \ -[Issue #498](https://github.com/json-c/json-c/issues/498) - double_serializer_test fails (with valgrind) \ -[Issue #499](https://github.com/json-c/json-c/issues/499) - .travis.yml:test on more recent clang and gcc versions \ -[Issue #500](https://github.com/json-c/json-c/issues/500) - test/Makefile.am:add missing deps for test1 and test2 \ -[Issue #501](https://github.com/json-c/json-c/issues/501) - undefine NDEBUG for tests \ -[Issue #502](https://github.com/json-c/json-c/issues/502) - configure error \ -[Issue #503](https://github.com/json-c/json-c/issues/503) - json-c retuns OK when Invalid json string is passed \ -[Issue #504](https://github.com/json-c/json-c/issues/504) - json_object_put coredump \ -[Issue #505](https://github.com/json-c/json-c/issues/505) - Add vcpkg installation instructions \ -[Issue #506](https://github.com/json-c/json-c/issues/506) - Cannot parse more than one object \ -[Issue #509](https://github.com/json-c/json-c/issues/509) - Sometimes a double value is not serialized \ -[Issue #510](https://github.com/json-c/json-c/issues/510) - Bump so-name and improve CMake \ -[Issue #511](https://github.com/json-c/json-c/issues/511) - Reduce lines for better optimization \ -[Issue #512](https://github.com/json-c/json-c/issues/512) - Properly append to CMAKE_C_FLAGS string \ -[Issue #513](https://github.com/json-c/json-c/issues/513) - What does `userdata` means?And what is the case we can use it? \ -[Issue #514](https://github.com/json-c/json-c/issues/514) - Json c 0.13 \ -[Issue #515](https://github.com/json-c/json-c/issues/515) - Mies suomesta fixes segfaults and logic errors \ -[Issue #516](https://github.com/json-c/json-c/issues/516) - Lja slight mods \ -[Issue #518](https://github.com/json-c/json-c/issues/518) - Escape character "\\003\", get unexpected value \ -[Issue #519](https://github.com/json-c/json-c/issues/519) - Add test case obj token \ -[Issue #520](https://github.com/json-c/json-c/issues/520) - Adding type uint64 \ -[Issue #521](https://github.com/json-c/json-c/issues/521) - build cmake windows 10 \ -[Issue #522](https://github.com/json-c/json-c/issues/522) - update json_visit testcase \ -[Issue #523](https://github.com/json-c/json-c/issues/523) - update tsetcase for tokener_c \ -[Issue #524](https://github.com/json-c/json-c/issues/524) - Increase coverage \ -[Issue #525](https://github.com/json-c/json-c/issues/525) - update pointer test case \ -[Issue #526](https://github.com/json-c/json-c/issues/526) - Increased the test coverage of printbuf.c 82% to 92%. \ -[Issue #527](https://github.com/json-c/json-c/issues/527) - Arraylist testcase \ -[Issue #528](https://github.com/json-c/json-c/issues/528) - Solve issue #108. Skip \u0000 while parsing. \ -[Issue #529](https://github.com/json-c/json-c/issues/529) - Increased the test coverage of json_c_version.c 0% to 100%. \ -[Issue #530](https://github.com/json-c/json-c/issues/530) - validate utf-8 string before parse \ -[Issue #531](https://github.com/json-c/json-c/issues/531) - validate utf-8 string \ -[Issue #532](https://github.com/json-c/json-c/issues/532) - json_object_object_get_ex returning the original object \ -[Issue #533](https://github.com/json-c/json-c/issues/533) - Fix "make check" \ -[Issue #535](https://github.com/json-c/json-c/issues/535) - short string optimization: excessive array length \ -[Issue #536](https://github.com/json-c/json-c/issues/536) - add json_object_new_null() \ -[Issue #538](https://github.com/json-c/json-c/issues/538) - update shortstring and arraylist parameters \ -[Issue #539](https://github.com/json-c/json-c/issues/539) - double serializes to the old value after set_double \ -[Issue #541](https://github.com/json-c/json-c/issues/541) - add coveralls auto tool to json-c \ -[Issue #542](https://github.com/json-c/json-c/issues/542) - add uint64 data to json-c \ -[Issue #543](https://github.com/json-c/json-c/issues/543) - Readme \ -[Issue #544](https://github.com/json-c/json-c/issues/544) - Increase distcheck target in cmake \ -[Issue #545](https://github.com/json-c/json-c/issues/545) - add doc target in cmake \ -[Issue #546](https://github.com/json-c/json-c/issues/546) - Add uninstall target in cmake \ -[Issue #547](https://github.com/json-c/json-c/issues/547) - modify json-c default build type, and fix up the assert() errors in t… \ -[Issue #548](https://github.com/json-c/json-c/issues/548) - Solve some problems about cmake build type (debug/release) \ -[Issue #549](https://github.com/json-c/json-c/issues/549) - lib installation issues \ -[Issue #550](https://github.com/json-c/json-c/issues/550) - Format codes with clang-format tool? \ -[Issue #551](https://github.com/json-c/json-c/issues/551) - Allow hexadecimal number format convention parsing \ -[Issue #553](https://github.com/json-c/json-c/issues/553) - Fix/clang ubsan \ -[Issue #554](https://github.com/json-c/json-c/issues/554) - RFC 8259 compatibility mode \ -[Issue #555](https://github.com/json-c/json-c/issues/555) - Format json-c with clang-format tool \ -[Issue #556](https://github.com/json-c/json-c/issues/556) - Fixes various Wreturn-type and Wimplicit-fallthrough errors on Mingw-w64 \ -[Issue #557](https://github.com/json-c/json-c/issues/557) - Add option in CMAKE to not build documentation \ -[Issue #558](https://github.com/json-c/json-c/issues/558) - modify the doc target message \ -[Issue #559](https://github.com/json-c/json-c/issues/559) - json_c_visit() not exported on Windows \ -[Issue #560](https://github.com/json-c/json-c/issues/560) - error: implicit declaration of function '_strtoi64' \ -[Issue #561](https://github.com/json-c/json-c/issues/561) - add the badge in README.md and test the coveralls \ -[Issue #562](https://github.com/json-c/json-c/issues/562) - Bugfix and testcases supplements \ -[Issue #563](https://github.com/json-c/json-c/issues/563) - Changed order of calloc args to match stdlib \ -[Issue #564](https://github.com/json-c/json-c/issues/564) - Remove autogenerated files \ -[Issue #565](https://github.com/json-c/json-c/issues/565) - test the CI and ignore this PR \ -[Issue #566](https://github.com/json-c/json-c/issues/566) - add the json_types.h to Makefile.am \ -[Issue #567](https://github.com/json-c/json-c/issues/567) - Install json_types.h with autotools build as well. \ -[Issue #568](https://github.com/json-c/json-c/issues/568) - Adding better support to MinGW \ -[Issue #569](https://github.com/json-c/json-c/issues/569) - Handling of -Bsymbolic-function in CMakeLists.txt is deficient \ -[Issue #571](https://github.com/json-c/json-c/issues/571) - CMake: Bump SONAME to 5. \ -[Issue #572](https://github.com/json-c/json-c/issues/572) - Small fixes to CMakeLists \ -[Issue #573](https://github.com/json-c/json-c/issues/573) - Fix coveralls submission. \ -[Issue #574](https://github.com/json-c/json-c/issues/574) - autogen.sh missing from repository \ -[Issue #575](https://github.com/json-c/json-c/issues/575) - Small cosmetics. \ -[Issue #576](https://github.com/json-c/json-c/issues/576) - Test coverage for json_c_version. \ -[Issue #577](https://github.com/json-c/json-c/issues/577) - Be verbose on failing json_c_version test. \ -[Issue #578](https://github.com/json-c/json-c/issues/578) - CMake: Install pkgconfig file in proper location by default \ -[Issue #579](https://github.com/json-c/json-c/issues/579) - Enforce strict prototypes. \ -[Issue #580](https://github.com/json-c/json-c/issues/580) - Fix CMake tests for enforced strict prototypes. \ -[Issue #581](https://github.com/json-c/json-c/issues/581) - CMakeLists: do not enforce strict prototypes on Windows. \ +* [Issue #122](https://github.com/json-c/json-c/issues/122) - Add utf-8 validation when parsing strings. \ +* [Issue #139](https://github.com/json-c/json-c/issues/139) - json_object_from_file cannot accept max_depth \ +* [Issue #143](https://github.com/json-c/json-c/issues/143) - RFE / enhancement for full 64-bit signed/unsigned support \ +* [Issue #147](https://github.com/json-c/json-c/issues/147) - Please introduce soname bump if API changed \ +* [Issue #166](https://github.com/json-c/json-c/issues/166) - Need a way to specify nesting depth when opening JSON file \ +* [Issue #226](https://github.com/json-c/json-c/issues/226) - There is no json_object_new_null() \ +* [Issue #314](https://github.com/json-c/json-c/issues/314) - new release ? \ +* [Issue #326](https://github.com/json-c/json-c/issues/326) - Please extend api json_object_get_uint64 \ +* [Issue #334](https://github.com/json-c/json-c/issues/334) - Switch json-c builds to use CMake \ +* [Issue #386](https://github.com/json-c/json-c/issues/386) - Makefile: Add ACLOCAL_AMFLAGS \ +* [Issue #387](https://github.com/json-c/json-c/issues/387) - doc: Use other doxygen feature to specify mainpage \ +* [Issue #388](https://github.com/json-c/json-c/issues/388) - json_object: Add size_t json_object_sizeof() \ +* [Issue #389](https://github.com/json-c/json-c/issues/389) - json_object: Avoid double free (and thus a segfault) when ref_count gets < 0 \ +* [Issue #390](https://github.com/json-c/json-c/issues/390) - json_object: Add const size_t json_c_object_sizeof() \ +* [Issue #391](https://github.com/json-c/json-c/issues/391) - Fix non-GNUC define for JSON_C_CONST_FUNCTION \ +* [Issue #392](https://github.com/json-c/json-c/issues/392) - json_object: Avoid invalid free (and thus a segfault) when ref_count gets < 0 \ +* [Issue #393](https://github.com/json-c/json-c/issues/393) - json_object_private: Use unsigned 32-bit integer type for refcount \ +* [Issue #394](https://github.com/json-c/json-c/issues/394) - Problem serializing double \ +* [Issue #395](https://github.com/json-c/json-c/issues/395) - Key gets modified if it contains "\" \ +* [Issue #396](https://github.com/json-c/json-c/issues/396) - Build failure with no threads uClibc toolchain \ +* [Issue #397](https://github.com/json-c/json-c/issues/397) - update json object with key. \ +* [Issue #398](https://github.com/json-c/json-c/issues/398) - Build failed. \ +* [Issue #399](https://github.com/json-c/json-c/issues/399) - Avoid uninitialized variable warnings \ +* [Issue #400](https://github.com/json-c/json-c/issues/400) - How to generate static lib (.a) \ +* [Issue #401](https://github.com/json-c/json-c/issues/401) - Warnings with Valgrind \ +* [Issue #402](https://github.com/json-c/json-c/issues/402) - Add fuzzers from OSS-Fuzz \ +* [Issue #403](https://github.com/json-c/json-c/issues/403) - Segmentation fault when double quotes is used \ +* [Issue #404](https://github.com/json-c/json-c/issues/404) - valgrind: memory leak \ +* [Issue #405](https://github.com/json-c/json-c/issues/405) - Missing API to determine an object is empty \ +* [Issue #406](https://github.com/json-c/json-c/issues/406) - Undefine NDEBUG for tests \ +* [Issue #407](https://github.com/json-c/json-c/issues/407) - json_tokener_parse is crash \ +* [Issue #408](https://github.com/json-c/json-c/issues/408) - bug in array_list_del_idx when array_list_length()==1 \ +* [Issue #410](https://github.com/json-c/json-c/issues/410) - Fixed typos \ +* [Issue #411](https://github.com/json-c/json-c/issues/411) - Crash- signal SIGSEGV, Segmentation fault. ../sysdeps/x86_64/strlen.S: No such file or directory. \ +* [Issue #412](https://github.com/json-c/json-c/issues/412) - json_type changes during inter process communication. \ +* [Issue #413](https://github.com/json-c/json-c/issues/413) - how to read object of type `json_object *` in c++ \ +* [Issue #414](https://github.com/json-c/json-c/issues/414) - [Question] How JSON-c stores the serialized data in memory? \ +* [Issue #415](https://github.com/json-c/json-c/issues/415) - Resolve windows name conflict \ +* [Issue #416](https://github.com/json-c/json-c/issues/416) - segmentation fault in json_tokener_parse \ +* [Issue #417](https://github.com/json-c/json-c/issues/417) - json_tokener_parse json_object_object_get_ex with string value which is json string \ +* [Issue #418](https://github.com/json-c/json-c/issues/418) - json_object_from_* return value documented incorrectly \ +* [Issue #419](https://github.com/json-c/json-c/issues/419) - Suggestion: document (and define) that json_object_put() accepts NULL pointer to object \ +* [Issue #420](https://github.com/json-c/json-c/issues/420) - arraylist: Fixed names of parameters for callback function \ +* [Issue #421](https://github.com/json-c/json-c/issues/421) - install json_object_iterator.h header file \ +* [Issue #422](https://github.com/json-c/json-c/issues/422) - json_object_get_double() does not set errno when there is no valid conversion \ +* [Issue #423](https://github.com/json-c/json-c/issues/423) - memory leak \ +* [Issue #424](https://github.com/json-c/json-c/issues/424) - Parse string contains "\" or "/" errors \ +* [Issue #425](https://github.com/json-c/json-c/issues/425) - what this is? \ +* [Issue #426](https://github.com/json-c/json-c/issues/426) - __deprecated not supported on clang. \ +* [Issue #427](https://github.com/json-c/json-c/issues/427) - CMake: builds involving this target will not be correct \ +* [Issue #430](https://github.com/json-c/json-c/issues/430) - json_object_object_del() and Segmentation fault \ +* [Issue #431](https://github.com/json-c/json-c/issues/431) - cmake: Bump required version \ +* [Issue #432](https://github.com/json-c/json-c/issues/432) - The real CMake support. \ +* [Issue #433](https://github.com/json-c/json-c/issues/433) - The real CMake support. \ +* [Issue #434](https://github.com/json-c/json-c/issues/434) - The real CMake support \ +* [Issue #435](https://github.com/json-c/json-c/issues/435) - json_object_object_del() segmentation fault \ +* [Issue #436](https://github.com/json-c/json-c/issues/436) - Improve pkgconfig setting \ +* [Issue #437](https://github.com/json-c/json-c/issues/437) - Bad link in README.md \ +* [Issue #438](https://github.com/json-c/json-c/issues/438) - Bad link in README.html \ +* [Issue #439](https://github.com/json-c/json-c/issues/439) - reserved identifier violation \ +* [Issue #440](https://github.com/json-c/json-c/issues/440) - Use of angle brackets around file names for include statements \ +* [Issue #441](https://github.com/json-c/json-c/issues/441) - fix c flag loss during cmake building \ +* [Issue #442](https://github.com/json-c/json-c/issues/442) - error in configure file \ +* [Issue #443](https://github.com/json-c/json-c/issues/443) - remove pretty spaces when using pretty tabs \ +* [Issue #444](https://github.com/json-c/json-c/issues/444) - Document refcount of json_tokener_parse_ex return \ +* [Issue #445](https://github.com/json-c/json-c/issues/445) - Add missing "make check" target to cmake config \ +* [Issue #446](https://github.com/json-c/json-c/issues/446) - Forward slashes get escaped \ +* [Issue #448](https://github.com/json-c/json-c/issues/448) - Buffer overflow in json-c \ +* [Issue #449](https://github.com/json-c/json-c/issues/449) - Need of json_type_int64 returned by json_object_get_type() \ +* [Issue #450](https://github.com/json-c/json-c/issues/450) - Allow use json-c cmake as subproject \ +* [Issue #452](https://github.com/json-c/json-c/issues/452) - Update README.md \ +* [Issue #453](https://github.com/json-c/json-c/issues/453) - Fixed misalignment in JSON string due to space after \n being printed... \ +* [Issue #454](https://github.com/json-c/json-c/issues/454) - json_object_private: save 8 bytes in struct json_object in 64-bit arc… \ +* [Issue #455](https://github.com/json-c/json-c/issues/455) - index.html:fix dead link \ +* [Issue #456](https://github.com/json-c/json-c/issues/456) - STYLE.txt:remove executable permissions \ +* [Issue #457](https://github.com/json-c/json-c/issues/457) - .gitignore:add build directory \ +* [Issue #458](https://github.com/json-c/json-c/issues/458) - README.md:fix dead "file.html" link \ +* [Issue #459](https://github.com/json-c/json-c/issues/459) - README.html:fix link to Doxygen docs, remove WIN32 link \ +* [Issue #460](https://github.com/json-c/json-c/issues/460) - No docs for json_object_new_string_len() \ +* [Issue #461](https://github.com/json-c/json-c/issues/461) - json_object.c:set errno in json_object_get_double() \ +* [Issue #462](https://github.com/json-c/json-c/issues/462) - json_object.h:document json_object_new_string_len() \ +* [Issue #463](https://github.com/json-c/json-c/issues/463) - please check newlocale api first argument valuse. \ +* [Issue #465](https://github.com/json-c/json-c/issues/465) - CMakeLists.txt doesn't contain json_object_iterator.h which json.h includes \ +* [Issue #466](https://github.com/json-c/json-c/issues/466) - configure:3610: error: C compiler cannot create executables \ +* [Issue #467](https://github.com/json-c/json-c/issues/467) - Fix compiler warnings \ +* [Issue #468](https://github.com/json-c/json-c/issues/468) - Fix compiler warnings \ +* [Issue #469](https://github.com/json-c/json-c/issues/469) - Build under alpine with pecl install & docker-php-ext-enable? \ +* [Issue #470](https://github.com/json-c/json-c/issues/470) - cfuhash_foreach_remove doesn't upate cfuhash_num_entries \ +* [Issue #472](https://github.com/json-c/json-c/issues/472) - Segmentation fault in json_object_iter_begin \ +* [Issue #473](https://github.com/json-c/json-c/issues/473) - Convert ChangeLog to valid UTF-8 encoding. \ +* [Issue #474](https://github.com/json-c/json-c/issues/474) - Installation directories empty with CMake in pkg-config. \ +* [Issue #475](https://github.com/json-c/json-c/issues/475) - improvement proposal for json_object_object_foreach \ +* [Issue #477](https://github.com/json-c/json-c/issues/477) - Hang/Crash with large strings \ +* [Issue #478](https://github.com/json-c/json-c/issues/478) - json_object_get_string_len returns 0 when value is number \ +* [Issue #479](https://github.com/json-c/json-c/issues/479) - I want to use it in iOS or Android but I can't compile \ +* [Issue #480](https://github.com/json-c/json-c/issues/480) - json-c-0.12.1 failed making from source code \ +* [Issue #481](https://github.com/json-c/json-c/issues/481) - error while loading shared libraries: libjson-c.so.4 \ +* [Issue #482](https://github.com/json-c/json-c/issues/482) - Error "double free or corruption" after free() \ +* [Issue #483](https://github.com/json-c/json-c/issues/483) - compatible with rarely-used Chinese characters in GBK charset \ +* [Issue #485](https://github.com/json-c/json-c/issues/485) - Install CMake module files \ +* [Issue #486](https://github.com/json-c/json-c/issues/486) - In the case of negative double value, it is formatted without including ".0" \ +* [Issue #488](https://github.com/json-c/json-c/issues/488) - Some APIs are not exported when built as shared lib on Win32 \ +* [Issue #489](https://github.com/json-c/json-c/issues/489) - Don't use -Werror by default \ +* [Issue #490](https://github.com/json-c/json-c/issues/490) - do not compile with -Werror by default \ +* [Issue #491](https://github.com/json-c/json-c/issues/491) - build: add option --disable-werror to configure \ +* [Issue #492](https://github.com/json-c/json-c/issues/492) - lack some quick usage in readme \ +* [Issue #494](https://github.com/json-c/json-c/issues/494) - Code generator? \ +* [Issue #495](https://github.com/json-c/json-c/issues/495) - README.md:fix 2 typos \ +* [Issue #496](https://github.com/json-c/json-c/issues/496) - json_pointer.h:suggest minor grammar improvement for pointer doc \ +* [Issue #497](https://github.com/json-c/json-c/issues/497) - add common header for all tests \ +* [Issue #498](https://github.com/json-c/json-c/issues/498) - double_serializer_test fails (with valgrind) \ +* [Issue #499](https://github.com/json-c/json-c/issues/499) - .travis.yml:test on more recent clang and gcc versions \ +* [Issue #500](https://github.com/json-c/json-c/issues/500) - test/Makefile.am:add missing deps for test1 and test2 \ +* [Issue #501](https://github.com/json-c/json-c/issues/501) - undefine NDEBUG for tests \ +* [Issue #502](https://github.com/json-c/json-c/issues/502) - configure error \ +* [Issue #503](https://github.com/json-c/json-c/issues/503) - json-c retuns OK when Invalid json string is passed \ +* [Issue #504](https://github.com/json-c/json-c/issues/504) - json_object_put coredump \ +* [Issue #505](https://github.com/json-c/json-c/issues/505) - Add vcpkg installation instructions \ +* [Issue #506](https://github.com/json-c/json-c/issues/506) - Cannot parse more than one object \ +* [Issue #509](https://github.com/json-c/json-c/issues/509) - Sometimes a double value is not serialized \ +* [Issue #510](https://github.com/json-c/json-c/issues/510) - Bump so-name and improve CMake \ +* [Issue #511](https://github.com/json-c/json-c/issues/511) - Reduce lines for better optimization \ +* [Issue #512](https://github.com/json-c/json-c/issues/512) - Properly append to CMAKE_C_FLAGS string \ +* [Issue #513](https://github.com/json-c/json-c/issues/513) - What does `userdata` means?And what is the case we can use it? \ +* [Issue #514](https://github.com/json-c/json-c/issues/514) - Json c 0.13 \ +* [Issue #515](https://github.com/json-c/json-c/issues/515) - Mies suomesta fixes segfaults and logic errors \ +* [Issue #516](https://github.com/json-c/json-c/issues/516) - Lja slight mods \ +* [Issue #518](https://github.com/json-c/json-c/issues/518) - Escape character "\\003\", get unexpected value \ +* [Issue #519](https://github.com/json-c/json-c/issues/519) - Add test case obj token \ +* [Issue #520](https://github.com/json-c/json-c/issues/520) - Adding type uint64 \ +* [Issue #521](https://github.com/json-c/json-c/issues/521) - build cmake windows 10 \ +* [Issue #522](https://github.com/json-c/json-c/issues/522) - update json_visit testcase \ +* [Issue #523](https://github.com/json-c/json-c/issues/523) - update tsetcase for tokener_c \ +* [Issue #524](https://github.com/json-c/json-c/issues/524) - Increase coverage \ +* [Issue #525](https://github.com/json-c/json-c/issues/525) - update pointer test case \ +* [Issue #526](https://github.com/json-c/json-c/issues/526) - Increased the test coverage of printbuf.c 82% to 92%. \ +* [Issue #527](https://github.com/json-c/json-c/issues/527) - Arraylist testcase \ +* [Issue #528](https://github.com/json-c/json-c/issues/528) - Solve issue #108. Skip \u0000 while parsing. \ +* [Issue #529](https://github.com/json-c/json-c/issues/529) - Increased the test coverage of json_c_version.c 0% to 100%. \ +* [Issue #530](https://github.com/json-c/json-c/issues/530) - validate utf-8 string before parse \ +* [Issue #531](https://github.com/json-c/json-c/issues/531) - validate utf-8 string \ +* [Issue #532](https://github.com/json-c/json-c/issues/532) - json_object_object_get_ex returning the original object \ +* [Issue #533](https://github.com/json-c/json-c/issues/533) - Fix "make check" \ +* [Issue #535](https://github.com/json-c/json-c/issues/535) - short string optimization: excessive array length \ +* [Issue #536](https://github.com/json-c/json-c/issues/536) - add json_object_new_null() \ +* [Issue #538](https://github.com/json-c/json-c/issues/538) - update shortstring and arraylist parameters \ +* [Issue #539](https://github.com/json-c/json-c/issues/539) - double serializes to the old value after set_double \ +* [Issue #541](https://github.com/json-c/json-c/issues/541) - add coveralls auto tool to json-c \ +* [Issue #542](https://github.com/json-c/json-c/issues/542) - add uint64 data to json-c \ +* [Issue #543](https://github.com/json-c/json-c/issues/543) - Readme \ +* [Issue #544](https://github.com/json-c/json-c/issues/544) - Increase distcheck target in cmake \ +* [Issue #545](https://github.com/json-c/json-c/issues/545) - add doc target in cmake \ +* [Issue #546](https://github.com/json-c/json-c/issues/546) - Add uninstall target in cmake \ +* [Issue #547](https://github.com/json-c/json-c/issues/547) - modify json-c default build type, and fix up the assert() errors in t… \ +* [Issue #548](https://github.com/json-c/json-c/issues/548) - Solve some problems about cmake build type (debug/release) \ +* [Issue #549](https://github.com/json-c/json-c/issues/549) - lib installation issues \ +* [Issue #550](https://github.com/json-c/json-c/issues/550) - Format codes with clang-format tool? \ +* [Issue #551](https://github.com/json-c/json-c/issues/551) - Allow hexadecimal number format convention parsing \ +* [Issue #553](https://github.com/json-c/json-c/issues/553) - Fix/clang ubsan \ +* [Issue #554](https://github.com/json-c/json-c/issues/554) - RFC 8259 compatibility mode \ +* [Issue #555](https://github.com/json-c/json-c/issues/555) - Format json-c with clang-format tool \ +* [Issue #556](https://github.com/json-c/json-c/issues/556) - Fixes various Wreturn-type and Wimplicit-fallthrough errors on Mingw-w64 \ +* [Issue #557](https://github.com/json-c/json-c/issues/557) - Add option in CMAKE to not build documentation \ +* [Issue #558](https://github.com/json-c/json-c/issues/558) - modify the doc target message \ +* [Issue #559](https://github.com/json-c/json-c/issues/559) - json_c_visit() not exported on Windows \ +* [Issue #560](https://github.com/json-c/json-c/issues/560) - error: implicit declaration of function '_strtoi64' \ +* [Issue #561](https://github.com/json-c/json-c/issues/561) - add the badge in README.md and test the coveralls \ +* [Issue #562](https://github.com/json-c/json-c/issues/562) - Bugfix and testcases supplements \ +* [Issue #563](https://github.com/json-c/json-c/issues/563) - Changed order of calloc args to match stdlib \ +* [Issue #564](https://github.com/json-c/json-c/issues/564) - Remove autogenerated files \ +* [Issue #565](https://github.com/json-c/json-c/issues/565) - test the CI and ignore this PR \ +* [Issue #566](https://github.com/json-c/json-c/issues/566) - add the json_types.h to Makefile.am \ +* [Issue #567](https://github.com/json-c/json-c/issues/567) - Install json_types.h with autotools build as well. \ +* [Issue #568](https://github.com/json-c/json-c/issues/568) - Adding better support to MinGW \ +* [Issue #569](https://github.com/json-c/json-c/issues/569) - Handling of -Bsymbolic-function in CMakeLists.txt is deficient \ +* [Issue #571](https://github.com/json-c/json-c/issues/571) - CMake: Bump SONAME to 5. \ +* [Issue #572](https://github.com/json-c/json-c/issues/572) - Small fixes to CMakeLists \ +* [Issue #573](https://github.com/json-c/json-c/issues/573) - Fix coveralls submission. \ +* [Issue #574](https://github.com/json-c/json-c/issues/574) - autogen.sh missing from repository \ +* [Issue #575](https://github.com/json-c/json-c/issues/575) - Small cosmetics. \ +* [Issue #576](https://github.com/json-c/json-c/issues/576) - Test coverage for json_c_version. \ +* [Issue #577](https://github.com/json-c/json-c/issues/577) - Be verbose on failing json_c_version test. \ +* [Issue #578](https://github.com/json-c/json-c/issues/578) - CMake: Install pkgconfig file in proper location by default \ +* [Issue #579](https://github.com/json-c/json-c/issues/579) - Enforce strict prototypes. \ +* [Issue #580](https://github.com/json-c/json-c/issues/580) - Fix CMake tests for enforced strict prototypes. \ +* [Issue #581](https://github.com/json-c/json-c/issues/581) - CMakeLists: do not enforce strict prototypes on Windows. \ diff --git a/issues_closed_for_0.15.md b/issues_closed_for_0.15.md new file mode 100644 index 0000000..8c7f2f6 --- /dev/null +++ b/issues_closed_for_0.15.md @@ -0,0 +1,85 @@ +This list was created with: + +``` +curl "https://api.github.com/search/issues?q=repo%3Ajson-c%2Fjson-c+closed%3A>2020-04-18+created%3A<2020-07-23&sort=created&order=asc&per_page=100&page=1" > issues1.out +jq -r '.items[] | "[" + .title + "](" + .url + ")" | tostring' issues?.out > issues.md +sed -e's,^\[ *\(.*\)\](https://api.github.com/.*/\([0-9].*\)),* [Issue #\2](https://github.com/json-c/json-c/issues/\2) - \1,' -i issues.md +#... manual editing ... + +``` + +---- + +Issues and Pull Requests closed for the 0.15 release +(since commit 31ab57ca, the 0.14 branch point, 2020-04-19) + +* [Issue #428](https://github.com/json-c/json-c/issues/428) - Added new_null() function +* [Issue #429](https://github.com/json-c/json-c/issues/429) - Conflict of interest between JSON_C_TO_STRING_SPACED and JSON_C_TO_STRING_PRETTY +* [Issue #451](https://github.com/json-c/json-c/issues/451) - Add option to disable HAVE___THREAD +* [Issue #471](https://github.com/json-c/json-c/issues/471) - create folders with mode 0755 when building +* [Issue #476](https://github.com/json-c/json-c/issues/476) - Add new function named json_object_new_string_noalloc +* [Issue #484](https://github.com/json-c/json-c/issues/484) - Add support for uint64 +* [Issue #487](https://github.com/json-c/json-c/issues/487) - Any plans to make new release? (0.14) +* [Issue #493](https://github.com/json-c/json-c/issues/493) - Kdopen rename library +* [Issue #507](https://github.com/json-c/json-c/issues/507) - Double value -1.0 converts to integer in json_object_to_json_string() +* [Issue #508](https://github.com/json-c/json-c/issues/508) - Recommend enabling the `-fPIC` compiler flag by default +* [Issue #517](https://github.com/json-c/json-c/issues/517) - Lja mods +* [Issue #534](https://github.com/json-c/json-c/issues/534) - Both json-c and json-glib have json_object_get_type() +* [Issue #584](https://github.com/json-c/json-c/issues/584) - CMake: SOVERSION and the major library VERSION need to be in lockstep. +* [Issue #585](https://github.com/json-c/json-c/issues/585) - CMake: Do not install config.h, as it is not a public header file. +* [Issue #586](https://github.com/json-c/json-c/issues/586) - 10796 Segmentation fault +* [Issue #588](https://github.com/json-c/json-c/issues/588) - Broken RDRAND causes infinite looping +* [Issue #589](https://github.com/json-c/json-c/issues/589) - Detect broken RDRAND during initialization +* [Issue #590](https://github.com/json-c/json-c/issues/590) - Fix segmentation fault in CPUID check +* [Issue #591](https://github.com/json-c/json-c/issues/591) - Update README.md +* [Issue #592](https://github.com/json-c/json-c/issues/592) - Prevent out of boundary write on malicious input +* [Issue #593](https://github.com/json-c/json-c/issues/593) - Building both static and shared libraries +* [Issue #594](https://github.com/json-c/json-c/issues/594) - Some subsequent call of lh_get_hash not working +* [Issue #595](https://github.com/json-c/json-c/issues/595) - Support to build both static and shared libraries +* [Issue #596](https://github.com/json-c/json-c/issues/596) - QA Notice: Package triggers severe warnings +* [Issue #597](https://github.com/json-c/json-c/issues/597) - json_parse demo: fix and use usage() function +* [Issue #598](https://github.com/json-c/json-c/issues/598) - Turning off shared libs causes target duplication or build error +* [Issue #599](https://github.com/json-c/json-c/issues/599) - cannot add more than 11 objects. Is this a known issue? +* [Issue #600](https://github.com/json-c/json-c/issues/600) - Library name conflicts on Windows are back again +* [Issue #601](https://github.com/json-c/json-c/issues/601) - json_tokener_parse() in master sets errno=1 "Operation not permitted" +* [Issue #602](https://github.com/json-c/json-c/issues/602) - fix json_parse_uint64() internal error checking with errno +* [Issue #603](https://github.com/json-c/json-c/issues/603) - Backport of fixes from master branch. +* [Issue #604](https://github.com/json-c/json-c/issues/604) - commit f2e991a3419ee4078e8915e840b1a0d9003b349e breaks cross-compilation with mingw +* [Issue #605](https://github.com/json-c/json-c/issues/605) - Update to 0.15 release +* [Issue #606](https://github.com/json-c/json-c/issues/606) - Improved support for IBM operating systems +* [Issue #607](https://github.com/json-c/json-c/issues/607) - json-c-0.13.x: Fix CVE-2020-12762 - json-c through 0.14 has an integer overflow and out-of-bounds write ... +* [Issue #608](https://github.com/json-c/json-c/issues/608) - json-c-0.14: Fix CVE-2020-12762 - json-c through 0.14 has an integer overflow and out-of-bounds write ... +* [Issue #609](https://github.com/json-c/json-c/issues/609) - use unsigned types for sizes in lh_table and entries +* [Issue #610](https://github.com/json-c/json-c/issues/610) - let's not call lh_table_resize with INT_MAX +* [Issue #611](https://github.com/json-c/json-c/issues/611) - json-c-0.12.x: Fix CVE-2020-12762 - json-c through 0.14 has an integer overflow and out-of-bounds write ... +* [Issue #613](https://github.com/json-c/json-c/issues/613) - json-c-0.10: Fix CVE-2020-12762 - json-c through 0.14 has an integer overflow and out-of-bounds write ... +* [Issue #614](https://github.com/json-c/json-c/issues/614) - Prevent truncation on custom double formatters. +* [Issue #615](https://github.com/json-c/json-c/issues/615) - New release with security fix +* [Issue #616](https://github.com/json-c/json-c/issues/616) - Parsing fails if UTF-16 low surrogate pair is not in same chunk is the high pair +* [Issue #617](https://github.com/json-c/json-c/issues/617) - Add an option to disable the use of thread-local storage. +* [Issue #618](https://github.com/json-c/json-c/issues/618) - test_deep_copy: Fix assertion value. +* [Issue #619](https://github.com/json-c/json-c/issues/619) - CMake: Fix out-of-tree build for Doxygen documentation. +* [Issue #621](https://github.com/json-c/json-c/issues/621) - json-c and jansson libraries have symbol conflicts +* [Issue #622](https://github.com/json-c/json-c/issues/622) - doc: Move Doxyfile into doc subdir. +* [Issue #623](https://github.com/json-c/json-c/issues/623) - json_tokener_parse : Segmentation fault +* [Issue #626](https://github.com/json-c/json-c/issues/626) - Fixes for cmake 2.8.12 + link issue on AIX 6.1/cc 11.01 +* [Issue #627](https://github.com/json-c/json-c/issues/627) - Compat fixes +* [Issue #628](https://github.com/json-c/json-c/issues/628) - get_cryptgenrandom_seed: compat with old windows + fallback +* [Issue #629](https://github.com/json-c/json-c/issues/629) - [0.12] Remove the Visual Studio project file +* [Issue #630](https://github.com/json-c/json-c/issues/630) - Linking with Windows MINGW not working +* [Issue #632](https://github.com/json-c/json-c/issues/632) - Json object split +* [Issue #633](https://github.com/json-c/json-c/issues/633) - fix issue 616: support the surrogate pair in split file. +* [Issue #634](https://github.com/json-c/json-c/issues/634) - Issue #508: `-fPIC` to link libjson-c.a with libs +* [Issue #635](https://github.com/json-c/json-c/issues/635) - expression has no effect warning in json_tokener.c +* [Issue #636](https://github.com/json-c/json-c/issues/636) - json_object_get_string free str memory +* [Issue #637](https://github.com/json-c/json-c/issues/637) - json_object_put() has 'double free or corruption (out) ' +* [Issue #638](https://github.com/json-c/json-c/issues/638) - json-c/json_object.c:50:2: error: #error Unable to determine size of ssize_t +* [Issue #639](https://github.com/json-c/json-c/issues/639) - build: Add a symbol version to all exported symbols +* [Issue #640](https://github.com/json-c/json-c/issues/640) - Fix build issues with SSIZE_MAX on 64bit Linux +* [Issue #641](https://github.com/json-c/json-c/issues/641) - Formal verification of your test suite +* [Issue #642](https://github.com/json-c/json-c/issues/642) - Please provide more precise informations about when to call json_object_put +* [Issue #643](https://github.com/json-c/json-c/issues/643) - not able to compare with string +* [Issue #644](https://github.com/json-c/json-c/issues/644) - Why src->_userdata not checked before calling strdup? +* [Issue #645](https://github.com/json-c/json-c/issues/645) - Misuse of tolower() in json_tokener.c +* [Issue #646](https://github.com/json-c/json-c/issues/646) - Cast to unsigned char instead of int when calling tolower (Fixes #645) + diff --git a/json-c.sym b/json-c.sym new file mode 100644 index 0000000..2dedc6e --- /dev/null +++ b/json-c.sym @@ -0,0 +1,170 @@ + +/* + * Symbol versioning for libjson-c. + * All exported symbols must be listed here. + * + * See + * https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf + */ + +/* + * Symbols in JSONC_PRIVATE are exported for historical + * reasons, but should not be used outside of json-c. + */ +JSONC_PRIVATE { + array_list_add; + array_list_del_idx; + array_list_free; + array_list_new; + array_list_put_idx; + array_list_sort; + json_hex_chars; + json_parse_double; + json_parse_int64; + json_parse_uint64; + lh_table_delete; + lh_table_delete_entry; + lh_table_free; + lh_table_insert; + lh_table_insert_w_hash; + lh_table_new; + lh_table_resize; + mc_debug; + mc_error; + mc_get_debug; + mc_info; + mc_set_debug; + mc_set_syslog; + printbuf_free; + printbuf_memappend; + printbuf_memset; + printbuf_new; + printbuf_reset; + sprintbuf; +}; + +JSONC_0.14 { + global: + array_list_bsearch; + array_list_get_idx; + array_list_length; + json_c_get_random_seed; + json_c_object_sizeof; + json_c_set_serialization_double_format; + json_c_shallow_copy_default; + json_c_version; + json_c_version_num; + json_c_visit; + json_global_set_string_hash; + json_number_chars; + json_object_array_add; + json_object_array_bsearch; + json_object_array_del_idx; + json_object_array_get_idx; + json_object_array_length; + json_object_array_put_idx; + json_object_array_sort; + json_object_deep_copy; + json_object_double_to_json_string; + json_object_equal; + json_object_free_userdata; + json_object_from_fd; + json_object_from_fd_ex; + json_object_from_file; + json_object_get; + json_object_get_array; + json_object_get_boolean; + json_object_get_double; + json_object_get_int64; + json_object_get_int; + json_object_get_object; + json_object_get_string; + json_object_get_string_len; + json_object_get_type; + json_object_get_uint64; + json_object_get_userdata; + json_object_int_inc; + json_object_is_type; + json_object_iter_begin; + json_object_iter_end; + json_object_iter_equal; + json_object_iter_init_default; + json_object_iter_next; + json_object_iter_peek_name; + json_object_iter_peek_value; + json_object_new_array; + json_object_new_boolean; + json_object_new_double; + json_object_new_double_s; + json_object_new_int64; + json_object_new_int; + json_object_new_null; + json_object_new_object; + json_object_new_string; + json_object_new_string_len; + json_object_new_uint64; + json_object_object_add; + json_object_object_add_ex; + json_object_object_del; + json_object_object_get; + json_object_object_get_ex; + json_object_object_length; + json_object_put; + json_object_set_boolean; + json_object_set_double; + json_object_set_int64; + json_object_set_int; + json_object_set_serializer; + json_object_set_string; + json_object_set_string_len; + json_object_set_uint64; + json_object_set_userdata; + json_object_to_fd; + json_object_to_file; + json_object_to_file_ext; + json_object_to_json_string; + json_object_to_json_string_ext; + json_object_to_json_string_length; + json_object_userdata_to_json_string; + json_pointer_get; + json_pointer_getf; + json_pointer_set; + json_pointer_setf; + json_tokener_error_desc; + json_tokener_free; + json_tokener_get_error; + json_tokener_get_parse_end; + json_tokener_new; + json_tokener_new_ex; + json_tokener_parse; + json_tokener_parse_ex; + json_tokener_parse_verbose; + json_tokener_reset; + json_tokener_set_flags; + json_type_to_name; + json_util_get_last_err; + lh_char_equal; + lh_kchar_table_new; + lh_kptr_table_new; + lh_ptr_equal; + lh_table_length; + lh_table_lookup_entry; + lh_table_lookup_entry_w_hash; + lh_table_lookup_ex; + + local: + *; +}; + +JSONC_0.15 { + global: + array_list_new2; + array_list_shrink; + json_object_array_shrink; + json_object_new_array_ext; +} JSONC_0.14; + +JSONC_0.16 { +# global: +# ...new symbols here... +} JSONC_0.15; @@ -26,7 +26,7 @@ extern "C" { #include "json_c_version.h" #include "json_object.h" #include "json_object_iterator.h" -#include "json_pointer.h" +@JSON_H_JSON_POINTER@ #include "json_tokener.h" #include "json_util.h" #include "linkhash.h" diff --git a/json_c_version.h b/json_c_version.h index 84b6b3e..d15ad64 100644 --- a/json_c_version.h +++ b/json_c_version.h @@ -17,14 +17,14 @@ extern "C" { #endif #define JSON_C_MAJOR_VERSION 0 -#define JSON_C_MINOR_VERSION 14 +#define JSON_C_MINOR_VERSION 15 #define JSON_C_MICRO_VERSION 99 #define JSON_C_VERSION_NUM \ ((JSON_C_MAJOR_VERSION << 16) | (JSON_C_MINOR_VERSION << 8) | JSON_C_MICRO_VERSION) -#define JSON_C_VERSION "0.14.99" +#define JSON_C_VERSION "0.15.99" #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/json_object.c b/json_object.c index c2463c1..c15a477 100644 --- a/json_object.c +++ b/json_object.c @@ -1,6 +1,4 @@ /* - * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $ - * * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. * Michael Clark <michael@metaparadigm.com> * Copyright (c) 2009 Hewlett-Packard Development Company, L.P. @@ -16,6 +14,9 @@ #include <assert.h> #include <ctype.h> +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif #include <math.h> #include <stddef.h> #include <stdio.h> @@ -38,14 +39,98 @@ #error "The long long type isn't 64-bits" #endif +#ifndef SSIZE_T_MAX +#if SIZEOF_SSIZE_T == SIZEOF_INT +#define SSIZE_T_MAX INT_MAX +#elif SIZEOF_SSIZE_T == SIZEOF_LONG +#define SSIZE_T_MAX LONG_MAX +#elif SIZEOF_SSIZE_T == SIZEOF_LONG_LONG +#define SSIZE_T_MAX LLONG_MAX +#else +#error Unable to determine size of ssize_t +#endif +#endif + // Don't define this. It's not thread-safe. /* #define REFCOUNT_DEBUG 1 */ -const char *json_number_chars = "0123456789.+-eE"; const char *json_hex_chars = "0123456789abcdefABCDEF"; static void json_object_generic_delete(struct json_object *jso); -static struct json_object *json_object_new(enum json_type o_type); + +#if defined(_MSC_VER) && (_MSC_VER <= 1800) +/* VS2013 doesn't know about "inline" */ +#define inline __inline +#elif defined(AIX_CC) +#define inline +#endif + +/* + * Helper functions to more safely cast to a particular type of json_object + */ +static inline struct json_object_object *JC_OBJECT(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_object *JC_OBJECT_C(const struct json_object *jso) +{ + return (const void *)jso; +} +static inline struct json_object_array *JC_ARRAY(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_array *JC_ARRAY_C(const struct json_object *jso) +{ + return (const void *)jso; +} +static inline struct json_object_boolean *JC_BOOL(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_boolean *JC_BOOL_C(const struct json_object *jso) +{ + return (const void *)jso; +} +static inline struct json_object_double *JC_DOUBLE(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_double *JC_DOUBLE_C(const struct json_object *jso) +{ + return (const void *)jso; +} +static inline struct json_object_int *JC_INT(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_int *JC_INT_C(const struct json_object *jso) +{ + return (const void *)jso; +} +static inline struct json_object_string *JC_STRING(struct json_object *jso) +{ + return (void *)jso; +} +static inline const struct json_object_string *JC_STRING_C(const struct json_object *jso) +{ + return (const void *)jso; +} + +#define JC_CONCAT(a, b) a##b +#define JC_CONCAT3(a, b, c) a##b##c + +#define JSON_OBJECT_NEW(jtype) \ + (struct JC_CONCAT(json_object_, jtype) *)json_object_new( \ + JC_CONCAT(json_type_, jtype), sizeof(struct JC_CONCAT(json_object_, jtype)), \ + &JC_CONCAT3(json_object_, jtype, _to_json_string)) + +static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size, + json_object_to_json_string_fn *to_json_string); + +static void json_object_object_delete(struct json_object *jso_base); +static void json_object_string_delete(struct json_object *jso); +static void json_object_array_delete(struct json_object *jso); static json_object_to_json_string_fn json_object_object_to_json_string; static json_object_to_json_string_fn json_object_boolean_to_json_string; @@ -111,17 +196,25 @@ static void json_object_fini(void) /* helper for accessing the optimized string data component in json_object */ -static const char *get_string_component(const struct json_object *jso) +static inline char *get_string_component_mutable(struct json_object *jso) { - return (jso->o.c_string.len < LEN_DIRECT_STRING_DATA) ? jso->o.c_string.str.data - : jso->o.c_string.str.ptr; + if (JC_STRING_C(jso)->len < 0) + { + /* Due to json_object_set_string(), we might have a pointer */ + return JC_STRING(jso)->c_string.pdata; + } + return JC_STRING(jso)->c_string.idata; +} +static inline const char *get_string_component(const struct json_object *jso) +{ + return get_string_component_mutable((void *)(uintptr_t)(const void *)jso); } /* string escaping */ -static int json_escape_str(struct printbuf *pb, const char *str, int len, int flags) +static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags) { - int pos = 0, start_offset = 0; + size_t pos = 0, start_offset = 0; unsigned char c; while (len--) { @@ -142,7 +235,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl break; } - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); if (c == '\b') @@ -168,7 +261,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl if (c < ' ') { char sbuf[7]; - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4], @@ -180,7 +273,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl pos++; } } - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); return 0; } @@ -230,7 +323,13 @@ int json_object_put(struct json_object *jso) if (jso->_user_delete) jso->_user_delete(jso, jso->_userdata); - jso->_delete(jso); + switch (jso->o_type) + { + case json_type_object: json_object_object_delete(jso); break; + case json_type_array: json_object_array_delete(jso); break; + case json_type_string: json_object_string_delete(jso); break; + default: json_object_generic_delete(jso); break; + } return 1; } @@ -246,16 +345,23 @@ static void json_object_generic_delete(struct json_object *jso) free(jso); } -static struct json_object *json_object_new(enum json_type o_type) +static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size, + json_object_to_json_string_fn *to_json_string) { struct json_object *jso; - jso = (struct json_object *)calloc(1, sizeof(struct json_object)); + jso = (struct json_object *)malloc(alloc_size); if (!jso) return NULL; + jso->o_type = o_type; jso->_ref_count = 1; - jso->_delete = &json_object_generic_delete; + jso->_to_json_string = to_json_string; + jso->_pb = NULL; + jso->_user_delete = NULL; + jso->_userdata = NULL; + //jso->... // Type-specific fields must be set by caller + #ifdef REFCOUNT_DEBUG lh_table_insert(json_object_table, jso, jso); MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso); @@ -441,28 +547,26 @@ static void json_object_lh_entry_free(struct lh_entry *ent) json_object_put((struct json_object *)lh_entry_v(ent)); } -static void json_object_object_delete(struct json_object *jso) +static void json_object_object_delete(struct json_object *jso_base) { - lh_table_free(jso->o.c_object); - json_object_generic_delete(jso); + lh_table_free(JC_OBJECT(jso_base)->c_object); + json_object_generic_delete(jso_base); } struct json_object *json_object_new_object(void) { - struct json_object *jso = json_object_new(json_type_object); + struct json_object_object *jso = JSON_OBJECT_NEW(object); if (!jso) return NULL; - jso->_delete = &json_object_object_delete; - jso->_to_json_string = &json_object_object_to_json_string; - jso->o.c_object = + jso->c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, &json_object_lh_entry_free); - if (!jso->o.c_object) + if (!jso->c_object) { - json_object_generic_delete(jso); + json_object_generic_delete(&jso->base); errno = ENOMEM; return NULL; } - return jso; + return &jso->base; } struct lh_table *json_object_get_object(const struct json_object *jso) @@ -471,7 +575,7 @@ struct lh_table *json_object_get_object(const struct json_object *jso) return NULL; switch (jso->o_type) { - case json_type_object: return jso->o.c_object; + case json_type_object: return JC_OBJECT_C(jso)->c_object; default: return NULL; } } @@ -487,11 +591,11 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key, // We lookup the entry and replace the value, rather than just deleting // and re-adding it, so the existing key remains valid. - hash = lh_get_hash(jso->o.c_object, (const void *)key); + hash = lh_get_hash(JC_OBJECT(jso)->c_object, (const void *)key); existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL - : lh_table_lookup_entry_w_hash(jso->o.c_object, (const void *)key, hash); + : lh_table_lookup_entry_w_hash(JC_OBJECT(jso)->c_object, (const void *)key, hash); // The caller must avoid creating loops in the object tree, but do a // quick check anyway to make sure we're not creating a trivial loop. @@ -504,7 +608,7 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key, (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : strdup(key); if (k == NULL) return -1; - return lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts); + return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, opts); } existing_value = (json_object *)lh_entry_v(existing_entry); if (existing_value) @@ -521,7 +625,7 @@ int json_object_object_add(struct json_object *jso, const char *key, struct json int json_object_object_length(const struct json_object *jso) { assert(json_object_get_type(jso) == json_type_object); - return lh_table_length(jso->o.c_object); + return lh_table_length(JC_OBJECT_C(jso)->c_object); } size_t json_c_object_sizeof(void) @@ -548,7 +652,8 @@ json_bool json_object_object_get_ex(const struct json_object *jso, const char *k switch (jso->o_type) { case json_type_object: - return lh_table_lookup_ex(jso->o.c_object, (const void *)key, (void **)value); + return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, (const void *)key, + (void **)value); default: if (value != NULL) *value = NULL; @@ -559,7 +664,7 @@ json_bool json_object_object_get_ex(const struct json_object *jso, const char *k void json_object_object_del(struct json_object *jso, const char *key) { assert(json_object_get_type(jso) == json_type_object); - lh_table_delete(jso->o.c_object, key); + lh_table_delete(JC_OBJECT(jso)->c_object, key); } /* json_object_boolean */ @@ -567,19 +672,18 @@ void json_object_object_del(struct json_object *jso, const char *key) static int json_object_boolean_to_json_string(struct json_object *jso, struct printbuf *pb, int level, int flags) { - if (jso->o.c_boolean) + if (JC_BOOL(jso)->c_boolean) return printbuf_strappend(pb, "true"); return printbuf_strappend(pb, "false"); } struct json_object *json_object_new_boolean(json_bool b) { - struct json_object *jso = json_object_new(json_type_boolean); + struct json_object_boolean *jso = JSON_OBJECT_NEW(boolean); if (!jso) return NULL; - jso->_to_json_string = &json_object_boolean_to_json_string; - jso->o.c_boolean = b; - return jso; + jso->c_boolean = b; + return &jso->base; } json_bool json_object_get_boolean(const struct json_object *jso) @@ -588,16 +692,16 @@ json_bool json_object_get_boolean(const struct json_object *jso) return 0; switch (jso->o_type) { - case json_type_boolean: return jso->o.c_boolean; + case json_type_boolean: return JC_BOOL_C(jso)->c_boolean; case json_type_int: - switch (jso->o.c_int.cint_type) + switch (JC_INT_C(jso)->cint_type) { - case json_object_int_type_int64: return (jso->o.c_int.cint.c_int64 != 0); - case json_object_int_type_uint64: return (jso->o.c_int.cint.c_uint64 != 0); + case json_object_int_type_int64: return (JC_INT_C(jso)->cint.c_int64 != 0); + case json_object_int_type_uint64: return (JC_INT_C(jso)->cint.c_uint64 != 0); default: json_abort("invalid cint_type"); } - case json_type_double: return (jso->o.c_double != 0); - case json_type_string: return (jso->o.c_string.len != 0); + case json_type_double: return (JC_DOUBLE_C(jso)->c_double != 0); + case json_type_string: return (JC_STRING_C(jso)->len != 0); default: return 0; } } @@ -606,7 +710,7 @@ int json_object_set_boolean(struct json_object *jso, json_bool new_value) { if (!jso || jso->o_type != json_type_boolean) return 0; - jso->o.c_boolean = new_value; + JC_BOOL(jso)->c_boolean = new_value; return 1; } @@ -617,46 +721,44 @@ static int json_object_int_to_json_string(struct json_object *jso, struct printb { /* room for 19 digits, the sign char, and a null term */ char sbuf[21]; - if (jso->o.c_int.cint_type == json_object_int_type_int64) - snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int.cint.c_int64); + if (JC_INT(jso)->cint_type == json_object_int_type_int64) + snprintf(sbuf, sizeof(sbuf), "%" PRId64, JC_INT(jso)->cint.c_int64); else - snprintf(sbuf, sizeof(sbuf), "%" PRIu64, jso->o.c_int.cint.c_uint64); + snprintf(sbuf, sizeof(sbuf), "%" PRIu64, JC_INT(jso)->cint.c_uint64); return printbuf_memappend(pb, sbuf, strlen(sbuf)); } struct json_object *json_object_new_int(int32_t i) { - struct json_object *jso = json_object_new(json_type_int); - if (!jso) - return NULL; - jso->_to_json_string = &json_object_int_to_json_string; - jso->o.c_int.cint.c_int64 = i; - jso->o.c_int.cint_type = json_object_int_type_int64; - return jso; + return json_object_new_int64(i); } int32_t json_object_get_int(const struct json_object *jso) { - int64_t cint64; + int64_t cint64=0; + double cdouble; enum json_type o_type; if (!jso) return 0; o_type = jso->o_type; - if (jso->o.c_int.cint_type == json_object_int_type_int64) + if (o_type == json_type_int) { - cint64 = jso->o.c_int.cint.c_int64; - } - else - { - if (jso->o.c_int.cint.c_uint64 >= INT64_MAX) - cint64 = INT64_MAX; + const struct json_object_int *jsoint = JC_INT_C(jso); + if (jsoint->cint_type == json_object_int_type_int64) + { + cint64 = jsoint->cint.c_int64; + } else - cint64 = (int64_t)jso->o.c_int.cint.c_uint64; + { + if (jsoint->cint.c_uint64 >= INT64_MAX) + cint64 = INT64_MAX; + else + cint64 = (int64_t)jsoint->cint.c_uint64; + } } - - if (o_type == json_type_string) + else if (o_type == json_type_string) { /* * Parse strings into 64-bit numbers, then use the @@ -677,12 +779,13 @@ int32_t json_object_get_int(const struct json_object *jso) return INT32_MAX; return (int32_t)cint64; case json_type_double: - if (jso->o.c_double <= INT32_MIN) + cdouble = JC_DOUBLE_C(jso)->c_double; + if (cdouble <= INT32_MIN) return INT32_MIN; - if (jso->o.c_double >= INT32_MAX) + if (cdouble >= INT32_MAX) return INT32_MAX; - return (int32_t)jso->o.c_double; - case json_type_boolean: return jso->o.c_boolean; + return (int32_t)cdouble; + case json_type_boolean: return JC_BOOL_C(jso)->c_boolean; default: return 0; } } @@ -694,24 +797,22 @@ int json_object_set_int(struct json_object *jso, int new_value) struct json_object *json_object_new_int64(int64_t i) { - struct json_object *jso = json_object_new(json_type_int); + struct json_object_int *jso = JSON_OBJECT_NEW(int); if (!jso) return NULL; - jso->_to_json_string = &json_object_int_to_json_string; - jso->o.c_int.cint.c_int64 = i; - jso->o.c_int.cint_type = json_object_int_type_int64; - return jso; + jso->cint.c_int64 = i; + jso->cint_type = json_object_int_type_int64; + return &jso->base; } struct json_object *json_object_new_uint64(uint64_t i) { - struct json_object *jso = json_object_new(json_type_int); + struct json_object_int *jso = JSON_OBJECT_NEW(int); if (!jso) return NULL; - jso->_to_json_string = &json_object_int_to_json_string; - jso->o.c_int.cint.c_uint64 = i; - jso->o.c_int.cint_type = json_object_int_type_uint64; - return jso; + jso->cint.c_uint64 = i; + jso->cint_type = json_object_int_type_uint64; + return &jso->base; } int64_t json_object_get_int64(const struct json_object *jso) @@ -723,24 +824,27 @@ int64_t json_object_get_int64(const struct json_object *jso) switch (jso->o_type) { case json_type_int: - switch (jso->o.c_int.cint_type) + { + const struct json_object_int *jsoint = JC_INT_C(jso); + switch (jsoint->cint_type) { - case json_object_int_type_int64: return jso->o.c_int.cint.c_int64; + case json_object_int_type_int64: return jsoint->cint.c_int64; case json_object_int_type_uint64: - if (jso->o.c_int.cint.c_uint64 >= INT64_MAX) + if (jsoint->cint.c_uint64 >= INT64_MAX) return INT64_MAX; - return (int64_t)jso->o.c_int.cint.c_uint64; + return (int64_t)jsoint->cint.c_uint64; default: json_abort("invalid cint_type"); } + } case json_type_double: // INT64_MAX can't be exactly represented as a double // so cast to tell the compiler it's ok to round up. - if (jso->o.c_double >= (double)INT64_MAX) + if (JC_DOUBLE_C(jso)->c_double >= (double)INT64_MAX) return INT64_MAX; - if (jso->o.c_double <= INT64_MIN) + if (JC_DOUBLE_C(jso)->c_double <= INT64_MIN) return INT64_MIN; - return (int64_t)jso->o.c_double; - case json_type_boolean: return jso->o.c_boolean; + return (int64_t)JC_DOUBLE_C(jso)->c_double; + case json_type_boolean: return JC_BOOL_C(jso)->c_boolean; case json_type_string: if (json_parse_int64(get_string_component(jso), &cint) == 0) return cint; @@ -758,24 +862,27 @@ uint64_t json_object_get_uint64(const struct json_object *jso) switch (jso->o_type) { case json_type_int: - switch (jso->o.c_int.cint_type) + { + const struct json_object_int *jsoint = JC_INT_C(jso); + switch (jsoint->cint_type) { case json_object_int_type_int64: - if (jso->o.c_int.cint.c_int64 < 0) + if (jsoint->cint.c_int64 < 0) return 0; - return (uint64_t)jso->o.c_int.cint.c_int64; - case json_object_int_type_uint64: return jso->o.c_int.cint.c_uint64; + return (uint64_t)jsoint->cint.c_int64; + case json_object_int_type_uint64: return jsoint->cint.c_uint64; default: json_abort("invalid cint_type"); } + } case json_type_double: // UINT64_MAX can't be exactly represented as a double // so cast to tell the compiler it's ok to round up. - if (jso->o.c_double >= (double)UINT64_MAX) + if (JC_DOUBLE_C(jso)->c_double >= (double)UINT64_MAX) return UINT64_MAX; - if (jso->o.c_double < 0) + if (JC_DOUBLE_C(jso)->c_double < 0) return 0; - return (uint64_t)jso->o.c_double; - case json_type_boolean: return jso->o.c_boolean; + return (uint64_t)JC_DOUBLE_C(jso)->c_double; + case json_type_boolean: return JC_BOOL_C(jso)->c_boolean; case json_type_string: if (json_parse_uint64(get_string_component(jso), &cuint) == 0) return cuint; @@ -788,8 +895,8 @@ int json_object_set_int64(struct json_object *jso, int64_t new_value) { if (!jso || jso->o_type != json_type_int) return 0; - jso->o.c_int.cint.c_int64 = new_value; - jso->o.c_int.cint_type = json_object_int_type_int64; + JC_INT(jso)->cint.c_int64 = new_value; + JC_INT(jso)->cint_type = json_object_int_type_int64; return 1; } @@ -797,50 +904,51 @@ int json_object_set_uint64(struct json_object *jso, uint64_t new_value) { if (!jso || jso->o_type != json_type_int) return 0; - jso->o.c_int.cint.c_uint64 = new_value; - jso->o.c_int.cint_type = json_object_int_type_uint64; + JC_INT(jso)->cint.c_uint64 = new_value; + JC_INT(jso)->cint_type = json_object_int_type_uint64; return 1; } int json_object_int_inc(struct json_object *jso, int64_t val) { + struct json_object_int *jsoint; if (!jso || jso->o_type != json_type_int) return 0; - switch (jso->o.c_int.cint_type) + jsoint = JC_INT(jso); + switch (jsoint->cint_type) { case json_object_int_type_int64: - if (val > 0 && jso->o.c_int.cint.c_int64 > INT64_MAX - val) + if (val > 0 && jsoint->cint.c_int64 > INT64_MAX - val) { - jso->o.c_int.cint.c_uint64 = - (uint64_t)jso->o.c_int.cint.c_int64 + (uint64_t)val; - jso->o.c_int.cint_type = json_object_int_type_uint64; + jsoint->cint.c_uint64 = (uint64_t)jsoint->cint.c_int64 + (uint64_t)val; + jsoint->cint_type = json_object_int_type_uint64; } - else if (val < 0 && jso->o.c_int.cint.c_int64 < INT64_MIN - val) + else if (val < 0 && jsoint->cint.c_int64 < INT64_MIN - val) { - jso->o.c_int.cint.c_int64 = INT64_MIN; + jsoint->cint.c_int64 = INT64_MIN; } else { - jso->o.c_int.cint.c_int64 += val; + jsoint->cint.c_int64 += val; } return 1; case json_object_int_type_uint64: - if (val > 0 && jso->o.c_int.cint.c_uint64 > UINT64_MAX - (uint64_t)val) + if (val > 0 && jsoint->cint.c_uint64 > UINT64_MAX - (uint64_t)val) { - jso->o.c_int.cint.c_uint64 = UINT64_MAX; + jsoint->cint.c_uint64 = UINT64_MAX; } - else if (val < 0 && jso->o.c_int.cint.c_uint64 < (uint64_t)(-val)) + else if (val < 0 && jsoint->cint.c_uint64 < (uint64_t)(-val)) { - jso->o.c_int.cint.c_int64 = (int64_t)jso->o.c_int.cint.c_uint64 + val; - jso->o.c_int.cint_type = json_object_int_type_int64; + jsoint->cint.c_int64 = (int64_t)jsoint->cint.c_uint64 + val; + jsoint->cint_type = json_object_int_type_int64; } - else if (val < 0 && jso->o.c_int.cint.c_uint64 >= (uint64_t)(-val)) + else if (val < 0 && jsoint->cint.c_uint64 >= (uint64_t)(-val)) { - jso->o.c_int.cint.c_uint64 -= (uint64_t)(-val); + jsoint->cint.c_uint64 -= (uint64_t)(-val); } else { - jso->o.c_int.cint.c_uint64 += val; + jsoint->cint.c_uint64 += val; } return 1; default: json_abort("invalid cint_type"); @@ -896,6 +1004,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global static int json_object_double_to_json_string_format(struct json_object *jso, struct printbuf *pb, int level, int flags, const char *format) { + struct json_object_double *jsodbl = JC_DOUBLE(jso); char buf[128], *p, *q; int size; /* Although JSON RFC does not support @@ -903,13 +1012,13 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str * ECMA 262 section 9.8.1 defines * how to handle these cases as strings */ - if (isnan(jso->o.c_double)) + if (isnan(jsodbl->c_double)) { size = snprintf(buf, sizeof(buf), "NaN"); } - else if (isinf(jso->o.c_double)) + else if (isinf(jsodbl->c_double)) { - if (jso->o.c_double > 0) + if (jsodbl->c_double > 0) size = snprintf(buf, sizeof(buf), "Infinity"); else size = snprintf(buf, sizeof(buf), "-Infinity"); @@ -932,7 +1041,7 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str else format = std_format; } - size = snprintf(buf, sizeof(buf), format, jso->o.c_double); + size = snprintf(buf, sizeof(buf), format, jsodbl->c_double); if (size < 0) return -1; @@ -1001,12 +1110,12 @@ int json_object_double_to_json_string(struct json_object *jso, struct printbuf * struct json_object *json_object_new_double(double d) { - struct json_object *jso = json_object_new(json_type_double); + struct json_object_double *jso = JSON_OBJECT_NEW(double); if (!jso) return NULL; - jso->_to_json_string = &json_object_double_to_json_string_default; - jso->o.c_double = d; - return jso; + jso->base._to_json_string = &json_object_double_to_json_string_default; + jso->c_double = d; + return &jso->base; } struct json_object *json_object_new_double_s(double d, const char *ds) @@ -1061,15 +1170,15 @@ double json_object_get_double(const struct json_object *jso) return 0.0; switch (jso->o_type) { - case json_type_double: return jso->o.c_double; + case json_type_double: return JC_DOUBLE_C(jso)->c_double; case json_type_int: - switch (jso->o.c_int.cint_type) + switch (JC_INT_C(jso)->cint_type) { - case json_object_int_type_int64: return jso->o.c_int.cint.c_int64; - case json_object_int_type_uint64: return jso->o.c_int.cint.c_uint64; + case json_object_int_type_int64: return JC_INT_C(jso)->cint.c_int64; + case json_object_int_type_uint64: return JC_INT_C(jso)->cint.c_uint64; default: json_abort("invalid cint_type"); } - case json_type_boolean: return jso->o.c_boolean; + case json_type_boolean: return JC_BOOL_C(jso)->c_boolean; case json_type_string: errno = 0; cdouble = strtod(get_string_component(jso), &errPtr); @@ -1114,7 +1223,7 @@ int json_object_set_double(struct json_object *jso, double new_value) { if (!jso || jso->o_type != json_type_double) return 0; - jso->o.c_double = new_value; + JC_DOUBLE(jso)->c_double = new_value; if (jso->_to_json_string == &_json_object_userdata_to_json_string) json_object_set_serializer(jso, NULL, NULL, NULL); return 1; @@ -1125,71 +1234,65 @@ int json_object_set_double(struct json_object *jso, double new_value) static int json_object_string_to_json_string(struct json_object *jso, struct printbuf *pb, int level, int flags) { + ssize_t len = JC_STRING(jso)->len; printbuf_strappend(pb, "\""); - json_escape_str(pb, get_string_component(jso), jso->o.c_string.len, flags); + json_escape_str(pb, get_string_component(jso), len < 0 ? -(ssize_t)len : len, flags); printbuf_strappend(pb, "\""); return 0; } static void json_object_string_delete(struct json_object *jso) { - if (jso->o.c_string.len >= LEN_DIRECT_STRING_DATA) - free(jso->o.c_string.str.ptr); + if (JC_STRING(jso)->len < 0) + free(JC_STRING(jso)->c_string.pdata); json_object_generic_delete(jso); } -struct json_object *json_object_new_string(const char *s) +static struct json_object *_json_object_new_string(const char *s, const size_t len) { - struct json_object *jso = json_object_new(json_type_string); + size_t objsize; + struct json_object_string *jso; + + /* + * Structures Actual memory layout + * ------------------- -------------------- + * [json_object_string [json_object_string + * [json_object] [json_object] + * ...other fields... ...other fields... + * c_string] len + * bytes + * of + * string + * data + * \0] + */ + if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1)) + return NULL; + objsize = (sizeof(*jso) - sizeof(jso->c_string)) + len + 1; + if (len < sizeof(void *)) + // We need a minimum size to support json_object_set_string() mutability + // so we can stuff a pointer into pdata :( + objsize += sizeof(void *) - len; + + jso = (struct json_object_string *)json_object_new(json_type_string, objsize, + &json_object_string_to_json_string); + if (!jso) return NULL; - jso->_delete = &json_object_string_delete; - jso->_to_json_string = &json_object_string_to_json_string; - jso->o.c_string.len = strlen(s); - if (jso->o.c_string.len < LEN_DIRECT_STRING_DATA) - { - memcpy(jso->o.c_string.str.data, s, jso->o.c_string.len); - } - else - { - jso->o.c_string.str.ptr = strdup(s); - if (!jso->o.c_string.str.ptr) - { - json_object_generic_delete(jso); - errno = ENOMEM; - return NULL; - } - } - return jso; + jso->len = len; + memcpy(jso->c_string.idata, s, len); + jso->c_string.idata[len] = '\0'; + return &jso->base; +} + +struct json_object *json_object_new_string(const char *s) +{ + return _json_object_new_string(s, strlen(s)); } struct json_object *json_object_new_string_len(const char *s, const int len) { - char *dstbuf; - struct json_object *jso = json_object_new(json_type_string); - if (!jso) - return NULL; - jso->_delete = &json_object_string_delete; - jso->_to_json_string = &json_object_string_to_json_string; - if (len < LEN_DIRECT_STRING_DATA) - { - dstbuf = jso->o.c_string.str.data; - } - else - { - jso->o.c_string.str.ptr = (char *)malloc(len + 1); - if (!jso->o.c_string.str.ptr) - { - json_object_generic_delete(jso); - errno = ENOMEM; - return NULL; - } - dstbuf = jso->o.c_string.str.ptr; - } - memcpy(dstbuf, (const void *)s, len); - dstbuf[len] = '\0'; - jso->o.c_string.len = len; - return jso; + return _json_object_new_string(s, len); } const char *json_object_get_string(struct json_object *jso) @@ -1202,49 +1305,78 @@ const char *json_object_get_string(struct json_object *jso) default: return json_object_to_json_string(jso); } } - int json_object_get_string_len(const struct json_object *jso) { + ssize_t len; if (!jso) return 0; switch (jso->o_type) { - case json_type_string: return jso->o.c_string.len; + case json_type_string: + { + len = JC_STRING_C(jso)->len; + return (len < 0) ? -(ssize_t)len : len; + } default: return 0; } } -int json_object_set_string(json_object *jso, const char *s) -{ - return json_object_set_string_len(jso, s, (int)(strlen(s))); -} - -int json_object_set_string_len(json_object *jso, const char *s, int len) +static int _json_object_set_string_len(json_object *jso, const char *s, size_t len) { char *dstbuf; + ssize_t curlen; + ssize_t newlen; if (jso == NULL || jso->o_type != json_type_string) return 0; - if (len < LEN_DIRECT_STRING_DATA) - { - dstbuf = jso->o.c_string.str.data; - if (jso->o.c_string.len >= LEN_DIRECT_STRING_DATA) - free(jso->o.c_string.str.ptr); - } - else + + if (len >= INT_MAX - 1) + // jso->len is a signed ssize_t, so it can't hold the + // full size_t range. json_object_get_string_len returns + // length as int, cap length at INT_MAX. + return 0; + + dstbuf = get_string_component_mutable(jso); + curlen = JC_STRING(jso)->len; + if (curlen < 0) + curlen = -curlen; + newlen = len; + + if ((ssize_t)len > curlen) { + // We have no way to return the new ptr from realloc(jso, newlen) + // and we have no way of knowing whether there's extra room available + // so we need to stuff a pointer in to pdata :( dstbuf = (char *)malloc(len + 1); if (dstbuf == NULL) return 0; - if (jso->o.c_string.len >= LEN_DIRECT_STRING_DATA) - free(jso->o.c_string.str.ptr); - jso->o.c_string.str.ptr = dstbuf; + if (JC_STRING(jso)->len < 0) + free(JC_STRING(jso)->c_string.pdata); + JC_STRING(jso)->c_string.pdata = dstbuf; + newlen = -(ssize_t)len; } - jso->o.c_string.len = len; + else if (JC_STRING(jso)->len < 0) + { + // We've got enough room in the separate allocated buffer, + // so use it as-is and continue to indicate that pdata is used. + newlen = -(ssize_t)len; + } + memcpy(dstbuf, (const void *)s, len); dstbuf[len] = '\0'; + JC_STRING(jso)->len = newlen; return 1; } +int json_object_set_string(json_object *jso, const char *s) +{ + return _json_object_set_string_len(jso, s, strlen(s)); +} + +int json_object_set_string_len(json_object *jso, const char *s, int len) +{ + return _json_object_set_string_len(jso, s, len); +} + /* json_object_array */ static int json_object_array_to_json_string(struct json_object *jso, struct printbuf *pb, int level, @@ -1294,24 +1426,26 @@ static void json_object_array_entry_free(void *data) static void json_object_array_delete(struct json_object *jso) { - array_list_free(jso->o.c_array); + array_list_free(JC_ARRAY(jso)->c_array); json_object_generic_delete(jso); } struct json_object *json_object_new_array(void) { - struct json_object *jso = json_object_new(json_type_array); + return json_object_new_array_ext(ARRAY_LIST_DEFAULT_SIZE); +} +struct json_object *json_object_new_array_ext(int initial_size) +{ + struct json_object_array *jso = JSON_OBJECT_NEW(array); if (!jso) return NULL; - jso->_delete = &json_object_array_delete; - jso->_to_json_string = &json_object_array_to_json_string; - jso->o.c_array = array_list_new(&json_object_array_entry_free); - if (jso->o.c_array == NULL) + jso->c_array = array_list_new2(&json_object_array_entry_free, initial_size); + if (jso->c_array == NULL) { free(jso); return NULL; } - return jso; + return &jso->base; } struct array_list *json_object_get_array(const struct json_object *jso) @@ -1320,7 +1454,7 @@ struct array_list *json_object_get_array(const struct json_object *jso) return NULL; switch (jso->o_type) { - case json_type_array: return jso->o.c_array; + case json_type_array: return JC_ARRAY_C(jso)->c_array; default: return NULL; } } @@ -1328,7 +1462,7 @@ struct array_list *json_object_get_array(const struct json_object *jso) void json_object_array_sort(struct json_object *jso, int (*sort_fn)(const void *, const void *)) { assert(json_object_get_type(jso) == json_type_array); - array_list_sort(jso->o.c_array, sort_fn); + array_list_sort(JC_ARRAY(jso)->c_array, sort_fn); } struct json_object *json_object_array_bsearch(const struct json_object *key, @@ -1339,7 +1473,7 @@ struct json_object *json_object_array_bsearch(const struct json_object *key, assert(json_object_get_type(jso) == json_type_array); result = (struct json_object **)array_list_bsearch((const void **)(void *)&key, - jso->o.c_array, sort_fn); + JC_ARRAY_C(jso)->c_array, sort_fn); if (!result) return NULL; @@ -1349,31 +1483,31 @@ struct json_object *json_object_array_bsearch(const struct json_object *key, size_t json_object_array_length(const struct json_object *jso) { assert(json_object_get_type(jso) == json_type_array); - return array_list_length(jso->o.c_array); + return array_list_length(JC_ARRAY_C(jso)->c_array); } int json_object_array_add(struct json_object *jso, struct json_object *val) { assert(json_object_get_type(jso) == json_type_array); - return array_list_add(jso->o.c_array, val); + return array_list_add(JC_ARRAY(jso)->c_array, val); } int json_object_array_put_idx(struct json_object *jso, size_t idx, struct json_object *val) { assert(json_object_get_type(jso) == json_type_array); - return array_list_put_idx(jso->o.c_array, idx, val); + return array_list_put_idx(JC_ARRAY(jso)->c_array, idx, val); } int json_object_array_del_idx(struct json_object *jso, size_t idx, size_t count) { assert(json_object_get_type(jso) == json_type_array); - return array_list_del_idx(jso->o.c_array, idx, count); + return array_list_del_idx(JC_ARRAY(jso)->c_array, idx, count); } struct json_object *json_object_array_get_idx(const struct json_object *jso, size_t idx) { assert(json_object_get_type(jso) == json_type_array); - return (struct json_object *)array_list_get_idx(jso->o.c_array, idx); + return (struct json_object *)array_list_get_idx(JC_ARRAY_C(jso)->c_array, idx); } static int json_array_equal(struct json_object *jso1, struct json_object *jso2) @@ -1393,6 +1527,13 @@ static int json_array_equal(struct json_object *jso1, struct json_object *jso2) return 1; } +int json_object_array_shrink(struct json_object *jso, int empty_slots) +{ + if (empty_slots < 0) + json_abort("json_object_array_shrink called with negative empty_slots"); + return array_list_shrink(JC_ARRAY(jso)->c_array, empty_slots); +} + struct json_object *json_object_new_null(void) { return NULL; @@ -1408,7 +1549,8 @@ static int json_object_all_values_equal(struct json_object *jso1, struct json_ob /* Iterate over jso1 keys and see if they exist and are equal in jso2 */ json_object_object_foreachC(jso1, iter) { - if (!lh_table_lookup_ex(jso2->o.c_object, (void *)iter.key, (void **)(void *)&sub)) + if (!lh_table_lookup_ex(JC_OBJECT(jso2)->c_object, (void *)iter.key, + (void **)(void *)&sub)) return 0; if (!json_object_equal(iter.val, sub)) return 0; @@ -1417,7 +1559,8 @@ static int json_object_all_values_equal(struct json_object *jso1, struct json_ob /* Iterate over jso2 keys to see if any exist that are not in jso1 */ json_object_object_foreachC(jso2, iter) { - if (!lh_table_lookup_ex(jso1->o.c_object, (void *)iter.key, (void **)(void *)&sub)) + if (!lh_table_lookup_ex(JC_OBJECT(jso1)->c_object, (void *)iter.key, + (void **)(void *)&sub)) return 0; } @@ -1437,31 +1580,36 @@ int json_object_equal(struct json_object *jso1, struct json_object *jso2) switch (jso1->o_type) { - case json_type_boolean: return (jso1->o.c_boolean == jso2->o.c_boolean); + case json_type_boolean: return (JC_BOOL(jso1)->c_boolean == JC_BOOL(jso2)->c_boolean); - case json_type_double: return (jso1->o.c_double == jso2->o.c_double); + case json_type_double: return (JC_DOUBLE(jso1)->c_double == JC_DOUBLE(jso2)->c_double); case json_type_int: - if (jso1->o.c_int.cint_type == json_object_int_type_int64) + { + struct json_object_int *int1 = JC_INT(jso1); + struct json_object_int *int2 = JC_INT(jso2); + if (int1->cint_type == json_object_int_type_int64) { - if (jso2->o.c_int.cint_type == json_object_int_type_int64) - return (jso1->o.c_int.cint.c_int64 == jso2->o.c_int.cint.c_int64); - if (jso1->o.c_int.cint.c_int64 < 0) + if (int2->cint_type == json_object_int_type_int64) + return (int1->cint.c_int64 == int2->cint.c_int64); + if (int1->cint.c_int64 < 0) return 0; - return ((uint64_t)jso1->o.c_int.cint.c_int64 == - jso2->o.c_int.cint.c_uint64); + return ((uint64_t)int1->cint.c_int64 == int2->cint.c_uint64); } // else jso1 is a uint64 - if (jso2->o.c_int.cint_type == json_object_int_type_uint64) - return (jso1->o.c_int.cint.c_uint64 == jso2->o.c_int.cint.c_uint64); - if (jso2->o.c_int.cint.c_int64 < 0) + if (int2->cint_type == json_object_int_type_uint64) + return (int1->cint.c_uint64 == int2->cint.c_uint64); + if (int2->cint.c_int64 < 0) return 0; - return (jso1->o.c_int.cint.c_uint64 == (uint64_t)jso2->o.c_int.cint.c_int64); + return (int1->cint.c_uint64 == (uint64_t)int2->cint.c_int64); + } case json_type_string: - return (jso1->o.c_string.len == jso2->o.c_string.len && + { + return (json_object_get_string_len(jso1) == json_object_get_string_len(jso2) && memcmp(get_string_component(jso1), get_string_component(jso2), - jso1->o.c_string.len) == 0); + json_object_get_string_len(jso1)) == 0); + } case json_type_object: return json_object_all_values_equal(jso1, jso2); @@ -1488,7 +1636,7 @@ static int json_object_copy_serializer_data(struct json_object *src, struct json { _json_c_set_last_err( "json_object_deep_copy: unable to copy unknown serializer data: %p\n", - dst->_to_json_string); + (void *)dst->_to_json_string); return -1; } dst->_user_delete = src->_user_delete; @@ -1508,18 +1656,18 @@ int json_c_shallow_copy_default(json_object *src, json_object *parent, const cha { switch (src->o_type) { - case json_type_boolean: *dst = json_object_new_boolean(src->o.c_boolean); break; + case json_type_boolean: *dst = json_object_new_boolean(JC_BOOL(src)->c_boolean); break; - case json_type_double: *dst = json_object_new_double(src->o.c_double); break; + case json_type_double: *dst = json_object_new_double(JC_DOUBLE(src)->c_double); break; case json_type_int: - switch (src->o.c_int.cint_type) + switch (JC_INT(src)->cint_type) { case json_object_int_type_int64: - *dst = json_object_new_int64(src->o.c_int.cint.c_int64); + *dst = json_object_new_int64(JC_INT(src)->cint.c_int64); break; case json_object_int_type_uint64: - *dst = json_object_new_uint64(src->o.c_int.cint.c_uint64); + *dst = json_object_new_uint64(JC_INT(src)->cint.c_uint64); break; default: json_abort("invalid cint_type"); } @@ -1577,7 +1725,7 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_ /* This handles the `json_type_null` case */ if (!iter.val) jso = NULL; - else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso, + else if (json_object_deep_copy_recursive(iter.val, src, iter.key, UINT_MAX, &jso, shallow_copy) < 0) { json_object_put(jso); @@ -1642,7 +1790,7 @@ int json_object_deep_copy(struct json_object *src, struct json_object **dst, if (shallow_copy == NULL) shallow_copy = json_c_shallow_copy_default; - rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy); + rc = json_object_deep_copy_recursive(src, NULL, NULL, UINT_MAX, dst, shallow_copy); if (rc < 0) { json_object_put(*dst); diff --git a/json_object.h b/json_object.h index be6919a..d67f384 100644 --- a/json_object.h +++ b/json_object.h @@ -18,16 +18,6 @@ #define _json_object_h_ #ifdef __GNUC__ -#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func -#elif defined(__clang__) -#define THIS_FUNCTION_IS_DEPRECATED(func) func __deprecated -#else -#define THIS_FUNCTION_IS_DEPRECATED(func) func -#endif - -#ifdef __GNUC__ #define JSON_C_CONST_FUNCTION(func) func __attribute__((const)) #else #define JSON_C_CONST_FUNCTION(func) func @@ -133,21 +123,43 @@ extern "C" { /* reference counting functions */ /** - * Increment the reference count of json_object, thereby grabbing shared - * ownership of obj. + * Increment the reference count of json_object, thereby taking ownership of it. + * + * Cases where you might need to increase the refcount include: + * - Using an object field or array index (retrieved through + * `json_object_object_get()` or `json_object_array_get_idx()`) + * beyond the lifetime of the parent object. + * - Detaching an object field or array index from its parent object + * (using `json_object_object_del()` or `json_object_array_del_idx()`) + * - Sharing a json_object with multiple (not necesarily parallel) threads + * of execution that all expect to free it (with `json_object_put()`) when + * they're done. * * @param obj the json_object instance + * @see json_object_put() + * @see json_object_object_get() + * @see json_object_array_get_idx() */ JSON_EXPORT struct json_object *json_object_get(struct json_object *obj); /** * Decrement the reference count of json_object and free if it reaches zero. + * * You must have ownership of obj prior to doing this or you will cause an - * imbalance in the reference count. - * An obj of NULL may be passed; in that case this call is a no-op. + * imbalance in the reference count, leading to a classic use-after-free bug. + * In particular, you normally do not need to call `json_object_put()` on the + * json_object returned by `json_object_object_get()` or `json_object_array_get_idx()`. + * + * Just like after calling `free()` on a block of memory, you must not use + * `obj` after calling `json_object_put()` on it or any object that it + * is a member of (unless you know you've called `json_object_get(obj)` to + * explicitly increment the refcount). + * + * NULL may be passed, which which case this is a no-op. * * @param obj the json_object instance * @returns 1 if the object was freed. + * @see json_object_get() */ JSON_EXPORT int json_object_put(struct json_object *obj); @@ -347,15 +359,21 @@ JSON_C_CONST_FUNCTION(JSON_EXPORT size_t json_c_object_sizeof(void)); /** Add an object field to a json_object of type json_type_object * - * The reference count will *not* be incremented. This is to make adding - * fields to objects in code more compact. If you want to retain a reference - * to an added object, independent of the lifetime of obj, you must wrap the - * passed object with json_object_get. + * The reference count of `val` will *not* be incremented, in effect + * transferring ownership that object to `obj`, and thus `val` will be + * freed when `obj` is. (i.e. through `json_object_put(obj)`) + * + * If you want to retain a reference to the added object, independent + * of the lifetime of obj, you must increment the refcount with + * `json_object_get(val)` (and later release it with json_object_put()). + * + * Since ownership transfers to `obj`, you must make sure + * that you do in fact have ownership over `val`. For instance, + * json_object_new_object() will give you ownership until you transfer it, + * whereas json_object_object_get() does not. * - * Upon calling this, the ownership of val transfers to obj. Thus you must - * make sure that you do in fact have ownership over this object. For instance, - * json_object_new_object will give you ownership until you transfer it, - * whereas json_object_object_get does not. + * Any previous object stored under `key` in `obj` will have its refcount + * decremented, and be freed normally if that drops to zero. * * @param obj the json_object instance * @param key the object field name (a private copy will be duplicated) @@ -378,7 +396,7 @@ JSON_EXPORT int json_object_object_add(struct json_object *obj, const char *key, * @param key the object field name (a private copy will be duplicated) * @param val a json_object or NULL member to associate with the given field * @param opts process-modifying options. To specify multiple options, use - * arithmetic or (OPT1|OPT2) + * (OPT1|OPT2) */ JSON_EXPORT int json_object_object_add_ex(struct json_object *obj, const char *const key, struct json_object *const val, const unsigned opts); @@ -500,10 +518,23 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key /* Array type methods */ /** Create a new empty json_object of type json_type_array + * with 32 slots allocated. + * If you know the array size you'll need ahead of time, use + * json_object_new_array_ext() instead. + * @see json_object_new_array_ext() + * @see json_object_array_shrink() * @returns a json_object of type json_type_array */ JSON_EXPORT struct json_object *json_object_new_array(void); +/** Create a new empty json_object of type json_type_array + * with the desired number of slots allocated. + * @see json_object_array_shrink() + * @param initial_size the number of slots to allocate + * @returns a json_object of type json_type_array + */ +JSON_EXPORT struct json_object *json_object_new_array_ext(int initial_size); + /** Get the arraylist of a json_object of type json_type_array * @param obj the json_object instance * @returns an arraylist @@ -574,7 +605,15 @@ JSON_EXPORT int json_object_array_add(struct json_object *obj, struct json_objec JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, struct json_object *val); -/** Get the element at specified index of the array (a json_object of type json_type_array) +/** Get the element at specified index of array `obj` (which must be a json_object of type json_type_array) + * + * *No* reference counts will be changed, and ownership of the returned + * object remains with `obj`. See json_object_object_get() for additional + * implications of this behavior. + * + * Calling this with anything other than a json_type_array will trigger + * an assert. + * * @param obj the json_object instance * @param idx the index to get the element at * @returns the json_object at the specified index (or NULL) @@ -595,6 +634,15 @@ JSON_EXPORT struct json_object *json_object_array_get_idx(const struct json_obje */ JSON_EXPORT int json_object_array_del_idx(struct json_object *obj, size_t idx, size_t count); +/** + * Shrink the internal memory allocation of the array to just + * enough to fit the number of elements in it, plus empty_slots. + * + * @param jso the json_object instance, must be json_type_array + * @param empty_slots the number of empty slots to leave allocated + */ +JSON_EXPORT int json_object_array_shrink(struct json_object *jso, int empty_slots); + /* json_bool type methods */ /** Create a new empty json_object of type json_type_boolean @@ -608,8 +656,9 @@ JSON_EXPORT struct json_object *json_object_new_boolean(json_bool b); * The type is coerced to a json_bool if the passed object is not a json_bool. * integer and double objects will return 0 if there value is zero * or 1 otherwise. If the passed object is a string it will return - * 1 if it has a non zero length. If any other object type is passed - * 1 will be returned if the object is not NULL. + * 1 if it has a non zero length. + * If any other object type is passed 0 will be returned, even non-empty + * json_type_array and json_type_object objects. * * @param obj the json_object instance * @returns a json_bool diff --git a/json_object_iterator.c b/json_object_iterator.c index 796015e..1c2b3f2 100644 --- a/json_object_iterator.c +++ b/json_object_iterator.c @@ -9,6 +9,7 @@ * ******************************************************************************* */ +#include "config.h" #include <stddef.h> diff --git a/json_object_private.h b/json_object_private.h index 1c7737a..e143b46 100644 --- a/json_object_private.h +++ b/json_object_private.h @@ -20,14 +20,18 @@ extern "C" { #endif -/**< how many bytes are directly stored in json_object for strings? */ -#define LEN_DIRECT_STRING_DATA 32 - struct json_object; #include "json_inttypes.h" #include "json_types.h" -typedef void(json_object_private_delete_fn)(struct json_object *o); +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef _MSC_VER +#include <BaseTsd.h> +typedef SSIZE_T ssize_t; +#endif /* json object int type, support extension*/ typedef enum json_object_int_type @@ -40,44 +44,60 @@ struct json_object { enum json_type o_type; uint32_t _ref_count; - json_object_private_delete_fn *_delete; json_object_to_json_string_fn *_to_json_string; struct printbuf *_pb; - union data - { - json_bool c_boolean; - double c_double; - struct - { - union - { - int64_t c_int64; - uint64_t c_uint64; - } cint; - enum json_object_int_type cint_type; - } c_int; - struct lh_table *c_object; - struct array_list *c_array; - struct - { - union - { - /* optimize: if we have small strings, we can store them - * directly. This saves considerable CPU cycles AND memory. - */ - char *ptr; - char data[LEN_DIRECT_STRING_DATA]; - } str; - int len; - } c_string; - } o; json_object_delete_fn *_user_delete; void *_userdata; + // Actually longer, always malloc'd as some more-specific type. + // The rest of a struct json_object_${o_type} follows +}; + +struct json_object_object +{ + struct json_object base; + struct lh_table *c_object; +}; +struct json_object_array +{ + struct json_object base; + struct array_list *c_array; +}; + +struct json_object_boolean +{ + struct json_object base; + json_bool c_boolean; +}; +struct json_object_double +{ + struct json_object base; + double c_double; +}; +struct json_object_int +{ + struct json_object base; + enum json_object_int_type cint_type; + union + { + int64_t c_int64; + uint64_t c_uint64; + } cint; +}; +struct json_object_string +{ + struct json_object base; + ssize_t len; // Signed b/c negative lengths indicate data is a pointer + // Consider adding an "alloc" field here, if json_object_set_string calls + // to expand the length of a string are common operations to perform. + union + { + char idata[1]; // Immediate data. Actually longer + char *pdata; // Only when len < 0 + } c_string; }; void _json_c_set_last_err(const char *err_fmt, ...); -extern const char *json_number_chars; extern const char *json_hex_chars; #ifdef __cplusplus diff --git a/json_tokener.c b/json_tokener.c index 0373d6f..aad463a 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -97,6 +97,8 @@ static const char *json_tokener_errors[] = { */ static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes); +static int json_tokener_parse_double(const char *buf, int len, double *retval); + const char *json_tokener_error_desc(enum json_tokener_error jerr) { int jerr_int = (int)jerr; @@ -132,6 +134,12 @@ struct json_tokener *json_tokener_new_ex(int depth) return NULL; } tok->pb = printbuf_new(); + if (!tok->pb) + { + free(tok); + free(tok->stack); + return NULL; + } tok->max_depth = depth; json_tokener_reset(tok); return tok; @@ -191,7 +199,17 @@ struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokene return NULL; obj = json_tokener_parse_ex(tok, str, -1); *error = tok->err; - if (tok->err != json_tokener_success) + if (tok->err != json_tokener_success +#if 0 + /* This would be a more sensible default, and cause parsing + * things like "null123" to fail when the caller can't know + * where the parsing left off, but starting to fail would + * be a notable behaviour change. Save for a 1.0 release. + */ + || json_tokener_get_parse_end(tok) != strlen(str) +#endif + ) + { if (obj != NULL) json_object_put(obj); @@ -223,7 +241,7 @@ struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokene /* PEEK_CHAR(dest, tok) macro: * Peeks at the current char and stores it in dest. * Returns 1 on success, sets tok->err and returns 0 if no more chars. - * Implicit inputs: str, len vars + * Implicit inputs: str, len, nBytesp vars */ #define PEEK_CHAR(dest, tok) \ (((tok)->char_offset == len) \ @@ -295,7 +313,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * } #endif - while (PEEK_CHAR(c, tok)) + while (PEEK_CHAR(c, tok)) // Note: c might be '\0' ! { redo_char: @@ -418,7 +436,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * { char inf_char = *str; if (!(tok->flags & JSON_TOKENER_STRICT)) - inf_char = tolower((int)*str); + inf_char = tolower((unsigned char)*str); if (inf_char != _json_inf_str[tok->st_pos]) { tok->err = json_tokener_error_parse_unexpected; @@ -628,173 +646,165 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * } break; + // =================================================== + case json_tokener_state_escape_unicode: { - unsigned int got_hi_surrogate = 0; - - /* Handle a 4-byte sequence, or two sequences if a surrogate pair */ + /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */ while (1) { - if (c && strchr(json_hex_chars, c)) - { - tok->ucs_char += ((unsigned int)jt_hexdigit(c) - << ((3 - tok->st_pos++) * 4)); - if (tok->st_pos == 4) - { - unsigned char unescaped_utf[4]; - - if (got_hi_surrogate) - { - if (IS_LOW_SURROGATE(tok->ucs_char)) - { - /* Recalculate the ucs_char, then fall thru to process normally */ - tok->ucs_char = - DECODE_SURROGATE_PAIR( - got_hi_surrogate, - tok->ucs_char); - } - else - { - /* Hi surrogate was not followed by a low surrogate */ - /* Replace the hi and process the rest normally */ - printbuf_memappend_fast( - tok->pb, - (char *)utf8_replacement_char, - 3); - } - got_hi_surrogate = 0; - } - - if (tok->ucs_char < 0x80) - { - unescaped_utf[0] = tok->ucs_char; - printbuf_memappend_fast( - tok->pb, (char *)unescaped_utf, 1); - } - else if (tok->ucs_char < 0x800) - { - unescaped_utf[0] = - 0xc0 | (tok->ucs_char >> 6); - unescaped_utf[1] = - 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend_fast( - tok->pb, (char *)unescaped_utf, 2); - } - else if (IS_HIGH_SURROGATE(tok->ucs_char)) - { - /* Got a high surrogate. Remember it and look for - * the beginning of another sequence, which - * should be the low surrogate. - */ - got_hi_surrogate = tok->ucs_char; - /* Not at end, and the next two chars should be "\u" */ - if ((len == -1 || - len > (tok->char_offset + 2)) && - // str[0] != '0' && // implied by json_hex_chars, above. - (str[1] == '\\') && (str[2] == 'u')) - { - /* Advance through the 16 bit surrogate, and move - * on to the next sequence. The next step is to - * process the following characters. - */ - if (!ADVANCE_CHAR(str, tok) || - !ADVANCE_CHAR(str, tok)) - { - printbuf_memappend_fast( - tok->pb, - (char *) - utf8_replacement_char, - 3); - } - /* Advance to the first char of the next sequence and - * continue processing with the next sequence. - */ - if (!ADVANCE_CHAR(str, tok) || - !PEEK_CHAR(c, tok)) - { - printbuf_memappend_fast( - tok->pb, - (char *) - utf8_replacement_char, - 3); - goto out; - } - tok->ucs_char = 0; - tok->st_pos = 0; - /* other json_tokener_state_escape_unicode */ - continue; - } - else - { - /* Got a high surrogate without another sequence following - * it. Put a replacement char in for the hi surrogate - * and pretend we finished. - */ - printbuf_memappend_fast( - tok->pb, - (char *)utf8_replacement_char, - 3); - } - } - else if (IS_LOW_SURROGATE(tok->ucs_char)) - { - /* Got a low surrogate not preceded by a high */ - printbuf_memappend_fast( - tok->pb, (char *)utf8_replacement_char, - 3); - } - else if (tok->ucs_char < 0x10000) - { - unescaped_utf[0] = - 0xe0 | (tok->ucs_char >> 12); - unescaped_utf[1] = - 0x80 | ((tok->ucs_char >> 6) & 0x3f); - unescaped_utf[2] = - 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend_fast( - tok->pb, (char *)unescaped_utf, 3); - } - else if (tok->ucs_char < 0x110000) - { - unescaped_utf[0] = - 0xf0 | ((tok->ucs_char >> 18) & 0x07); - unescaped_utf[1] = - 0x80 | ((tok->ucs_char >> 12) & 0x3f); - unescaped_utf[2] = - 0x80 | ((tok->ucs_char >> 6) & 0x3f); - unescaped_utf[3] = - 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend_fast( - tok->pb, (char *)unescaped_utf, 4); - } - else - { - /* Don't know what we got--insert the replacement char */ - printbuf_memappend_fast( - tok->pb, (char *)utf8_replacement_char, - 3); - } - state = saved_state; - break; - } - } - else + if (!c || !strchr(json_hex_chars, c)) { tok->err = json_tokener_error_parse_string; goto out; } - if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) + tok->ucs_char |= + ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4)); + tok->st_pos++; + if (tok->st_pos >= 4) + break; + + (void)ADVANCE_CHAR(str, tok); + if (!PEEK_CHAR(c, tok)) { - /* Clean up any pending chars */ - if (got_hi_surrogate) - printbuf_memappend_fast( - tok->pb, (char *)utf8_replacement_char, 3); + /* + * We're out of characters in the current call to + * json_tokener_parse(), but a subsequent call might + * provide us with more, so leave our current state + * as-is (including tok->high_surrogate) and return. + */ goto out; } } + tok->st_pos = 0; + + /* Now, we have a full \uNNNN sequence in tok->ucs_char */ + + /* If the *previous* sequence was a high surrogate ... */ + if (tok->high_surrogate) + { + if (IS_LOW_SURROGATE(tok->ucs_char)) + { + /* Recalculate the ucs_char, then fall thru to process normally */ + tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate, + tok->ucs_char); + } + else + { + /* High surrogate was not followed by a low surrogate + * Replace the high and process the rest normally + */ + printbuf_memappend_fast(tok->pb, + (char *)utf8_replacement_char, 3); + } + tok->high_surrogate = 0; + } + + if (tok->ucs_char < 0x80) + { + unsigned char unescaped_utf[1]; + unescaped_utf[0] = tok->ucs_char; + printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 1); + } + else if (tok->ucs_char < 0x800) + { + unsigned char unescaped_utf[2]; + unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6); + unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 2); + } + else if (IS_HIGH_SURROGATE(tok->ucs_char)) + { + /* + * The next two characters should be \u, HOWEVER, + * we can't simply peek ahead here, because the + * characters we need might not be passed to us + * until a subsequent call to json_tokener_parse. + * Instead, transition throug a couple of states. + * (now): + * _escape_unicode => _unicode_need_escape + * (see a '\\' char): + * _unicode_need_escape => _unicode_need_u + * (see a 'u' char): + * _unicode_need_u => _escape_unicode + * ...and we'll end up back around here. + */ + tok->high_surrogate = tok->ucs_char; + tok->ucs_char = 0; + state = json_tokener_state_escape_unicode_need_escape; + break; + } + else if (IS_LOW_SURROGATE(tok->ucs_char)) + { + /* Got a low surrogate not preceded by a high */ + printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3); + } + else if (tok->ucs_char < 0x10000) + { + unsigned char unescaped_utf[3]; + unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12); + unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); + unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 3); + } + else if (tok->ucs_char < 0x110000) + { + unsigned char unescaped_utf[4]; + unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07); + unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f); + unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); + unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 4); + } + else + { + /* Don't know what we got--insert the replacement char */ + printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3); + } + state = saved_state; // i.e. _state_string or _state_object_field } break; + case json_tokener_state_escape_unicode_need_escape: + // We get here after processing a high_surrogate + // require a '\\' char + if (!c || c != '\\') + { + /* Got a high surrogate without another sequence following + * it. Put a replacement char in for the high surrogate + * and pop back up to _state_string or _state_object_field. + */ + printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3); + tok->high_surrogate = 0; + tok->ucs_char = 0; + tok->st_pos = 0; + state = saved_state; + goto redo_char; + } + state = json_tokener_state_escape_unicode_need_u; + break; + + case json_tokener_state_escape_unicode_need_u: + /* We already had a \ char, check that it's \u */ + if (!c || c != 'u') + { + /* Got a high surrogate with some non-unicode escape + * sequence following it. + * Put a replacement char in for the high surrogate + * and handle the escape sequence normally. + */ + printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3); + tok->high_surrogate = 0; + tok->ucs_char = 0; + tok->st_pos = 0; + state = json_tokener_state_string_escape; + goto redo_char; + } + state = json_tokener_state_escape_unicode; + break; + + // =================================================== + case json_tokener_state_boolean: { int size1, size2; @@ -844,9 +854,38 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * const char *case_start = str; int case_len = 0; int is_exponent = 0; - int negativesign_next_possible_location = 1; - while (c && strchr(json_number_chars, c)) + int neg_sign_ok = 1; + int pos_sign_ok = 0; + if (printbuf_length(tok->pb) > 0) + { + /* We don't save all state from the previous incremental parse + so we need to re-generate it based on the saved string so far. + */ + char *e_loc = strchr(tok->pb->buf, 'e'); + if (!e_loc) + e_loc = strchr(tok->pb->buf, 'E'); + if (e_loc) + { + char *last_saved_char = + &tok->pb->buf[printbuf_length(tok->pb) - 1]; + is_exponent = 1; + pos_sign_ok = neg_sign_ok = 1; + /* If the "e" isn't at the end, we can't start with a '-' */ + if (e_loc != last_saved_char) + { + neg_sign_ok = 0; + pos_sign_ok = 0; + } + // else leave it set to 1, i.e. start of the new input + } + } + + while (c && ((c >= '0' && c <= '9') || + (!is_exponent && (c == 'e' || c == 'E')) || + (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') || + (!tok->is_double && c == '.'))) { + pos_sign_ok = neg_sign_ok = 0; ++case_len; /* non-digit characters checks */ @@ -855,40 +894,21 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * * protected from input starting with '.' or * e/E. */ - if (c == '.') + switch (c) { - if (tok->is_double != 0) - { - /* '.' can only be found once, and out of the exponent part. - * Thus, if the input is already flagged as double, it - * is invalid. - */ - tok->err = json_tokener_error_parse_number; - goto out; - } + case '.': tok->is_double = 1; - } - if (c == 'e' || c == 'E') - { - if (is_exponent != 0) - { - /* only one exponent possible */ - tok->err = json_tokener_error_parse_number; - goto out; - } + pos_sign_ok = 1; + neg_sign_ok = 1; + break; + case 'e': /* FALLTHRU */ + case 'E': is_exponent = 1; tok->is_double = 1; /* the exponent part can begin with a negative sign */ - negativesign_next_possible_location = case_len + 1; - } - if (c == '-' && case_len != negativesign_next_possible_location) - { - /* If the negative sign is not where expected (ie - * start of input or start of exponent part), the - * input is invalid. - */ - tok->err = json_tokener_error_parse_number; - goto out; + pos_sign_ok = neg_sign_ok = 1; + break; + default: break; } if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) @@ -897,6 +917,20 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * goto out; } } + /* + Now we know c isn't a valid number char, but check whether + it might have been intended to be, and return a potentially + more understandable error right away. + However, if we're at the top-level, use the number as-is + because c can be part of a new object to parse on the + next call to json_tokener_parse(). + */ + if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' && + c != 'I' && c != 'i' && !isspace((unsigned char)c)) + { + tok->err = json_tokener_error_parse_number; + goto out; + } if (case_len > 0) printbuf_memappend_fast(tok->pb, case_start, case_len); @@ -907,6 +941,22 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * tok->st_pos = 0; goto redo_char; } + if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT)) + { + /* Trim some chars off the end, to allow things + like "123e+" to parse ok. */ + while (printbuf_length(tok->pb) > 1) + { + char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1]; + if (last_char != 'e' && last_char != 'E' && + last_char != '-' && last_char != '+') + { + break; + } + tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0'; + printbuf_length(tok->pb)--; + } + } } { int64_t num64; @@ -943,7 +993,8 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * } } else if (tok->is_double && - json_parse_double(tok->pb->buf, &numd) == 0) + json_tokener_parse_double( + tok->pb->buf, printbuf_length(tok->pb), &numd) == 0) { current = json_object_new_double_s(numd, tok->pb->buf); if (current == NULL) @@ -964,6 +1015,9 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * case json_tokener_state_array: if (c == ']') { + // Minimize memory usage; assume parsed objs are unlikely to be changed + json_object_array_shrink(current, 0); + if (state == json_tokener_state_array_after_sep && (tok->flags & JSON_TOKENER_STRICT)) { @@ -997,6 +1051,9 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * case json_tokener_state_array_sep: if (c == ']') { + // Minimize memory usage; assume parsed objs are unlikely to be changed + json_object_array_shrink(current, 0); + saved_state = json_tokener_state_finish; state = json_tokener_state_eatws; } @@ -1122,8 +1179,9 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * } break; } - if (!ADVANCE_CHAR(str, tok)) - goto out; + (void)ADVANCE_CHAR(str, tok); + if (!c) // This is the char *before* advancing + break; } /* while(PEEK_CHAR) */ out: @@ -1132,7 +1190,8 @@ out: tok->err = json_tokener_error_parse_utf8_string; } if (c && (state == json_tokener_state_finish) && (tok->depth == 0) && - (tok->flags & (JSON_TOKENER_STRICT|JSON_TOKENER_ALLOW_TRAILING_CHARS)) == JSON_TOKENER_STRICT) + (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) == + JSON_TOKENER_STRICT) { /* unexpected char after JSON data */ tok->err = json_tokener_error_parse_unexpected; @@ -1204,3 +1263,12 @@ size_t json_tokener_get_parse_end(struct json_tokener *tok) assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */ return (size_t)tok->char_offset; } + +static int json_tokener_parse_double(const char *buf, int len, double *retval) +{ + char *end; + *retval = strtod(buf, &end); + if (buf + len == end) + return 0; // It worked + return 1; +} diff --git a/json_tokener.h b/json_tokener.h index ea49ad8..a07e12c 100644 --- a/json_tokener.h +++ b/json_tokener.h @@ -59,6 +59,8 @@ enum json_tokener_state json_tokener_state_string, json_tokener_state_string_escape, json_tokener_state_escape_unicode, + json_tokener_state_escape_unicode_need_escape, + json_tokener_state_escape_unicode_need_u, json_tokener_state_boolean, json_tokener_state_number, json_tokener_state_array, @@ -111,7 +113,7 @@ struct json_tokener * @deprecated See json_tokener_get_error() instead. */ enum json_tokener_error err; - unsigned int ucs_char; + unsigned int ucs_char, high_surrogate; char quote_char; struct json_tokener_srec *stack; int flags; @@ -194,11 +196,44 @@ JSON_EXPORT const char *json_tokener_error_desc(enum json_tokener_error jerr); */ JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); +/** + * Allocate a new json_tokener. + * When done using that to parse objects, free it with json_tokener_free(). + * See json_tokener_parse_ex() for usage details. + */ JSON_EXPORT struct json_tokener *json_tokener_new(void); + +/** + * Allocate a new json_tokener with a custom max nesting depth. + * @see JSON_TOKENER_DEFAULT_DEPTH + */ JSON_EXPORT struct json_tokener *json_tokener_new_ex(int depth); + +/** + * Free a json_tokener previously allocated with json_tokener_new(). + */ JSON_EXPORT void json_tokener_free(struct json_tokener *tok); + +/** + * Reset the state of a json_tokener, to prepare to parse a + * brand new JSON object. + */ JSON_EXPORT void json_tokener_reset(struct json_tokener *tok); + +/** + * Parse a json_object out of the string `str`. + * + * If you need more control over how the parsing occurs, + * see json_tokener_parse_ex(). + */ JSON_EXPORT struct json_object *json_tokener_parse(const char *str); + +/** + * Parser a json_object out of the string `str`, but if it fails + * return the error in `*error`. + * @see json_tokener_parse() + * @see json_tokener_parse_ex() + */ JSON_EXPORT struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error); @@ -220,8 +255,8 @@ JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags); * * If json_tokener_parse_ex() returns NULL and the error is anything other than * json_tokener_continue, a fatal error has occurred and parsing must be - * halted. Then, the tok object must not be reused until json_tokener_reset() is - * called. + * halted. Then, the tok object must not be reused until json_tokener_reset() + * is called. * * When a valid JSON value is parsed, a non-NULL json_object will be * returned, with a reference count of one which belongs to the caller. Also, @@ -234,13 +269,18 @@ JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags); * error or to handle the additional characters, perhaps by parsing another * json value starting from that point. * + * If the caller knows that they are at the end of their input, the length + * passed MUST include the final '\0' character, so values with no inherent + * end (i.e. numbers) can be properly parsed, rather than just returning + * json_tokener_continue. + * * Extra characters can be detected by comparing the value returned by * json_tokener_get_parse_end() against * the length of the last len parameter passed in. * * The tokener does \b not maintain an internal buffer so the caller is - * responsible for calling json_tokener_parse_ex with an appropriate str - * parameter starting with the extra characters. + * responsible for a subsequent call to json_tokener_parse_ex with an + * appropriate str parameter starting with the extra characters. * * This interface is presently not 64-bit clean due to the int len argument * so the function limits the maximum string size to INT32_MAX (2GB). @@ -256,6 +296,8 @@ enum json_tokener_error jerr; do { mystring = ... // get JSON string, e.g. read from file, etc... stringlen = strlen(mystring); + if (end_of_input) + stringlen++; // Include the '\0' if we know we're at the end of input jobj = json_tokener_parse_ex(tok, mystring, stringlen); } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue); if (jerr != json_tokener_success) diff --git a/json_types.h b/json_types.h index 67f4497..b7e55ad 100644 --- a/json_types.h +++ b/json_types.h @@ -18,7 +18,7 @@ extern "C" { #endif #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/json_util.c b/json_util.c index e8e2ec6..a065523 100644 --- a/json_util.c +++ b/json_util.c @@ -222,6 +222,7 @@ int json_object_to_file(const char *filename, struct json_object *obj) return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); } +// Deprecated json_parse_double function. See json_tokener_parse_double instead. int json_parse_double(const char *buf, double *retval) { char *end; @@ -250,7 +251,7 @@ int json_parse_uint64(const char *buf, uint64_t *retval) while (*buf == ' ') buf++; if (*buf == '-') - return 1; /* error: uint cannot be negative */ + return 1; /* error: uint cannot be negative */ val = strtoull(buf, &end, 10); if (end != buf) diff --git a/json_util.h b/json_util.h index 7520f03..1f663e8 100644 --- a/json_util.h +++ b/json_util.h @@ -103,6 +103,9 @@ JSON_EXPORT const char *json_util_get_last_err(void); /* these parsing helpers return zero on success */ JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval); JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval); +/** + * @deprecated + */ JSON_EXPORT int json_parse_double(const char *buf, double *retval); /** @@ -311,11 +311,11 @@ int lh_table_resize(struct lh_table *t, int new_size); /** * @deprecated Don't use this outside of linkhash.h: */ -#if !defined(_MSC_VER) || (_MSC_VER > 1800) +#if (defined(AIX_CC) || (defined(_MSC_VER) && (_MSC_VER <= 1800)) ) /* VS2010 can't handle inline funcs, so skip it there */ -#define _LH_INLINE inline -#else #define _LH_INLINE +#else +#define _LH_INLINE inline #endif /** @@ -24,7 +24,7 @@ #define _printbuf_h_ #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/random_seed.c b/random_seed.c index b5f8a07..f474e39 100644 --- a/random_seed.c +++ b/random_seed.c @@ -13,9 +13,23 @@ #include "config.h" #include "strerror_override.h" #include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_BSD_STDLIB_H +#include <bsd/stdlib.h> +#endif #define DEBUG_SEED(s) +#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) +#define HAVE_DEV_RANDOM 1 +#endif + +#ifdef HAVE_ARC4RANDOM +#undef HAVE_GETRANDOM +#undef HAVE_DEV_RANDOM +#undef HAVE_CRYPTGENRANDOM +#endif + #if defined ENABLE_RDRAND /* cpuid */ @@ -155,9 +169,45 @@ retry: #endif /* defined ENABLE_RDRAND */ -/* has_dev_urandom */ +#ifdef HAVE_GETRANDOM -#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) +#include <stdlib.h> +#ifdef HAVE_SYS_RANDOM_H +#include <sys/random.h> +#endif + +static int get_getrandom_seed(int *seed) +{ + DEBUG_SEED("get_getrandom_seed"); + + ssize_t ret; + + do + { + ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK); + } while ((ret == -1) && (errno == EINTR)); + + if (ret == -1) + { + if (errno == ENOSYS) /* syscall not available in kernel */ + return -1; + if (errno == EAGAIN) /* entropy not yet initialized */ + return -1; + + fprintf(stderr, "error from getrandom(): %s", strerror(errno)); + return -1; + } + + if (ret != sizeof(*seed)) + return -1; + + return 0; +} +#endif /* defined HAVE_GETRANDOM */ + +/* get_dev_random_seed */ + +#ifdef HAVE_DEV_RANDOM #include <fcntl.h> #include <string.h> @@ -167,43 +217,34 @@ retry: #include <stdlib.h> #include <sys/stat.h> -#define HAVE_DEV_RANDOM 1 - static const char *dev_random_file = "/dev/urandom"; -static int has_dev_urandom(void) +static int get_dev_random_seed(int *seed) { + DEBUG_SEED("get_dev_random_seed"); + struct stat buf; if (stat(dev_random_file, &buf)) - { - return 0; - } - return ((buf.st_mode & S_IFCHR) != 0); -} - -/* get_dev_random_seed */ - -static int get_dev_random_seed(void) -{ - DEBUG_SEED("get_dev_random_seed"); + return -1; + if ((buf.st_mode & S_IFCHR) == 0) + return -1; int fd = open(dev_random_file, O_RDONLY); if (fd < 0) { fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno)); - exit(1); + return -1; } - int r; - ssize_t nread = read(fd, &r, sizeof(r)); - if (nread != sizeof(r)) + ssize_t nread = read(fd, seed, sizeof(*seed)); + if (nread != sizeof(*seed)) { fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno)); - exit(1); + return -1; } close(fd); - return r; + return 0; } #endif @@ -226,58 +267,87 @@ static int get_dev_random_seed(void) #pragma comment(lib, "advapi32.lib") #endif -static int get_cryptgenrandom_seed(void) +static int get_cryptgenrandom_seed(int *seed) { HCRYPTPROV hProvider = 0; - int r; + DWORD dwFlags = CRYPT_VERIFYCONTEXT; DEBUG_SEED("get_cryptgenrandom_seed"); - if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + /* WinNT 4 and Win98 do no support CRYPT_SILENT */ + if (LOBYTE(LOWORD(GetVersion())) > 4) + dwFlags |= CRYPT_SILENT; + + if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags)) { - fprintf(stderr, "error CryptAcquireContextW"); - exit(1); + fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError()); + return -1; } - - if (!CryptGenRandom(hProvider, sizeof(r), (BYTE *)&r)) + else { - fprintf(stderr, "error CryptGenRandom"); - exit(1); + BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed); + CryptReleaseContext(hProvider, 0); + if (!ret) + { + fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError()); + return -1; + } } - CryptReleaseContext(hProvider, 0); - - return r; + return 0; } #endif /* get_time_seed */ +#ifndef HAVE_ARC4RANDOM #include <time.h> static int get_time_seed(void) { DEBUG_SEED("get_time_seed"); - return (int)time(NULL) * 433494437; + return (unsigned)time(NULL) * 433494437; } +#endif /* json_c_get_random_seed */ int json_c_get_random_seed(void) { +#ifdef OVERRIDE_GET_RANDOM_SEED + OVERRIDE_GET_RANDOM_SEED; +#endif #if defined HAVE_RDRAND && HAVE_RDRAND if (has_rdrand()) return get_rdrand_seed(); #endif +#ifdef HAVE_ARC4RANDOM + /* arc4random never fails, so use it if it's available */ + return arc4random(); +#else +#ifdef HAVE_GETRANDOM + { + int seed; + if (get_getrandom_seed(&seed) == 0) + return seed; + } +#endif #if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM - if (has_dev_urandom()) - return get_dev_random_seed(); + { + int seed; + if (get_dev_random_seed(&seed) == 0) + return seed; + } #endif #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM - return get_cryptgenrandom_seed(); + { + int seed; + if (get_cryptgenrandom_seed(&seed) == 0) + return seed; + } #endif return get_time_seed(); +#endif /* !HAVE_ARC4RANDOM */ } diff --git a/strerror_override.c b/strerror_override.c index a93be38..a3dd377 100644 --- a/strerror_override.c +++ b/strerror_override.c @@ -59,7 +59,8 @@ static struct /* clang-format on */ // Enabled during tests -int _json_c_strerror_enable = 0; +static int _json_c_strerror_enable = 0; +extern char *getenv(const char *name); // Avoid including stdlib.h #define PREFIX "ERRNO=" static char errno_buf[128] = PREFIX; @@ -70,6 +71,8 @@ char *_json_c_strerror(int errno_in) int ii, jj; if (!_json_c_strerror_enable) + _json_c_strerror_enable = (getenv("_JSON_C_STRERROR_ENABLE") == NULL) ? -1 : 1; + if (_json_c_strerror_enable == -1) return strerror(errno_in); // Avoid standard functions, so we don't need to include any @@ -91,7 +94,7 @@ char *_json_c_strerror(int errno_in) } // It's not one of the known errno values, return the numeric value. - for (ii = 0; errno_in > 10; errno_in /= 10, ii++) + for (ii = 0; errno_in >= 10; errno_in /= 10, ii++) { digbuf[ii] = "0123456789"[(errno_in % 10)]; } @@ -102,5 +105,6 @@ char *_json_c_strerror(int errno_in) { errno_buf[start_idx] = digbuf[ii]; } + errno_buf[start_idx] = '\0'; return errno_buf; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a871573..d7abf51 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,31 +12,41 @@ target_link_libraries(test2Formatted PRIVATE ${PROJECT_NAME}) include_directories(PUBLIC ${CMAKE_SOURCE_DIR}) -foreach(TESTNAME - test1 - test2 - test4 - testReplaceExisting - test_cast - test_charcase - test_compare - test_deep_copy - test_double_serializer - test_float - test_int_add - test_json_pointer - test_locale - test_null - test_parse - test_parse_int64 - test_printbuf - test_set_serializer - test_set_value - test_util_file - test_visit - test_object_iterator) +set(ALL_TEST_NAMES + test1 + test2 + test4 + testReplaceExisting + test_cast + test_charcase + test_compare + test_deep_copy + test_double_serializer + test_float + test_int_add + test_locale + test_null + test_parse + test_parse_int64 + test_printbuf + test_set_serializer + test_set_value + test_strerror + test_util_file + test_visit + test_object_iterator) + +if (NOT DISABLE_JSON_POINTER) + set(ALL_TEST_NAMES ${ALL_TEST_NAMES} test_json_pointer) +endif() + +foreach(TESTNAME ${ALL_TEST_NAMES}) add_executable(${TESTNAME} ${TESTNAME}.c) +if(${TESTNAME} STREQUAL test_strerror OR ${TESTNAME} STREQUAL test_util_file) +# For output consistency, we need _json_c_strerror() in some tests: +target_sources(${TESTNAME} PRIVATE ../strerror_override.c) +endif() add_test(NAME ${TESTNAME} COMMAND ${PROJECT_SOURCE_DIR}/tests/${TESTNAME}.test) # XXX using the non-target_ versions of these doesn't work :( diff --git a/tests/test1.c b/tests/test1.c index 98546bf..4d29601 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -1,9 +1,12 @@ #include <assert.h> +#include <limits.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "config.h" + #include "json.h" #include "parse_flags.h" @@ -250,7 +253,7 @@ int main(int argc, char **argv) test_array_del_idx(); test_array_list_expand_internal(); - my_array = json_object_new_array(); + my_array = json_object_new_array_ext(5); json_object_array_add(my_array, json_object_new_int(3)); json_object_array_add(my_array, json_object_new_int(1)); json_object_array_add(my_array, json_object_new_int(2)); @@ -307,6 +310,27 @@ int main(int argc, char **argv) } printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); + json_object_put(my_array); + my_array = json_object_new_array_ext(INT_MIN + 1); + if (my_array != NULL) + { + printf("ERROR: able to allocate an array of negative size!\n"); + fflush(stdout); + json_object_put(my_array); + my_array = NULL; + } + +#if SIZEOF_SIZE_T == SIZEOF_INT + my_array = json_object_new_array_ext(INT_MAX / 2 + 2); + if (my_array != NULL) + { + printf("ERROR: able to allocate an array of insufficient size!\n"); + fflush(stdout); + json_object_put(my_array); + my_array = NULL; + } +#endif + json_object_put(my_string); json_object_put(my_int); json_object_put(my_null); diff --git a/tests/test_basic.test b/tests/test_basic.test index 154e036..474e7a8 100755 --- a/tests/test_basic.test +++ b/tests/test_basic.test @@ -1,5 +1,7 @@ #!/bin/sh +export _JSON_C_STRERROR_ENABLE=1 + # Common definitions if test -z "$srcdir"; then srcdir="${0%/*}" diff --git a/tests/test_cast.c b/tests/test_cast.c index fb63e0d..fc769f5 100644 --- a/tests/test_cast.c +++ b/tests/test_cast.c @@ -28,6 +28,11 @@ int main(int argc, char **argv) \"int64_number\": 2147483649,\n\ \"negative_number\": -321321321,\n\ \"a_null\": null,\n\ + \"empty_array\": [],\n\ + \"nonempty_array\": [ 123 ],\n\ + \"array_with_zero\": [ 0 ],\n\ + \"empty_object\": {},\n\ + \"nonempty_object\": { \"a\": 123 },\n\ }"; /* Note: 2147483649 = INT_MAX + 2 */ /* Note: 9223372036854775809 = INT64_MAX + 2 */ @@ -49,6 +54,11 @@ int main(int argc, char **argv) getit(new_obj, "int64_number"); getit(new_obj, "negative_number"); getit(new_obj, "a_null"); + getit(new_obj, "empty_array"); + getit(new_obj, "nonempty_array"); + getit(new_obj, "array_with_zero"); + getit(new_obj, "empty_object"); + getit(new_obj, "nonempty_object"); // Now check the behaviour of the json_object_is_type() function. printf("\n================================\n"); diff --git a/tests/test_cast.expected b/tests/test_cast.expected index 347d540..6a19de9 100644 --- a/tests/test_cast.expected +++ b/tests/test_cast.expected @@ -7,6 +7,11 @@ Parsed input: { "int64_number": 2147483649, "negative_number": -321321321, "a_null": null, + "empty_array": [], + "nonempty_array": [ 123 ], + "array_with_zero": [ 0 ], + "empty_object": {}, + "nonempty_object": { "a": 123 }, } Result is not NULL new_obj.string_of_digits json_object_get_type()=string @@ -57,6 +62,36 @@ new_obj.a_null json_object_get_int64()=0 new_obj.a_null json_object_get_uint64()=0 new_obj.a_null json_object_get_boolean()=0 new_obj.a_null json_object_get_double()=0.000000 +new_obj.empty_array json_object_get_type()=array +new_obj.empty_array json_object_get_int()=0 +new_obj.empty_array json_object_get_int64()=0 +new_obj.empty_array json_object_get_uint64()=0 +new_obj.empty_array json_object_get_boolean()=0 +new_obj.empty_array json_object_get_double()=0.000000 +new_obj.nonempty_array json_object_get_type()=array +new_obj.nonempty_array json_object_get_int()=0 +new_obj.nonempty_array json_object_get_int64()=0 +new_obj.nonempty_array json_object_get_uint64()=0 +new_obj.nonempty_array json_object_get_boolean()=0 +new_obj.nonempty_array json_object_get_double()=0.000000 +new_obj.array_with_zero json_object_get_type()=array +new_obj.array_with_zero json_object_get_int()=0 +new_obj.array_with_zero json_object_get_int64()=0 +new_obj.array_with_zero json_object_get_uint64()=0 +new_obj.array_with_zero json_object_get_boolean()=0 +new_obj.array_with_zero json_object_get_double()=0.000000 +new_obj.empty_object json_object_get_type()=object +new_obj.empty_object json_object_get_int()=0 +new_obj.empty_object json_object_get_int64()=0 +new_obj.empty_object json_object_get_uint64()=0 +new_obj.empty_object json_object_get_boolean()=0 +new_obj.empty_object json_object_get_double()=0.000000 +new_obj.nonempty_object json_object_get_type()=object +new_obj.nonempty_object json_object_get_int()=0 +new_obj.nonempty_object json_object_get_int64()=0 +new_obj.nonempty_object json_object_get_uint64()=0 +new_obj.nonempty_object json_object_get_boolean()=0 +new_obj.nonempty_object json_object_get_double()=0.000000 ================================ json_object_is_type: null,boolean,double,int,object,array,string diff --git a/tests/test_deep_copy.c b/tests/test_deep_copy.c index b6c1b99..34ef1fe 100644 --- a/tests/test_deep_copy.c +++ b/tests/test_deep_copy.c @@ -126,7 +126,7 @@ int main(int argc, char **argv) src3 = json_tokener_parse(json_str3); assert(src1 != NULL); - assert(src1 != NULL); + assert(src2 != NULL); assert(src3 != NULL); printf("PASSED - loaded input data\n"); diff --git a/tests/test_double_serializer.c b/tests/test_double_serializer.c index 71ec8ec..8b2487a 100644 --- a/tests/test_double_serializer.c +++ b/tests/test_double_serializer.c @@ -59,6 +59,7 @@ int main() #else // Just fake it up, so the output matches. printf("obj.to_string(with thread format)=%s\n", "T0.52X"); + printf("obj.to_string(long thread format)=%s\n", "Ttttttttttttt0.52xxxxxxxxxxxxxxxxxxX"); printf("obj.to_string(back to global format)=%s\n", "x0.524y"); #endif if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_GLOBAL) < 0) diff --git a/tests/test_json_pointer.c b/tests/test_json_pointer.c index 34fa202..3174c87 100644 --- a/tests/test_json_pointer.c +++ b/tests/test_json_pointer.c @@ -1,9 +1,8 @@ -#include "strerror_override.h" -#include "strerror_override_private.h" #ifdef NDEBUG #undef NDEBUG #endif #include <assert.h> +#include <errno.h> #include <stdio.h> #include <string.h> @@ -320,8 +319,6 @@ static void test_wrong_inputs_set(void) int main(int argc, char **argv) { - _json_c_strerror_enable = 1; - test_example_get(); test_recursion_get(); test_wrong_inputs_get(); diff --git a/tests/test_parse.c b/tests/test_parse.c index 6014ac1..5363f32 100644 --- a/tests/test_parse.c +++ b/tests/test_parse.c @@ -33,6 +33,52 @@ int main(void) static json_c_visit_userfunc clear_serializer; static void do_clear_serializer(json_object *jso); +static void single_incremental_parse(const char *test_string, int clear_serializer) +{ + int ii; + int chunksize = atoi(getenv("TEST_PARSE_CHUNKSIZE")); + struct json_tokener *tok; + enum json_tokener_error jerr; + json_object *all_at_once_obj, *new_obj; + const char *all_at_once_str, *new_str; + + assert(chunksize > 0); + all_at_once_obj = json_tokener_parse(test_string); + if (clear_serializer) + do_clear_serializer(all_at_once_obj); + all_at_once_str = json_object_to_json_string(all_at_once_obj); + + tok = json_tokener_new(); + int test_string_len = strlen(test_string) + 1; // Including '\0' ! + for (ii = 0; ii < test_string_len; ii += chunksize) + { + int len_to_parse = chunksize; + if (ii + chunksize > test_string_len) + len_to_parse = test_string_len - ii; + + if (getenv("TEST_PARSE_DEBUG") != NULL) + printf(" chunk: %.*s\n", len_to_parse, &test_string[ii]); + new_obj = json_tokener_parse_ex(tok, &test_string[ii], len_to_parse); + jerr = json_tokener_get_error(tok); + if (jerr != json_tokener_continue || new_obj) + break; + } + if (clear_serializer && new_obj) + do_clear_serializer(new_obj); + new_str = json_object_to_json_string(new_obj); + + if (strcmp(all_at_once_str, new_str) != 0) + { + printf("ERROR: failed to parse (%s) in %d byte chunks: %s != %s\n", test_string, + chunksize, all_at_once_str, new_str); + } + json_tokener_free(tok); + if (all_at_once_obj) + json_object_put(all_at_once_obj); + if (new_obj) + json_object_put(new_obj); +} + static void single_basic_parse(const char *test_string, int clear_serializer) { json_object *new_obj; @@ -42,6 +88,9 @@ static void single_basic_parse(const char *test_string, int clear_serializer) do_clear_serializer(new_obj); printf("new_obj.to_string(%s)=%s\n", test_string, json_object_to_json_string(new_obj)); json_object_put(new_obj); + + if (getenv("TEST_PARSE_CHUNKSIZE") != NULL) + single_incremental_parse(test_string, clear_serializer); } static void test_basic_parse() { @@ -93,16 +142,18 @@ static void test_basic_parse() single_basic_parse("12", 0); single_basic_parse("12.3", 0); - single_basic_parse("12.3.4", 0); /* non-sensical, returns null */ - /* was returning (int)2015 before patch, should return null */ - single_basic_parse("2015-01-15", 0); - /* ...but this works. It's rather inconsistent, and a future major release - * should change the behavior so it either always returns null when extra - * bytes are present (preferred), or always return object created from as much - * as was able to be parsed. + /* Even though, when using json_tokener_parse() there's no way to + * know when there is more data after the parsed object, + * an object is successfully returned anyway (in some cases) */ + + single_basic_parse("12.3.4", 0); + single_basic_parse("2015-01-15", 0); single_basic_parse("12.3xxx", 0); + single_basic_parse("12.3{\"a\":123}", 0); + single_basic_parse("12.3\n", 0); + single_basic_parse("12.3 ", 0); single_basic_parse("{\"FoO\" : -12.3E512}", 0); single_basic_parse("{\"FoO\" : -12.3e512}", 0); @@ -149,8 +200,8 @@ static void test_utf8_parse() // json_tokener_parse doesn't support checking for byte order marks. // It's the responsibility of the caller to detect and skip a BOM. // Both of these checks return null. - char* utf8_bom = "\xEF\xBB\xBF"; - char* utf8_bom_and_chars = "\xEF\xBB\xBF{}"; + char *utf8_bom = "\xEF\xBB\xBF"; + char *utf8_bom_and_chars = "\xEF\xBB\xBF{}"; single_basic_parse(utf8_bom, 0); single_basic_parse(utf8_bom_and_chars, 0); } @@ -201,7 +252,7 @@ struct incremental_step int char_offset; enum json_tokener_error expected_error; int reset_tokener; /* Set to 1 to call json_tokener_reset() after parsing */ - int tok_flags; /* JSON_TOKENER_* flags to pass to json_tokener_set_flags() */ + int tok_flags; /* JSON_TOKENER_* flags to pass to json_tokener_set_flags() */ } incremental_steps[] = { /* Check that full json messages can be parsed, both w/ and w/o a reset */ @@ -224,6 +275,49 @@ struct incremental_step {"\": {\"bar", -1, -1, json_tokener_continue, 0}, {"\":13}}", -1, -1, json_tokener_success, 1}, + /* Check the UTF-16 surrogate pair handling in various ways. + * Note: \ud843\udd1e is u+1D11E, Musical Symbol G Clef + * Your terminal may not display these correctly, in particular + * PuTTY doesn't currently show this character. + */ + /* parse one char at every time */ + {"\"\\", -1, -1, json_tokener_continue, 0}, + {"u", -1, -1, json_tokener_continue, 0}, + {"d", -1, -1, json_tokener_continue, 0}, + {"8", -1, -1, json_tokener_continue, 0}, + {"3", -1, -1, json_tokener_continue, 0}, + {"4", -1, -1, json_tokener_continue, 0}, + {"\\", -1, -1, json_tokener_continue, 0}, + {"u", -1, -1, json_tokener_continue, 0}, + {"d", -1, -1, json_tokener_continue, 0}, + {"d", -1, -1, json_tokener_continue, 0}, + {"1", -1, -1, json_tokener_continue, 0}, + {"e\"", -1, -1, json_tokener_success, 1}, + /* parse two char at every time */ + {"\"\\u", -1, -1, json_tokener_continue, 0}, + {"d8", -1, -1, json_tokener_continue, 0}, + {"34", -1, -1, json_tokener_continue, 0}, + {"\\u", -1, -1, json_tokener_continue, 0}, + {"dd", -1, -1, json_tokener_continue, 0}, + {"1e\"", -1, -1, json_tokener_success, 1}, + /* check the low surrogate pair */ + {"\"\\ud834", -1, -1, json_tokener_continue, 0}, + {"\\udd1e\"", -1, -1, json_tokener_success, 1}, + {"\"\\ud834\\", -1, -1, json_tokener_continue, 0}, + {"udd1e\"", -1, -1, json_tokener_success, 1}, + {"\"\\ud834\\u", -1, -1, json_tokener_continue, 0}, + {"dd1e\"", -1, -1, json_tokener_success, 1}, + {"\"fff \\ud834\\ud", -1, -1, json_tokener_continue, 0}, + {"d1e bar\"", -1, -1, json_tokener_success, 1}, + {"\"fff \\ud834\\udd", -1, -1, json_tokener_continue, 0}, + {"1e bar\"", -1, -1, json_tokener_success, 1}, + + /* \ud83d\ude00 is U+1F600, Grinning Face + * Displays fine in PuTTY, though you may need "less -r" + */ + {"\"fff \\ud83d\\ude", -1, -1, json_tokener_continue, 0}, + {"00 bar\"", -1, -1, json_tokener_success, 1}, + /* Check that json_tokener_reset actually resets */ {"{ \"foo", -1, -1, json_tokener_continue, 1}, {": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1}, @@ -239,19 +333,49 @@ struct incremental_step {"\"Y\"", -1, -1, json_tokener_success, 1}, /* Trailing characters should cause a failure in strict mode */ - {"{\"foo\":9}{\"bar\":8}", -1, 9, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, + {"{\"foo\":9}{\"bar\":8}", -1, 9, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, /* ... unless explicitly allowed. */ - {"{\"foo\":9}{\"bar\":8}", -1, 9, json_tokener_success, 0, JSON_TOKENER_STRICT|JSON_TOKENER_ALLOW_TRAILING_CHARS }, - {"{\"b\":8}ignored garbage", -1, 7, json_tokener_success, 1, JSON_TOKENER_STRICT|JSON_TOKENER_ALLOW_TRAILING_CHARS }, + {"{\"foo\":9}{\"bar\":8}", -1, 9, json_tokener_success, 0, + JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS}, + {"{\"b\":8}ignored garbage", -1, 7, json_tokener_success, 1, + JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS}, /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */ {"1", 1, 1, json_tokener_continue, 0}, /* This should parse as the number 12, since it continues the "1" */ {"2", 2, 1, json_tokener_success, 0}, {"12{", 3, 2, json_tokener_success, 1}, - /* Parse number in strict model */ - {"[02]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT }, + /* Parse number in strict mode */ + {"[02]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, + + {"0e+0", 5, 4, json_tokener_success, 1}, + {"[0e+0]", -1, -1, json_tokener_success, 1}, + + /* The behavior when missing the exponent varies slightly */ + {"0e", 2, 2, json_tokener_continue, 1}, + {"0e", 3, 2, json_tokener_success, 1}, + {"0e", 3, 2, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT}, + {"[0e]", -1, -1, json_tokener_success, 1}, + {"[0e]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, + + {"0e+", 3, 3, json_tokener_continue, 1}, + {"0e+", 4, 3, json_tokener_success, 1}, + {"0e+", 4, 3, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT}, + {"[0e+]", -1, -1, json_tokener_success, 1}, + {"[0e+]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, + + {"0e-", 3, 3, json_tokener_continue, 1}, + {"0e-", 4, 3, json_tokener_success, 1}, + {"0e-", 4, 3, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT}, + {"[0e-]", -1, -1, json_tokener_success, 1}, + {"[0e-]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, + + /* You might expect this to fail, but it won't because + it's a valid partial parse; note the char_offset: */ + {"0e+-", 5, 3, json_tokener_success, 1}, + {"0e+-", 5, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, + {"[0e+-]", -1, 4, json_tokener_error_parse_number, 1}, /* Similar tests for other kinds of objects: */ /* These could all return success immediately, since regardless of @@ -267,8 +391,8 @@ struct incremental_step {"Infinity", 9, 8, json_tokener_success, 1}, {"infinity", 9, 8, json_tokener_success, 1}, {"-infinity", 10, 9, json_tokener_success, 1}, - {"infinity", 9, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, - {"-infinity", 10, 1, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, + {"infinity", 9, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, + {"-infinity", 10, 1, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, {"inf", 3, 3, json_tokener_continue, 0}, {"inity", 6, 5, json_tokener_success, 1}, @@ -322,15 +446,29 @@ struct incremental_step * the next few tests check that parsing multiple sequential * json objects in the input works as expected */ - {"null123", 9, 4, json_tokener_success, 0}, + {"null123", 8, 4, json_tokener_success, 0}, {&"null123"[4], 4, 3, json_tokener_success, 1}, - {"nullx", 5, 4, json_tokener_success, 0}, + {"nullx", 6, 4, json_tokener_success, 0}, {&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1}, {"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0}, {&"{\"a\":1}{\"b\":2}"[7], 8, 7, json_tokener_success, 1}, - /* Some bad formatting. Check we get the correct error status */ - {"2015-01-15", 10, 4, json_tokener_error_parse_number, 1}, + /* + * Though this may seem invalid at first glance, it + * parses as three separate numbers, 2015, -1 and -15 + * Of course, simply pasting together a stream of arbitrary + * positive numbers won't work, since there'll be no way to + * tell where in e.g. "2015015" the next number stats, so + * a reliably parsable stream must not include json_type_int + * or json_type_double objects without some other delimiter. + * e.g. whitespace + */ + {&"2015-01-15"[0], 11, 4, json_tokener_success, 1}, + {&"2015-01-15"[4], 7, 3, json_tokener_success, 1}, + {&"2015-01-15"[7], 4, 3, json_tokener_success, 1}, + {&"2015 01 15"[0], 11, 5, json_tokener_success, 1}, + {&"2015 01 15"[4], 7, 4, json_tokener_success, 1}, + {&"2015 01 15"[7], 4, 3, json_tokener_success, 1}, /* Strings have a well defined end point, so we can stop at the quote */ {"\"blue\"", -1, -1, json_tokener_success, 0}, @@ -350,7 +488,7 @@ struct incremental_step {"\"\\a\"", -1, 2, json_tokener_error_parse_string, 1}, /* Check '\'' in strict model */ - {"\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, + {"\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, /* Parse array/object */ {"[1,2,3]", -1, -1, json_tokener_success, 0}, @@ -372,42 +510,54 @@ struct incremental_step {"[1,2,3,]", -1, -1, json_tokener_success, 0}, {"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0}, - {"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, - {"{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT }, + {"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, + {"{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT}, // utf-8 test // acsll encoding - {"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 1, + JSON_TOKENER_VALIDATE_UTF8}, {"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 1}, // utf-8 encoding - {"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x22\xe4\xb8", -1, 3, json_tokener_error_parse_utf8_string, 0, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x96\xe7\x95\x8c\x22", -1, 0, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 1, + JSON_TOKENER_VALIDATE_UTF8}, + {"\x22\xe4\xb8", -1, 3, json_tokener_error_parse_utf8_string, 0, JSON_TOKENER_VALIDATE_UTF8}, + {"\x96\xe7\x95\x8c\x22", -1, 0, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, {"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 1}, - {"\x22\xcf\x80\xcf\x86\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x22\xf0\xa5\x91\x95\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\xcf\x80\xcf\x86\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8}, + {"\x22\xf0\xa5\x91\x95\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8}, // wrong utf-8 encoding - {"\x22\xe6\x9d\x4e\x22", -1, 3, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\xe6\x9d\x4e\x22", -1, 3, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, {"\x22\xe6\x9d\x4e\x22", -1, 5, json_tokener_success, 1}, // GBK encoding - {"\x22\xc0\xee\xc5\xf4\x22", -1, 2, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\xc0\xee\xc5\xf4\x22", -1, 2, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, {"\x22\xc0\xee\xc5\xf4\x22", -1, 6, json_tokener_success, 1}, // char after space - {"\x20\x20\x22\xe4\xb8\x96\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x20\x20\x81\x22\xe4\xb8\x96\x22", -1, 2, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x5b\x20\x81\x31\x5d", -1, 2, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x20\x20\x22\xe4\xb8\x96\x22", -1, -1, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8}, + {"\x20\x20\x81\x22\xe4\xb8\x96\x22", -1, 2, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, + {"\x5b\x20\x81\x31\x5d", -1, 2, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, // char in state inf {"\x49\x6e\x66\x69\x6e\x69\x74\x79", 9, 8, json_tokener_success, 1}, - {"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, // char in escape unicode - {"\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22", 15, 14, json_tokener_success, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22", 15, 14, json_tokener_success, 1, + JSON_TOKENER_VALIDATE_UTF8}, {"\x22\x5c\x75\x64\x38\x35\x35\xc0\x75\x64\x63\x35\x35\x22", -1, 8, - json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, - {"\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22", -1, 9, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8}, + {"\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22", -1, 9, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, // char in number - {"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, // char in object - {"\x7b\x22\x31\x81\x22\x3a\x31\x7d", -1, 3, json_tokener_error_parse_utf8_string, 1, JSON_TOKENER_VALIDATE_UTF8 }, + {"\x7b\x22\x31\x81\x22\x3a\x31\x7d", -1, 3, json_tokener_error_parse_utf8_string, 1, + JSON_TOKENER_VALIDATE_UTF8}, {NULL, -1, -1, json_tokener_success, 0}, }; diff --git a/tests/test_parse.expected b/tests/test_parse.expected index 77e8be1..37db44d 100644 --- a/tests/test_parse.expected +++ b/tests/test_parse.expected @@ -40,9 +40,13 @@ new_obj.to_string(nAn)=NaN new_obj.to_string(iNfinity)=Infinity new_obj.to_string(12)=12 new_obj.to_string(12.3)=12.3 -new_obj.to_string(12.3.4)=null -new_obj.to_string(2015-01-15)=null +new_obj.to_string(12.3.4)=12.3 +new_obj.to_string(2015-01-15)=2015 new_obj.to_string(12.3xxx)=12.3 +new_obj.to_string(12.3{"a":123})=12.3 +new_obj.to_string(12.3 +)=12.3 +new_obj.to_string(12.3 )=12.3 new_obj.to_string({"FoO" : -12.3E512})={ "FoO": -12.3E512 } new_obj.to_string({"FoO" : -12.3e512})={ "FoO": -12.3e512 } new_obj.to_string({"FoO" : -12.3E51.2})=null @@ -100,6 +104,36 @@ json_tokener_parse_ex(tok, // hello"foo", 13) ... OK: got correct error: contin json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue json_tokener_parse_ex(tok, ":13}} , 6) ... OK: got object of type [object]: { "foo": { "bar": 13 } } +json_tokener_parse_ex(tok, "\ , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, u , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, d , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 8 , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 3 , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 4 , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, \ , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, u , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, d , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, d , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue +json_tokener_parse_ex(tok, e" , 2) ... OK: got object of type [string]: "ð„ž" +json_tokener_parse_ex(tok, "\u , 3) ... OK: got correct error: continue +json_tokener_parse_ex(tok, d8 , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 34 , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, \u , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, dd , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 1e" , 3) ... OK: got object of type [string]: "ð„ž" +json_tokener_parse_ex(tok, "\ud834 , 7) ... OK: got correct error: continue +json_tokener_parse_ex(tok, \udd1e" , 7) ... OK: got object of type [string]: "ð„ž" +json_tokener_parse_ex(tok, "\ud834\ , 8) ... OK: got correct error: continue +json_tokener_parse_ex(tok, udd1e" , 6) ... OK: got object of type [string]: "ð„ž" +json_tokener_parse_ex(tok, "\ud834\u , 9) ... OK: got correct error: continue +json_tokener_parse_ex(tok, dd1e" , 5) ... OK: got object of type [string]: "ð„ž" +json_tokener_parse_ex(tok, "fff \ud834\ud, 14) ... OK: got correct error: continue +json_tokener_parse_ex(tok, d1e bar" , 8) ... OK: got object of type [string]: "fff ð„ž bar" +json_tokener_parse_ex(tok, "fff \ud834\udd, 15) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 1e bar" , 7) ... OK: got object of type [string]: "fff ð„ž bar" +json_tokener_parse_ex(tok, "fff \ud83d\ude, 15) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 00 bar" , 7) ... OK: got object of type [string]: "fff 😀 bar" json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue json_tokener_parse_ex(tok, : "bar"} , 8) ... OK: got correct error: unexpected character json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue @@ -115,6 +149,26 @@ json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continu json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12 json_tokener_parse_ex(tok, 12{ , 3) ... OK: got object of type [int]: 12 json_tokener_parse_ex(tok, [02] , 4) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, 0e+0 , 5) ... OK: got object of type [double]: 0e+0 +json_tokener_parse_ex(tok, [0e+0] , 6) ... OK: got object of type [array]: [ 0e+0 ] +json_tokener_parse_ex(tok, 0e , 2) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 0e , 3) ... OK: got object of type [double]: 0 +json_tokener_parse_ex(tok, 0e , 3) ... OK: got correct error: unexpected end of data +json_tokener_parse_ex(tok, [0e] , 4) ... OK: got object of type [array]: [ 0 ] +json_tokener_parse_ex(tok, [0e] , 4) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, 0e+ , 3) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 0e+ , 4) ... OK: got object of type [double]: 0 +json_tokener_parse_ex(tok, 0e+ , 4) ... OK: got correct error: unexpected end of data +json_tokener_parse_ex(tok, [0e+] , 5) ... OK: got object of type [array]: [ 0 ] +json_tokener_parse_ex(tok, [0e+] , 5) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, 0e- , 3) ... OK: got correct error: continue +json_tokener_parse_ex(tok, 0e- , 4) ... OK: got object of type [double]: 0 +json_tokener_parse_ex(tok, 0e- , 4) ... OK: got correct error: unexpected end of data +json_tokener_parse_ex(tok, [0e-] , 5) ... OK: got object of type [array]: [ 0 ] +json_tokener_parse_ex(tok, [0e-] , 5) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, 0e+- , 5) ... OK: got object of type [double]: 0 +json_tokener_parse_ex(tok, 0e+- , 5) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, [0e+-] , 6) ... OK: got correct error: number expected json_tokener_parse_ex(tok, false , 5) ... OK: got correct error: continue json_tokener_parse_ex(tok, false , 6) ... OK: got object of type [boolean]: false json_tokener_parse_ex(tok, true , 4) ... OK: got correct error: continue @@ -160,13 +214,18 @@ json_tokener_parse_ex(tok, noodle , 7) ... OK: got correct error: null ex json_tokener_parse_ex(tok, naodle , 7) ... OK: got correct error: null expected json_tokener_parse_ex(tok, track , 6) ... OK: got correct error: boolean expected json_tokener_parse_ex(tok, fail , 5) ... OK: got correct error: boolean expected -json_tokener_parse_ex(tok, null123 , 9) ... OK: got object of type [null]: null +json_tokener_parse_ex(tok, null123 , 8) ... OK: got object of type [null]: null json_tokener_parse_ex(tok, 123 , 4) ... OK: got object of type [int]: 123 -json_tokener_parse_ex(tok, nullx , 5) ... OK: got object of type [null]: null +json_tokener_parse_ex(tok, nullx , 6) ... OK: got object of type [null]: null json_tokener_parse_ex(tok, x , 2) ... OK: got correct error: unexpected character json_tokener_parse_ex(tok, {"a":1}{"b":2}, 15) ... OK: got object of type [object]: { "a": 1 } json_tokener_parse_ex(tok, {"b":2} , 8) ... OK: got object of type [object]: { "b": 2 } -json_tokener_parse_ex(tok, 2015-01-15 , 10) ... OK: got correct error: number expected +json_tokener_parse_ex(tok, 2015-01-15 , 11) ... OK: got object of type [int]: 2015 +json_tokener_parse_ex(tok, -01-15 , 7) ... OK: got object of type [int]: -1 +json_tokener_parse_ex(tok, -15 , 4) ... OK: got object of type [int]: -15 +json_tokener_parse_ex(tok, 2015 01 15 , 11) ... OK: got object of type [int]: 2015 +json_tokener_parse_ex(tok, 01 15 , 7) ... OK: got object of type [int]: 1 +json_tokener_parse_ex(tok, 15 , 4) ... OK: got object of type [int]: 15 json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue" json_tokener_parse_ex(tok, "\"" , 4) ... OK: got object of type [string]: "\"" json_tokener_parse_ex(tok, "\\" , 4) ... OK: got object of type [string]: "\\" @@ -216,5 +275,5 @@ json_tokener_parse_ex(tok, "\ud855Àudc55", 14) ... OK: got correct error: inval json_tokener_parse_ex(tok, "\ud0031À" , 10) ... OK: got correct error: invalid utf-8 string json_tokener_parse_ex(tok, 1111 , 5) ... OK: got correct error: invalid utf-8 string json_tokener_parse_ex(tok, {"1":1} , 8) ... OK: got correct error: invalid utf-8 string -End Incremental Tests OK=130 ERROR=0 +End Incremental Tests OK=185 ERROR=0 ================================== diff --git a/tests/test_set_value.c b/tests/test_set_value.c index d6f1a33..157e64f 100644 --- a/tests/test_set_value.c +++ b/tests/test_set_value.c @@ -56,14 +56,18 @@ int main(int argc, char **argv) #define MID "A MID STRING" // 12345678901234567890123456789012.... #define HUGE "A string longer than 32 chars as to check non local buf codepath" - tmp = json_object_new_string(SHORT); - assert(strcmp(json_object_get_string(tmp), SHORT) == 0); - json_object_set_string(tmp, MID); + tmp = json_object_new_string(MID); assert(strcmp(json_object_get_string(tmp), MID) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" MID "\"") == 0); + json_object_set_string(tmp, SHORT); + assert(strcmp(json_object_get_string(tmp), SHORT) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" SHORT "\"") == 0); json_object_set_string(tmp, HUGE); assert(strcmp(json_object_get_string(tmp), HUGE) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" HUGE "\"") == 0); json_object_set_string(tmp, SHORT); assert(strcmp(json_object_get_string(tmp), SHORT) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" SHORT "\"") == 0); json_object_put(tmp); printf("STRING PASSED\n"); diff --git a/tests/test_strerror.c b/tests/test_strerror.c new file mode 100644 index 0000000..1780564 --- /dev/null +++ b/tests/test_strerror.c @@ -0,0 +1,11 @@ +#include "strerror_override.h" +#include "strerror_override_private.h" + +#include <stdio.h> + +int main(int argc, char **argv) +{ + puts(strerror(10000)); + puts(strerror(999)); + return 0; +} diff --git a/tests/test_strerror.expected b/tests/test_strerror.expected new file mode 100644 index 0000000..b6b3bb6 --- /dev/null +++ b/tests/test_strerror.expected @@ -0,0 +1,2 @@ +ERRNO=10000 +ERRNO=999 diff --git a/tests/test_strerror.test b/tests/test_strerror.test new file mode 120000 index 0000000..58a13f4 --- /dev/null +++ b/tests/test_strerror.test @@ -0,0 +1 @@ +test_basic.test
\ No newline at end of file diff --git a/tests/test_util_file.c b/tests/test_util_file.c index 9d50663..9150586 100644 --- a/tests/test_util_file.c +++ b/tests/test_util_file.c @@ -127,8 +127,6 @@ int main(int argc, char **argv) // json_object_to_file(file, obj); // json_object_to_file_ext(file, obj, flags); - _json_c_strerror_enable = 1; - const char *testdir; if (argc < 2) { |