Browse Source

replaced

pull/794/head
Stabbar 3 years ago
parent
commit
758c91d1ad
72 changed files with 1306 additions and 2511 deletions
  1. +0
    -31
      AUTHORS
  2. +25
    -121
      CMakeLists.txt
  3. +13
    -127
      ChangeLog
  4. +2
    -2
      README.html
  5. +23
    -101
      README.md
  6. +10
    -29
      RELEASE_CHECKLIST.txt
  7. +12
    -26
      apps/json_parse.c
  8. +17
    -105
      appveyor.yml
  9. +0
    -4
      arraylist.c
  10. +4
    -2
      arraylist.h
  11. +1
    -1
      bench/README.bench.md
  12. +0
    -10
      cmake-configure
  13. +0
    -15
      cmake/config.h.in
  14. +3
    -3
      debug.h
  15. +38
    -51
      doc/Doxyfile.in
  16. +252
    -252
      issues_closed_for_0.13.md
  17. +186
    -186
      issues_closed_for_0.14.md
  18. +3
    -3
      json_c_version.h
  19. +0
    -5
      json_inttypes.h
  20. +108
    -109
      json_object.c
  21. +39
    -81
      json_object.h
  22. +2
    -2
      json_object_iterator.c
  23. +1
    -0
      json_object_private.h
  24. +11
    -16
      json_pointer.c
  25. +211
    -299
      json_tokener.c
  26. +5
    -47
      json_tokener.h
  27. +1
    -1
      json_types.h
  28. +25
    -44
      json_util.c
  29. +1
    -13
      json_util.h
  30. +13
    -13
      linkhash.c
  31. +16
    -94
      linkhash.h
  32. +11
    -24
      printbuf.c
  33. +5
    -5
      printbuf.h
  34. +35
    -100
      random_seed.c
  35. +2
    -6
      strerror_override.c
  36. +24
    -34
      tests/CMakeLists.txt
  37. +0
    -3
      tests/parse_flags.c
  38. +4
    -36
      tests/test1.c
  39. +1
    -1
      tests/test1.expected
  40. +1
    -1
      tests/test1Formatted_plain.expected
  41. +1
    -3
      tests/test1Formatted_pretty.expected
  42. +1
    -1
      tests/test1Formatted_spaced.expected
  43. +1
    -3
      tests/test1Formatted_spaced_pretty.expected
  44. +1
    -3
      tests/test1Formatted_spaced_pretty_pretty_tab.expected
  45. +0
    -3
      tests/test2.c
  46. +1
    -4
      tests/test4.c
  47. +0
    -3
      tests/testReplaceExisting.c
  48. +0
    -2
      tests/test_basic.test
  49. +1
    -14
      tests/test_cast.c
  50. +0
    -35
      tests/test_cast.expected
  51. +1
    -4
      tests/test_charcase.c
  52. +1
    -4
      tests/test_compare.c
  53. +3
    -3
      tests/test_deep_copy.c
  54. +3
    -3
      tests/test_deep_copy.expected
  55. +1
    -4
      tests/test_double_serializer.c
  56. +0
    -3
      tests/test_float.c
  57. +0
    -3
      tests/test_int_add.c
  58. +5
    -2
      tests/test_json_pointer.c
  59. +2
    -3
      tests/test_locale.c
  60. +0
    -3
      tests/test_null.c
  61. +0
    -3
      tests/test_object_iterator.c
  62. +149
    -292
      tests/test_parse.c
  63. +6
    -54
      tests/test_parse.expected
  64. +1
    -4
      tests/test_parse_int64.c
  65. +2
    -5
      tests/test_printbuf.c
  66. +1
    -5
      tests/test_set_serializer.c
  67. +1
    -1
      tests/test_set_serializer.expected
  68. +0
    -11
      tests/test_set_value.c
  69. +10
    -11
      tests/test_util_file.c
  70. +1
    -1
      tests/test_util_file.expected
  71. +0
    -3
      tests/test_visit.c
  72. +8
    -15
      vasprintf_compat.h

+ 0
- 31
AUTHORS View File

@@ -1,61 +1,30 @@
Alan Coopersmith <alan.coopersmith@oracle.com>
Alexander Dahl <post@lespocky.de>
Alexandru Ardelean <ardeleanalex@gmail.com>
andy5995 <andy400-dev@yahoo.com>
Aram Poghosyan <Aram.Poghosyan@teamviewer.com>
Björn Esser <besser82@fedoraproject.org>
BonsaY <bonsay@posteo.de>
changyong guo <guo1487@163.com>
chenguoping <chenguopingdota@163.com>
Chris Lamb <lamby@debian.org>
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>
DeX77 <dex@dragonslave.de>
dota17 <chenguopingdota@163.com>
Eric Haszlakiewicz <erh+git@nimenees.com>
Eric Hawicz <erh+git@nimenees.com>
Even Rouault <even.rouault@spatialys.com>
Gianluigi Tiesi <sherpya@netfarm.it>
grdowns <grdowns@microsoft.com>
Hex052 <elijahiff@gmail.com>
hofnarr <hofnarr@hofnarr.fi>
ihsinme <61293369+ihsinme@users.noreply.github.com>
Ivan Romanov <drizt@land.ru>
Jaap Keuter <jaap.keuter@xs4all.nl>
Jakov Smolic <jakov.smolic@sartura.hr>
janczer <menshikov.ivn@gmail.com>
Jehan <jehan@girinstud.io>
Jehiah Czebotar <jehiah@gmail.com>
Jonathan Wiens <j.wiens@teles.com>
Jose Bollo <jose.bollo@iot.bzh>
José Bollo <jose.bollo@iot.bzh>
Juuso Alasuutari <juuso.alasuutari@gmail.com>
Keith Holman <keith.holman@windriver.com>
Kizuna-Meraki <z9@kizunameraki.de>
Leon Gross <leon.gross@rub.de>
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>
Pawday <pawday@mail.ru>
Philosoph228 <philosoph228@gmail.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 Bielik <robert.bielik@dirac.com>
Robert <roby_p97@yahoo.com>
Rosen Penev <rosenp@gmail.com>
Rubasri Kalidas <rubasri.kalidas@intel.com>
Simon McVittie <smcv@collabora.com>
ssrlive <30760636+ssrlive@users.noreply.github.com>
Tobias Nießen <tniessen@users.noreply.github.com>
Tobias Stoeckmann <tobias@stoeckmann.org>
Tudor Brindus <me@tbrindus.ca>
Unmanned Player <36690541+unmanned-player@users.noreply.github.com>

+ 25
- 121
CMakeLists.txt View File

@@ -10,11 +10,11 @@ endif()
if (CMAKE_VERSION VERSION_LESS 3.0)
project(json-c)
set(PROJECT_VERSION_MAJOR "0")
set(PROJECT_VERSION_MINOR "16")
set(PROJECT_VERSION_MINOR "14")
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.16.99)
project(json-c LANGUAGES C VERSION 0.14.99)
endif()

# If we've got 3.0 then it's good, let's provide support. Otherwise, leave it be.
@@ -42,6 +42,16 @@ endif()

include(CTest)

if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING AND
(NOT MSVC OR NOT (MSVC_VERSION LESS 1800)) # Tests need at least VS2013
)
add_subdirectory(tests)
endif()

if (NOT MSVC) # cmd line apps don't built on Windows currently.
add_subdirectory(apps)
endif()

# Set some packaging variables.
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
@@ -69,10 +79,6 @@ 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
@@ -90,10 +96,6 @@ option(DISABLE_THREAD_LOCAL_STORAGE "Disable using Thread-Local Storage (HAVE_
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)
@@ -140,14 +142,10 @@ 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)

if (HAVE_INTTYPES_H)
# Set a json-c specific var to stamp into json_config.h
# in a way that hopefully won't conflict with other
# projects that use json-c.
if (HAVE_INTTYPES_H AND NOT MSVC)
set(JSON_C_HAVE_INTTYPES_H 1)
endif()

@@ -169,19 +167,6 @@ 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 "bsd")
unset(HAVE_ARC4RANDOM CACHE)
check_symbol_exists(arc4random "bsd/stdlib.h" HAVE_ARC4RANDOM)
if (NOT HAVE_ARC4RANDOM)
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "bsd")
endif()
endif()
endif()

if (HAVE_FCNTL_H)
check_symbol_exists(open "fcntl.h" HAVE_OPEN)
endif()
@@ -192,18 +177,6 @@ if (HAVE_LOCALE_H)
check_symbol_exists(setlocale "locale.h" HAVE_SETLOCALE)
check_symbol_exists(uselocale "locale.h" HAVE_USELOCALE)
endif()

# uClibc *intentionally* crashes in duplocale(), at least as of:
# https://github.com/ffainelli/uClibc/blob/266bdc1/libc/misc/locale/locale.c#L1322
# So, if it looks like we're compiling for a system like that just disable
# locale handling entirely.
exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE CMAKE_GNU_C_MACHINE)
if (CMAKE_GNU_C_MACHINE MATCHES "uclibc")
message(STATUS "Detected uClibc compiler, disabling locale handling")
set(HAVE_SETLOCALE 0)
set(HAVE_USELOCALE 0)
endif()

if (HAVE_STRINGS_H)
check_symbol_exists(strcasecmp "strings.h" HAVE_STRCASECMP)
check_symbol_exists(strncasecmp "strings.h" HAVE_STRNCASECMP)
@@ -215,9 +188,6 @@ 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()
@@ -293,7 +263,7 @@ 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 "Wrote ${PROJECT_BINARY_DIR}/json_config.h")

if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
if ("${DISABLE_WERROR}" STREQUAL "OFF")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
@@ -355,22 +325,6 @@ 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})
@@ -382,13 +336,14 @@ set(JSON_C_PUBLIC_HEADERS
# Note: config.h is _not_ included here
${PROJECT_BINARY_DIR}/json_config.h

${PROJECT_BINARY_DIR}/json.h
${PROJECT_SOURCE_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
@@ -415,6 +370,7 @@ 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
@@ -424,31 +380,16 @@ set(JSON_C_SOURCES
${PROJECT_SOURCE_DIR}/strerror_override.c
)

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()

configure_file(json.h.cmakein ${PROJECT_BINARY_DIR}/json.h @ONLY)

include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR})

add_subdirectory(doc)

# "uninstall" custom target for make generators in unix like operating systems
# and if that target is not present
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
if(NOT TARGET uninstall)
add_custom_target(uninstall
COMMAND cat ${PROJECT_BINARY_DIR}/install_manifest.txt | xargs rm
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif()
endif()
# uninstall
add_custom_target(uninstall
COMMAND cat ${PROJECT_BINARY_DIR}/install_manifest.txt | xargs rm
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

# XXX for a normal full distribution we'll need to figure out
# XXX how to build both shared and static libraries.
@@ -458,7 +399,7 @@ add_library(${PROJECT_NAME}
${JSON_C_HEADERS}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION 5.2.0
VERSION 5.0.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
@@ -469,8 +410,6 @@ target_include_directories(${PROJECT_NAME}
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
)

target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_REQUIRED_LIBRARIES})

# Allow to build static and shared libraries at the same time
if (BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS)
set(STATIC_LIB ${PROJECT_NAME}-static)
@@ -478,13 +417,6 @@ if (BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS)
${JSON_C_SOURCES}
${JSON_C_HEADERS}
)
target_include_directories(${PROJECT_NAME}-static
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
)

target_link_libraries(${PROJECT_NAME}-static PUBLIC ${CMAKE_REQUIRED_LIBRARIES})

# rename the static library
if (NOT MSVC)
@@ -511,7 +443,7 @@ install(TARGETS ${CMAKE_TARGETS}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_INCLUDEDIR}/json-c
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(EXPORT ${PROJECT_NAME}-targets
@@ -539,37 +471,9 @@ if (UNIX OR MINGW OR CYGWIN)
SET(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
SET(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
SET(VERSION ${PROJECT_VERSION})

# Linking against the static json-c requires
# dependent packages to include additional libs:
SET(LIBS_LIST ${CMAKE_REQUIRED_LIBRARIES})

# Note: We would need cmake >= 3.12 in order to use list(TRANSFORM ...)
function(list_transform_prepend var prefix)
set(temp "")
foreach(f ${${var}})
list(APPEND temp "${prefix}${f}")
endforeach()
set(${var} "${temp}" PARENT_SCOPE)
endfunction()
list_transform_prepend(LIBS_LIST "-l")

string(REPLACE ";" " " LIBS "${LIBS_LIST}")

configure_file(json-c.pc.in json-c.pc @ONLY)
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
install(FILES ${PROJECT_BINARY_DIR}/json-c.pc DESTINATION "${INSTALL_PKGCONFIG_DIR}")
endif ()

install(FILES ${JSON_C_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/json-c)

if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING AND
(NOT MSVC OR NOT (MSVC_VERSION LESS 1800)) # Tests need at least VS2013
)
add_subdirectory(tests)
endif()

if (NOT MSVC) # cmd line apps don't built on Windows currently.
add_subdirectory(apps)
endif()

install(FILES ${JSON_C_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/json-c)

+ 13
- 127
ChangeLog View File

@@ -1,115 +1,17 @@

0.17 (future release)
========================================
Next Release 0.15
=====================

Deprecated and removed features:
--------------------------------
* ...

New features
------------
* ...

Significant changes and bug fixes
---------------------------------
* When serializing with JSON_C_TO_STRING_PRETTY set, keep the opening and
closing curly or square braces on same line for empty objects or arrays.
* Disable locale handling when targeting a uClibc system due to problems
with its duplocale() function.
* When parsing with JSON_TOKENER_STRICT set, integer overflow/underflow
now result in a json_tokener_error_parse_number. Without that flag
values are capped at INT64_MIN/UINT64_MAX.


0.16 (up to commit 66dcdf5, 2022-04-13)
========================================

Deprecated and removed features:
--------------------------------
* JSON_C_OBJECT_KEY_IS_CONSTANT is deprecated in favor of
JSON_C_OBJECT_ADD_CONSTANT_KEY
* Direct access to lh_table and lh_entry structure members is deprecated.
Use access functions instead, lh_table_head(), lh_entry_next(), etc...
* Drop REFCOUNT_DEBUG code.

New features
------------
* The 0.16 release introduces no new features

Build changes
-------------
* Add a DISABLE_EXTRA_LIBS option to skip using libbsd
* Add a DISABLE_JSON_POINTER option to skip compiling in json_pointer support.

Significant changes and bug fixes
---------------------------------
* Cap string length at INT_MAX to avoid various issues with very long strings.
* json_object_deep_copy: fix deep copy of strings containing '\0'
* Fix read past end of buffer in the "json_parse" command
* Avoid out of memory accesses in the locally provided vasprintf() function
(for those platforms that use it)
* Handle allocation failure in json_tokener_new_ex
* Fix use-after-free in json_tokener_new_ex() in the event of printbuf_new() returning NULL
* printbuf_memset(): set gaps to zero - areas within the print buffer which
have not been initialized by using printbuf_memset
* printbuf: return -1 on invalid arguments (len < 0 or total buffer > INT_MAX)
* sprintbuf(): propagate printbuf_memappend errors back to the caller

Optimizations
--------------
* Speed up parsing by replacing ctype functions with simplified, faster
non-locale-sensitive ones in json_tokener and json_object_to_json_string.
* Neither vertical tab nor formfeed are considered whitespace per the JSON spec
* json_object: speed up creation of objects, calloc() -> malloc() + set fields
* Avoid needless extra strlen() call in json_c_shallow_copy_default() and
json_object_equal() when the object is known to be a json_type_string.
* array_list_new() has been deprecated in favor of array_list_new2()

Other changes
-------------
* Validate size arguments in arraylist functions.
* Use getrandom() if available; with GRND_NONBLOCK to allow use of json-c
very early during boot, such as part of cryptsetup.
* Use arc4random() if it's available.
* random_seed: on error, continue to next method instead of exiting the process
* Close file when unable to read from /dev/urandom in get_dev_random_seed()

***

0.15 (up to commit 870965e, 2020/07/26)
========================================

Deprecated and removed features:
--------------------------------
* 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
---------------------------------
--------------
* 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.
* 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
@@ -121,24 +23,8 @@ Significant changes and bug fixes
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
-------------
* #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 created 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
* 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.


***
@@ -261,7 +147,7 @@ Behavior changes:
* Use size_t for array length and size. Platforms where sizeof(size_t) != sizeof(int) may not be backwards compatible
See commits 45c56b, 92e9a5 and others.

* Check for failure when allocating memory, returning NULL and errno=ENOMEM.
* Check for failue when allocating memory, returning NULL and errno=ENOMEM.
See commit 2149a04.

* Change json_object_object_add() return type from void to int, and will return -1 on failures, instead of exiting. (Note: this is not an ABI change)
@@ -452,7 +338,7 @@ List of new functions added:
* Add an alternative iterator implementation, see json_object_iterator.h
* Make json_object_iter public to enable external use of the
json_object_object_foreachC macro.
* Add a printbuf_memset() function to provide an efficient way to set and
* Add a printbuf_memset() function to provide an effecient way to set and
append things like whitespace indentation.
* Adjust json_object_is_type and json_object_get_type so they return
json_type_null for NULL objects and handle NULL passed to
@@ -538,7 +424,7 @@ List of new functions added:
0.7
===
* Add escaping of backslash to json output
* Add escaping of forward slash on tokenizing and output
* Add escaping of foward slash on tokenizing and output
* Changes to internal tokenizer from using recursion to
using a depth state structure to allow incremental parsing



+ 2
- 2
README.html View File

@@ -26,12 +26,12 @@
</ul>

<h3>Documentation</h3>
<P>Doxygen generated documentation exists <a href="https://json-c.github.io/json-c/">here</a>.</P>
<P>Doxygen generated documentation exists <a href="http://json-c.github.io/json-c/">here</a>.</P>

<h3><a href="https://github.com/json-c/json-c">GIT Reposository</a></h3>
<p><strong><code>git clone https://github.com/json-c/json-c.git</code></strong></p>

<h3><a href="https://groups.google.com/group/json-c">Mailing List</a></h3>
<h3><a href="http://groups.google.com/group/json-c">Mailing List</a></h3>
<pi>Send email to <strong><code>json-c <i>&lt;at&gt;</i> googlegroups <i>&lt;dot&gt;</i> com</code></strong></p>

<h3><a href="COPYING">License</a></h3>


+ 23
- 101
README.md View File

@@ -1,69 +1,41 @@
\mainpage

`json-c`
========

1. [Overview and Build Status](#overview)
2. [Getting Help](#gettinghelp)
3. [Building on Unix](#buildunix)
2. [Building on Unix](#buildunix)
* [Prerequisites](#installprereq)
* [Build commands](#buildcmds)
4. [CMake options](#CMake)
5. [Testing](#testing)
6. [Building with `vcpkg`](#buildvcpkg)
7. [Linking to libjson-c](#linking)
8. [Using json-c](#using)
3. [CMake options](#CMake)
4. [Testing](#testing)
5. [Building with `vcpkg`](#buildvcpkg)
6. [Linking to libjson-c](#linking)
7. [Using json-c](#using)

JSON-C - A JSON implementation in C <a name="overview"></a>
-----------------------------------

Build Status
* [AppVeyor Build](https://ci.appveyor.com/project/hawicz/json-c) ![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/json-c/json-c?branch=master&svg=true)
* [Travis Build](https://travis-ci.org/json-c/json-c) ![Travis Build Status](https://travis-ci.org/json-c/json-c.svg?branch=master)

Test Status
* [Coveralls](https://coveralls.io/github/json-c/json-c?branch=master) [![Coverage Status](https://coveralls.io/repos/github/json-c/json-c/badge.svg?branch=master)](https://coveralls.io/github/json-c/json-c?branch=master)

JSON-C implements a reference counting object model that allows you to easily
construct JSON objects in C, output them as JSON formatted strings and parse
JSON formatted strings back into the C representation of JSON objects.
It aims to conform to [RFC 7159](https://tools.ietf.org/html/rfc7159).

Skip down to [Using json-c](#using)
or check out the [API docs](https://json-c.github.io/json-c/),
if you already have json-c installed and ready to use.

Home page for json-c: https://github.com/json-c/json-c/wiki

Getting Help <a name="gettinghelp"></a>
------------

If you have questions about using json-c, please start a thread on
our forums at: https://groups.google.com/forum/#!forum/json-c

If you believe you've discovered a bug, report it at
(https://github.com/json-c/json-c/issues). Please be sure to include
the version of json-c you're using, the OS you're running on, and any
other relevant details. Fully reproducible test cases and/or patches
to fix problems are greatly appreciated.

Fixes for bugs, or small new features can be directly submitted as a
[pull request](https://github.com/json-c/json-c/pulls). For major new
features or large changes of any kind, please first start a discussion
on the [forums](https://groups.google.com/forum/#!forum/json-c).


Building on Unix with `git`, `gcc` and `cmake` <a name="buildunix"></a>
--------------------------------------------------

If you already have json-c installed, see [Linking to `libjson-c`](#linking)
for how to build and link your program against it.

Build Status
* [AppVeyor Build](https://ci.appveyor.com/project/hawicz/json-c) ![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/json-c/json-c?branch=master&svg=true)
* [Travis Build](https://app.travis-ci.com/github/json-c/json-c) ![Travis Build Status](https://api.travis-ci.com/json-c/json-c.svg?branch=master)

Test Status
* [Coveralls](https://coveralls.io/github/json-c/json-c?branch=master) [![Coverage Status](https://coveralls.io/repos/github/json-c/json-c/badge.svg?branch=master)](https://coveralls.io/github/json-c/json-c?branch=master)
Home page for json-c: https://github.com/json-c/json-c/wiki

### Prerequisites: <a name="installprereq"></a>

- `gcc`, `clang`, or another C compiler

- `cmake>=2.8`, `>=3.16` recommended, `cmake=>3.1` for tests
- cmake>=2.8, >=3.16 recommended

To generate docs you'll also need:
- `doxygen>=1.8.13`
@@ -100,13 +72,13 @@ Then:
$ make
$ make test
$ make USE_VALGRIND=0 test # optionally skip using valgrind
$ sudo make install # it could be necessary to execute make install
$ make install
```


### Generating documentation with Doxygen:

The library documentation can be generated directly from the source code using Doxygen tool:
The libray documentation can be generated directly from the source codes using Doxygen tool:

```sh
# in build directory
@@ -131,11 +103,8 @@ DISABLE_STATIC_FPIC | Bool | The default builds position independent
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.
DISABLE_EXTRA_LIBS | Bool | Disable use of extra libraries, libbsd
DISABLE_JSON_POINTER | Bool | Omit json_pointer support from the build.
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.

@@ -214,7 +183,7 @@ If a test fails, check `Testing/Temporary/LastTest.log`,
`tests/testSubDir/${testname}/${testname}.vg.out`, and other similar files.
If there is insufficient output try:
```sh
VERBOSE=1 CTEST_OUTPUT_ON_FAILURE=1 make test
VERBOSE=1 make test
```
or
```sh
@@ -248,74 +217,27 @@ CFLAGS += $(shell pkg-config --cflags json-c)
LDFLAGS += $(shell pkg-config --libs json-c)
```

Without `pkgconfig`, you might do something like this:
Without `pkgconfig`, you would do something like this:

```make
JSON_C_DIR=/path/to/json_c/install
CFLAGS += -I$(JSON_C_DIR)/include/json-c
# Or to use lines like: #include <json-c/json_object.h>
#CFLAGS += -I$(JSON_C_DIR)/include
LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c
```

If your project uses cmake:

* Add to your CMakeLists.txt file:

```cmake
find_package(json-c CONFIG)
target_link_libraries(${PROJECT_NAME} PRIVATE json-c::json-c)
```

* Then you might run in your project:

```sh
cd build
cmake -DCMAKE_PREFIX_PATH=/path/to/json_c/install/lib64/cmake ..
```

Using json-c <a name="using">
------------

To use json-c you can either include json.h, or preferably, one of the
To use json-c you can either include json.h, or preferrably, one of the
following more specific header files:

* json_object.h - Core types and methods.
* 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. (See also `json_object_object_foreach()` in json_object.h)
* json_object_iterator.h - Methods for iterating over single json_object instances.
* json_visit.h - Methods for walking a tree of json-c objects.
* json_util.h - Miscellaneous utility functions.

For a full list of headers see [files.html](https://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.
* json_util.h - Miscelleanous utility functions.

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)

+ 10
- 29
RELEASE_CHECKLIST.txt View File

@@ -18,16 +18,7 @@
* 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

PREV=$(git tag | tail -1)
( git log -r ${PREV}..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.

@@ -40,14 +31,14 @@
## Release creation

Start creating the new release:
release=0.16
release=0.15
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 -DCMAKE_BUILD_TYPE=Release ../json-c-${release}
cmake ../json-c-${release}
make distcheck
cd ..

@@ -62,6 +53,7 @@ Make any fixes/changes *before* branching.
Using ${release}:
Update the version in json_c_version.h
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:
@@ -71,20 +63,13 @@ 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:

(cd ../distcheck && make doc)
cp -r -p ../distcheck/doc/{html,Doxyfile} doc/.
rm doc/Doxyfile # Remove generated file w/ hardcoded paths
doxygen
git add -f doc
git commit doc -m "Generate docs for the ${release} release"
git commit doc

------------

@@ -94,7 +79,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}

------------
@@ -112,9 +97,8 @@ Tag the branch:
Go to Amazon S3 service at:
https://console.aws.amazon.com/s3/

Upload the two tarballs in the json-c_releases/releases folder.
* Expand "Permissions", pick "Grant public-read access"
* Expand "Properties", ensure "Standard" storage class is picked.
Upload the two tarballs in the json-c_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.
https://s3.amazonaws.com/json-c_releases/releases/index.html
@@ -130,14 +114,13 @@ 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 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 ${release}.99"
git commit -a -m "Update the master branch to version 0.${release}.99"
git push

------------
@@ -153,8 +136,6 @@ 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


+ 12
- 26
apps/json_parse.c View File

@@ -22,19 +22,6 @@
#include <sys/time.h>
#endif

#ifndef JSON_NORETURN
#if defined(_MSC_VER)
#define JSON_NORETURN __declspec(noreturn)
#elif defined(__OS400__)
#define JSON_NORETURN
#else
/* 'cold' attribute is for optimization, telling the computer this code
* path is unlikely.
*/
#define JSON_NORETURN __attribute__((noreturn, cold))
#endif
#endif

static int formatted_output = 0;
static int show_output = 1;
static int strict_mode = 0;
@@ -44,7 +31,7 @@ static const char *fname = NULL;
#define json_tokener_get_parse_end(tok) ((tok)->char_offset)
#endif

JSON_NORETURN static void usage(const char *argv0, int exitval, const char *errmsg);
static void usage(const char *argv0, int exitval, const char *errmsg);
static void showmem(void);
static int parseit(int fd, int (*callback)(struct json_object *));
static int showobj(struct json_object *new_obj);
@@ -63,7 +50,7 @@ static int parseit(int fd, int (*callback)(struct json_object *))
{
struct json_object *obj;
char buf[32768];
ssize_t ret;
int ret;
int depth = JSON_TOKENER_DEFAULT_DEPTH;
json_tokener *tok;

@@ -86,21 +73,19 @@ static int parseit(int fd, int (*callback)(struct json_object *))
size_t total_read = 0;
while ((ret = read(fd, buf, sizeof(buf))) > 0)
{
size_t retu = (size_t)ret; // We know it's positive
total_read += retu;
size_t start_pos = 0;
while (start_pos != retu)
total_read += ret;
int start_pos = 0;
while (start_pos != ret)
{
obj = json_tokener_parse_ex(tok, &buf[start_pos], retu - start_pos);
obj = json_tokener_parse_ex(tok, &buf[start_pos], ret - start_pos);
enum json_tokener_error jerr = json_tokener_get_error(tok);
size_t parse_end = json_tokener_get_parse_end(tok);
int parse_end = json_tokener_get_parse_end(tok);
if (obj == NULL && jerr != json_tokener_continue)
{
const char *aterr = (start_pos + parse_end < (int)sizeof(buf)) ?
&buf[start_pos + parse_end] : "";
char *aterr = &buf[start_pos + parse_end];
fflush(stdout);
size_t fail_offset = total_read - retu + start_pos + parse_end;
fprintf(stderr, "Failed at offset %lu: %s %c\n", (unsigned long)fail_offset,
int fail_offset = total_read - ret + start_pos + parse_end;
fprintf(stderr, "Failed at offset %d: %s %c\n", fail_offset,
json_tokener_error_desc(jerr), aterr[0]);
json_tokener_free(tok);
return 1;
@@ -116,7 +101,7 @@ static int parseit(int fd, int (*callback)(struct json_object *))
}
}
start_pos += json_tokener_get_parse_end(tok);
assert(start_pos <= retu);
assert(start_pos <= ret);
}
}
if (ret < 0)
@@ -172,6 +157,7 @@ static void usage(const char *argv0, int exitval, const char *errmsg)

int main(int argc, char **argv)
{
json_object *new_obj;
int opt;

while ((opt = getopt(argc, argv, "fhns")) != -1)


+ 17
- 105
appveyor.yml View File

@@ -1,125 +1,37 @@
version: '{branch}.{build}'

image:
# b_toolset: v143
- Visual Studio 2022

# VS2015 also used for earlier VS builds
# aka os: Windows Server 2012 R2
- Visual Studio 2015

# aka os: Windows Server 2016
# b_toolset: v141
- Visual Studio 2017

# aka os: Windows Server 2019
# b_toolset: v142
- Visual Studio 2019
os: Windows Server 2012 R2

platform: x64

# There should be a better way to set-up a build matrix.
environment:
matrix:
- b_toolset: Windows7.1SDK
b_config: Debug

- b_toolset: v120

- b_toolset: v140
- b_toolset: Windows7.1SDK
b_config: Release

- b_toolset: v141
- b_toolset: v120
b_config: Debug

- b_toolset: v142
- b_toolset: v120
b_config: Release

- b_toolset: v143
- b_toolset: v140
b_config: Debug

configuration:
- Debug
- Release
- b_toolset: v140
b_config: Release

build_script:
- cmake -T %b_toolset% -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DCMAKE_INSTALL_PREFIX=t_install .
- cmake -T %b_toolset% -DCMAKE_BUILD_TYPE=%b_config% -DCMAKE_INSTALL_PREFIX=t_install .
- cmake --build . --target install

matrix:
exclude:
# Skip release builds for all except the newest image
- image: Visual Studio 2015
configuration: Release

# In the "old" image, new toolsets aren't available:
- image: Visual Studio 2015
b_toolset: v141

- image: Visual Studio 2015
b_toolset: v142

- image: Visual Studio 2015
b_toolset: v143

# ----

- image: Visual Studio 2017
configuration: Release

# In the "new" images, exclude all toolsets except the relevant
# one for that image:

- image: Visual Studio 2017
b_toolset: Windows7.1SDK

- image: Visual Studio 2017
b_toolset: v120

- image: Visual Studio 2017
b_toolset: v140

- image: Visual Studio 2017
b_toolset: v142

- image: Visual Studio 2017
b_toolset: v143

# ----

- image: Visual Studio 2019
configuration: Release

- image: Visual Studio 2019
b_toolset: Windows7.1SDK

- image: Visual Studio 2019
b_toolset: v120

- image: Visual Studio 2019
b_toolset: v140

- image: Visual Studio 2019
b_toolset: v141

- image: Visual Studio 2019
b_toolset: v143

# ----

- image: Visual Studio 2022
b_toolset: Windows7.1SDK

- image: Visual Studio 2022
b_toolset: v120

- image: Visual Studio 2022
b_toolset: v140

- image: Visual Studio 2022
b_toolset: v141

- image: Visual Studio 2022
b_toolset: v142

after_build:
- cd t_install
- 7z a ../json-c.win32.%b_toolset%.%CONFIGURATION%.zip *
- 7z a ../json-c.win32.%b_toolset%.%b_config%.zip *

artifacts:
- path: json-c.win32.%b_toolset%.%CONFIGURATION%.zip
name: json-c.win32.%b_toolset%.%CONFIGURATION%.zip
- path: json-c.win32.%b_toolset%.%b_config%.zip
name: json-c.win32.%b_toolset%.%b_config%.zip

+ 0
- 4
arraylist.c View File

@@ -45,8 +45,6 @@ struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size
{
struct array_list *arr;

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;
@@ -108,8 +106,6 @@ 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;


+ 4
- 2
arraylist.h View File

@@ -15,8 +15,8 @@
* Although this is exposed by the json_object_get_array() method,
* it is not recommended for direct use.
*/
#ifndef _json_c_arraylist_h_
#define _json_c_arraylist_h_
#ifndef _arraylist_h_
#define _arraylist_h_

#ifdef __cplusplus
extern "C" {
@@ -75,12 +75,14 @@ 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


+ 1
- 1
bench/README.bench.md View File

@@ -70,7 +70,7 @@ Issues
Using heaptrack, and analyzing the histogram, only shows ~2.6MB
```
heaptrack ./json_parse -n canada.json
heaptrack --analyze heaptrack*gz -H histogram.out
heaptrack --analyze heaptrack*gz -H histgram.out
awk ' { s=$1; count=$2; ru=(int((s+ 15) / 16)) * 16; wasted = ((ru-s)*count); print s, count, ru-s, wasted; total=total+wasted} END { print "Total: ", total }' histogram.out
```



+ 0
- 10
cmake-configure View File

@@ -30,7 +30,6 @@ $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
@@ -65,24 +64,15 @@ while [ $# -gt 0 ] ; do
--enable-shared)
FLAGS+=(-DBUILD_SHARED_LIBS=ON)
;;
--disable-shared)
FLAGS+=(-DBUILD_SHARED_LIBS=OFF)
;;
--enable-static)
FLAGS+=(-DBUILD_STATIC_LIBS=ON)
;;
--disable-static)
FLAGS+=(-DBUILD_STATIC_LIBS=OFF)
;;
--disable-Bsymbolic)
FLAGS+=(-DDISABLE_BSYMBOLIC=ON)
;;
--disable-werror)
FLAGS+=(-DDISABLE_WERROR=ON)
;;
--disable-extra-libs)
FLAGS+=(-DDISABLE_EXTRA_LIBS=ON)
;;
--)
shift
break


+ 0
- 15
cmake/config.h.in View File

@@ -2,9 +2,6 @@
/* 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 "@@"

@@ -56,9 +53,6 @@
/* 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

@@ -74,12 +68,6 @@
/* 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

@@ -149,9 +137,6 @@
/* 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



+ 3
- 3
debug.h View File

@@ -14,8 +14,8 @@
* @file
* @brief Do not use, json-c internal, may be changed or removed at any time.
*/
#ifndef _JSON_C_DEBUG_H_
#define _JSON_C_DEBUG_H_
#ifndef _DEBUG_H_
#define _DEBUG_H_

#include <stdlib.h>

@@ -24,7 +24,7 @@ extern "C" {
#endif

#ifndef JSON_EXPORT
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#if defined(_MSC_VER)
#define JSON_EXPORT __declspec(dllexport)
#else
#define JSON_EXPORT extern


+ 38
- 51
doc/Doxyfile.in View File

@@ -20,7 +20,7 @@
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See https://www.gnu.org/software/libiconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# The default value is: UTF-8.

@@ -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 = @CMAKE_SOURCE_DIR@
STRIP_FROM_PATH =

# 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
@@ -285,7 +285,7 @@ EXTENSION_MAPPING =

# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -318,7 +318,7 @@ BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO

# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# https://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
@@ -427,7 +427,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation.
# The default value is: NO.

EXTRACT_STATIC = YES
EXTRACT_STATIC = NO

# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO
@@ -677,7 +677,7 @@ LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
@@ -758,7 +758,7 @@ 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
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: https://www.gnu.org/software/libiconv) for the list of
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
# possible encodings.
# The default value is: UTF-8.

@@ -805,13 +805,7 @@ 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 = \
*/json_object_private.h \
*/debug.h \
*/*config.h \
*/random_seed.h \
*/strerror_*h \
*/*compat.h
EXCLUDE_PATTERNS =

# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -822,11 +816,7 @@ 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 = \
_json_c_* \
_LH_* \
_printbuf_* \
__STRING
EXCLUDE_SYMBOLS =

# 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
@@ -869,7 +859,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 = @CMAKE_CURRENT_SOURCE_DIR@/fixup_markdown.sh
INPUT_FILTER =

# 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
@@ -961,7 +951,7 @@ SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see https://www.gnu.org/software/global/global.html). You will need version
# (see http://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
@@ -989,7 +979,7 @@ USE_HTAGS = NO
VERBATIM_HEADERS = NO

# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
# clang parser (see: https://clang.llvm.org/) for more accurate parsing at the
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
@@ -1103,7 +1093,7 @@ HTML_STYLESHEET =
# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates.
# standard style sheet and is therefor more robust against future updates.
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra stylesheet files is of importance (e.g. the last
# stylesheet in the list overrules the setting of the previous ones in the
@@ -1125,7 +1115,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the stylesheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
@@ -1183,13 +1173,12 @@ HTML_INDEX_NUM_ENTRIES = 100

# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See
# https://developer.apple.com/library/archive/featuredarticles/DoxygenXcode/
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1305,7 +1294,7 @@ QCH_FILE =

# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.

@@ -1313,8 +1302,8 @@ QHP_NAMESPACE = org.doxygen.Project

# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.

@@ -1322,23 +1311,23 @@ QHP_VIRTUAL_FOLDER = doc

# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_CUST_FILTER_NAME =

# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_CUST_FILTER_ATTRS =

# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_SECT_FILTER_ATTRS =
@@ -1443,7 +1432,7 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES

# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# https://www.mathjax.org) which uses client side Javascript for the rendering
# http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using prerendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1455,7 +1444,7 @@ USE_MATHJAX = NO

# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# https://docs.mathjax.org/en/latest/output/) for more details.
# http://docs.mathjax.org/en/latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
@@ -1470,11 +1459,11 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdn.mathjax.org/mathjax/latest.
# MathJax from http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# This tag requires that the tag USE_MATHJAX is set to YES.

MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest

# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
@@ -1485,7 +1474,7 @@ MATHJAX_EXTENSIONS =

# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see: https://docs.mathjax.org/en/latest/output/) for more details. For an
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.

@@ -1532,7 +1521,7 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer ( doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/).
# Xapian (see: http://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1545,7 +1534,7 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer ( doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Xapian (see: http://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.

@@ -1647,8 +1636,8 @@ EXTRA_PACKAGES =
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty string,
# for the replacement values of the other commands the user is referred to
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
# for the replacement values of the other commands the user is refered to
# HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.

@@ -1718,7 +1707,7 @@ LATEX_SOURCE_CODE = NO

# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.

@@ -1985,9 +1974,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

PREDEFINED = \
_LH_INLINE=inline \
JSON_C_CONST_FUNCTION(func)=func
PREDEFINED = THIS_FUNCTION_IS_DEPRECATED(f)=f

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2074,7 +2061,7 @@ CLASS_DIAGRAMS = YES

# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# https://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
@@ -2096,7 +2083,7 @@ HIDE_UNDOC_RELATIONS = YES

# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: YES.


+ 252
- 252
issues_closed_for_0.13.md View File

@@ -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. \

+ 186
- 186
issues_closed_for_0.14.md View File

@@ -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. \

+ 3
- 3
json_c_version.h View File

@@ -17,14 +17,14 @@ extern "C" {
#endif

#define JSON_C_MAJOR_VERSION 0
#define JSON_C_MINOR_VERSION 16
#define JSON_C_MINOR_VERSION 14
#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.16.99"
#define JSON_C_VERSION "0.14.99"

#ifndef JSON_EXPORT
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#if defined(_MSC_VER)
#define JSON_EXPORT __declspec(dllexport)
#else
#define JSON_EXPORT extern


+ 0
- 5
json_inttypes.h View File

@@ -21,9 +21,4 @@

#endif

#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif

#endif

+ 108
- 109
json_object.c View File

@@ -13,6 +13,7 @@
#include "strerror_override.h"

#include <assert.h>
#include <ctype.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -34,25 +35,26 @@
#include "snprintf_compat.h"
#include "strdup_compat.h"

/* Avoid ctype.h and locale overhead */
#define is_plain_digit(c) ((c) >= '0' && (c) <= '9')

#if SIZEOF_LONG_LONG != SIZEOF_INT64_T
#error The long long type is not 64-bits
#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
#define SSIZE_T_MAX UINT_MAX
#elif SIZEOF_SSIZE_T == SIZEOF_LONG
#define SSIZE_T_MAX LONG_MAX
#define SSIZE_T_MAX ULONG_MAX
#elif SIZEOF_SSIZE_T == SIZEOF_LONG_LONG
#define SSIZE_T_MAX LLONG_MAX
#define SSIZE_T_MAX ULLONG_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);
@@ -158,6 +160,41 @@ static json_object_to_json_string_fn _json_object_userdata_to_json_string;
* */
JSON_NORETURN static void json_abort(const char *message);

/* ref count debugging */

#ifdef REFCOUNT_DEBUG

static struct lh_table *json_object_table;

static void json_object_init(void) __attribute__((constructor));
static void json_object_init(void)
{
MC_DEBUG("json_object_init: creating object table\n");
json_object_table = lh_kptr_table_new(128, NULL);
}

static void json_object_fini(void) __attribute__((destructor));
static void json_object_fini(void)
{
struct lh_entry *ent;
if (MC_GET_DEBUG())
{
if (json_object_table->count)
{
MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
json_object_table->count);
lh_foreach(json_object_table, ent)
{
struct json_object *obj = (struct json_object *)lh_entry_v(ent);
MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
}
}
}
MC_DEBUG("json_object_fini: freeing object table\n");
lh_table_free(json_object_table);
}
#endif /* REFCOUNT_DEBUG */

/* helper for accessing the optimized string data component in json_object
*/
static inline char *get_string_component_mutable(struct json_object *jso)
@@ -178,11 +215,10 @@ static inline const char *get_string_component(const struct json_object *jso)

static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags)
{
size_t pos = 0, start_offset = 0;
int pos = 0, start_offset = 0;
unsigned char c;
while (len)
while (len--)
{
--len;
c = str[pos];
switch (c)
{
@@ -200,7 +236,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
break;
}

if (pos > start_offset)
if (pos - start_offset > 0)
printbuf_memappend(pb, str + start_offset, pos - start_offset);

if (c == '\b')
@@ -226,7 +262,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
if (c < ' ')
{
char sbuf[7];
if (pos > start_offset)
if (pos - start_offset > 0)
printbuf_memappend(pb, str + start_offset,
pos - start_offset);
snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4],
@@ -238,7 +274,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
pos++;
}
}
if (pos > start_offset)
if (pos - start_offset > 0)
printbuf_memappend(pb, str + start_offset, pos - start_offset);
return 0;
}
@@ -302,6 +338,10 @@ int json_object_put(struct json_object *jso)

static void json_object_generic_delete(struct json_object *jso)
{
#ifdef REFCOUNT_DEBUG
MC_DEBUG("json_object_delete_%s: %p\n", json_type_to_name(jso->o_type), jso);
lh_table_delete(json_object_table, jso);
#endif /* REFCOUNT_DEBUG */
printbuf_free(jso->_pb);
free(jso);
}
@@ -323,6 +363,10 @@ static inline struct json_object *json_object_new(enum json_type o_type, size_t
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);
#endif /* REFCOUNT_DEBUG */
return jso;
}

@@ -460,14 +504,16 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri
struct json_object_iter iter;

printbuf_strappend(pb, "{" /*}*/);
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
json_object_object_foreachC(jso, iter)
{
if (had_children)
{
printbuf_strappend(pb, ",");
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
}
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
had_children = 1;
if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
printbuf_strappend(pb, " ");
@@ -483,9 +529,10 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri
else if (iter.val->_to_json_string(iter.val, pb, level + 1, flags) < 0)
return -1;
}
if ((flags & JSON_C_TO_STRING_PRETTY) && had_children)
if (flags & JSON_C_TO_STRING_PRETTY)
{
printbuf_strappend(pb, "\n");
if (had_children)
printbuf_strappend(pb, "\n");
indent(pb, level, flags);
}
if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
@@ -496,7 +543,7 @@ static int json_object_object_to_json_string(struct json_object *jso, struct pri

static void json_object_lh_entry_free(struct lh_entry *ent)
{
if (!lh_entry_k_is_constant(ent))
if (!ent->k_is_constant)
free(lh_entry_k(ent));
json_object_put((struct json_object *)lh_entry_v(ent));
}
@@ -559,7 +606,7 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key,
if (!existing_entry)
{
const void *const k =
(opts & JSON_C_OBJECT_ADD_CONSTANT_KEY) ? (const void *)key : strdup(key);
(opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : strdup(key);
if (k == NULL)
return -1;
return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, opts);
@@ -567,7 +614,7 @@ int json_object_object_add_ex(struct json_object *jso, const char *const key,
existing_value = (json_object *)lh_entry_v(existing_entry);
if (existing_value)
json_object_put(existing_value);
lh_entry_set_val(existing_entry, val);
existing_entry->v = val;
return 0;
}

@@ -689,7 +736,7 @@ struct json_object *json_object_new_int(int32_t i)

int32_t json_object_get_int(const struct json_object *jso)
{
int64_t cint64 = 0;
int64_t cint64;
double cdouble;
enum json_type o_type;

@@ -930,21 +977,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global
#endif
if (global_serialization_float_format)
free(global_serialization_float_format);
if (double_format)
{
char *p = strdup(double_format);
if (p == NULL)
{
_json_c_set_last_err("json_c_set_serialization_double_format: "
"out of memory\n");
return -1;
}
global_serialization_float_format = p;
}
else
{
global_serialization_float_format = NULL;
}
global_serialization_float_format = double_format ? strdup(double_format) : NULL;
}
else if (global_or_thread == JSON_C_OPTION_THREAD)
{
@@ -954,31 +987,16 @@ int json_c_set_serialization_double_format(const char *double_format, int global
free(tls_serialization_float_format);
tls_serialization_float_format = NULL;
}
if (double_format)
{
char *p = strdup(double_format);
if (p == NULL)
{
_json_c_set_last_err("json_c_set_serialization_double_format: "
"out of memory\n");
return -1;
}
tls_serialization_float_format = p;
}
else
{
tls_serialization_float_format = NULL;
}
tls_serialization_float_format = double_format ? strdup(double_format) : NULL;
#else
_json_c_set_last_err("json_c_set_serialization_double_format: not compiled "
"with __thread support\n");
_json_c_set_last_err("json_c_set_option: not compiled with __thread support\n");
return -1;
#endif
}
else
{
_json_c_set_last_err("json_c_set_serialization_double_format: invalid "
"global_or_thread value: %d\n", global_or_thread);
_json_c_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n",
global_or_thread);
return -1;
}
return 0;
@@ -1039,7 +1057,8 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str
format_drops_decimals = 1;

looks_numeric = /* Looks like *some* kind of number */
is_plain_digit(buf[0]) || (size > 1 && buf[0] == '-' && is_plain_digit(buf[1]));
isdigit((unsigned char)buf[0]) ||
(size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1]));

if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
strchr(buf, 'e') == NULL && /* Not scientific notation */
@@ -1236,17 +1255,17 @@ static struct json_object *_json_object_new_string(const char *s, const size_t l
struct json_object_string *jso;

/*
* Structures Actual memory layout
* ------------------- --------------------
* Structures Actual memory layout
* ------------------- --------------------
* [json_object_string [json_object_string
* [json_object] [json_object]
* ...other fields... ...other fields...
* ...other fields... ...other fields...
* c_string] len
* bytes
* bytes
* of
* string
* data
* \0]
* \0]
*/
if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1))
return NULL;
@@ -1263,8 +1282,7 @@ static struct json_object *_json_object_new_string(const char *s, const size_t l
return NULL;
jso->len = len;
memcpy(jso->c_string.idata, s, len);
// Cast below needed for Clang UB sanitizer
((char *)jso->c_string.idata)[len] = '\0';
jso->c_string.idata[len] = '\0';
return &jso->base;
}

@@ -1288,20 +1306,18 @@ const char *json_object_get_string(struct json_object *jso)
default: return json_object_to_json_string(jso);
}
}

static inline ssize_t _json_object_get_string_len(const struct json_object_string *jso)
{
ssize_t len;
len = jso->len;
return (len < 0) ? -(ssize_t)len : len;
}
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 _json_object_get_string_len(JC_STRING_C(jso));
case json_type_string:
{
len = JC_STRING_C(jso)->len;
return (len < 0) ? -(ssize_t)len : len;
}
default: return 0;
}
}
@@ -1314,24 +1330,16 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l
if (jso == NULL || jso->o_type != json_type_string)
return 0;

if (len >= INT_MAX - 1)
if (len >= SSIZE_T_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.
// full size_t range.
return 0;

dstbuf = get_string_component_mutable(jso);
curlen = JC_STRING(jso)->len;
if (curlen < 0) {
if (len == 0) {
free(JC_STRING(jso)->c_string.pdata);
JC_STRING(jso)->len = curlen = 0;
} else {
curlen = -curlen;
}
}

if (curlen < 0)
curlen = -curlen;
newlen = len;
dstbuf = get_string_component_mutable(jso);

if ((ssize_t)len > curlen)
{
@@ -1378,15 +1386,17 @@ static int json_object_array_to_json_string(struct json_object *jso, struct prin
size_t ii;

printbuf_strappend(pb, "[");
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
for (ii = 0; ii < json_object_array_length(jso); ii++)
{
struct json_object *val;
if (had_children)
{
printbuf_strappend(pb, ",");
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
}
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
had_children = 1;
if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
printbuf_strappend(pb, " ");
@@ -1397,9 +1407,10 @@ static int json_object_array_to_json_string(struct json_object *jso, struct prin
else if (val->_to_json_string(val, pb, level + 1, flags) < 0)
return -1;
}
if ((flags & JSON_C_TO_STRING_PRETTY) && had_children)
if (flags & JSON_C_TO_STRING_PRETTY)
{
printbuf_strappend(pb, "\n");
if (had_children)
printbuf_strappend(pb, "\n");
indent(pb, level, flags);
}

@@ -1595,10 +1606,9 @@ int json_object_equal(struct json_object *jso1, struct json_object *jso2)

case json_type_string:
{
return (_json_object_get_string_len(JC_STRING(jso1)) ==
_json_object_get_string_len(JC_STRING(jso2)) &&
return (json_object_get_string_len(jso1) == json_object_get_string_len(jso2) &&
memcmp(get_string_component(jso1), get_string_component(jso2),
_json_object_get_string_len(JC_STRING(jso1))) == 0);
json_object_get_string_len(jso1)) == 0);
}

case json_type_object: return json_object_all_values_equal(jso1, jso2);
@@ -1619,22 +1629,14 @@ static int json_object_copy_serializer_data(struct json_object *src, struct json
if (dst->_to_json_string == json_object_userdata_to_json_string ||
dst->_to_json_string == _json_object_userdata_to_json_string)
{
char *p;
assert(src->_userdata);
p = strdup(src->_userdata);
if (p == NULL)
{
_json_c_set_last_err("json_object_copy_serializer_data: out of memory\n");
return -1;
}
dst->_userdata = p;
dst->_userdata = strdup(src->_userdata);
}
// else if ... other supported serializers ...
else
{
_json_c_set_last_err(
"json_object_copy_serializer_data: unable to copy unknown serializer data: "
"%p\n", (void *)dst->_to_json_string);
"json_object_deep_copy: unable to copy unknown serializer data: %p\n",
dst->_to_json_string);
return -1;
}
dst->_user_delete = src->_user_delete;
@@ -1671,10 +1673,7 @@ int json_c_shallow_copy_default(json_object *src, json_object *parent, const cha
}
break;

case json_type_string:
*dst = json_object_new_string_len(get_string_component(src),
_json_object_get_string_len(JC_STRING(src)));
break;
case json_type_string: *dst = json_object_new_string(get_string_component(src)); break;

case json_type_object: *dst = json_object_new_object(); break;

@@ -1726,8 +1725,8 @@ 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, UINT_MAX,
&jso, shallow_copy) < 0)
else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso,
shallow_copy) < 0)
{
json_object_put(jso);
return -1;
@@ -1791,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, UINT_MAX, dst, shallow_copy);
rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy);
if (rc < 0)
{
json_object_put(*dst);


+ 39
- 81
json_object.h View File

@@ -17,6 +17,16 @@
#ifndef _json_object_h_
#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
@@ -52,7 +62,7 @@ extern "C" {
* json_object_to_file_ext() functions which causes
* the output to be formatted.
*
* See the "Two Space Tab" option at https://jsonformatter.curiousconcept.com/
* See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/
* for an example of the format.
*/
#define JSON_C_TO_STRING_PRETTY (1 << 1)
@@ -100,17 +110,9 @@ extern "C" {
* key is given as a real constant value in the function
* call, e.g. as in
* json_object_object_add_ex(obj, "ip", json,
* JSON_C_OBJECT_ADD_CONSTANT_KEY);
*/
#define JSON_C_OBJECT_ADD_CONSTANT_KEY (1 << 2)
/**
* This flag is an alias to JSON_C_OBJECT_ADD_CONSTANT_KEY.
* Historically, this flag was used first and the new name
* JSON_C_OBJECT_ADD_CONSTANT_KEY was introduced for version
* 0.16.00 in order to have regular naming.
* Use of this flag is now legacy.
* JSON_C_OBJECT_KEY_IS_CONSTANT);
*/
#define JSON_C_OBJECT_KEY_IS_CONSTANT JSON_C_OBJECT_ADD_CONSTANT_KEY
#define JSON_C_OBJECT_KEY_IS_CONSTANT (1 << 2)

/**
* Set the global value of an option, which will apply to all
@@ -131,43 +133,21 @@ extern "C" {
/* reference counting functions */

/**
* 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 necessarily parallel) threads
* of execution that all expect to free it (with `json_object_put()`) when
* they're done.
* Increment the reference count of json_object, thereby grabbing shared
* ownership of obj.
*
* @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, 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.
* imbalance in the reference count.
* An obj of NULL may be passed; in that case this call 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);

@@ -367,21 +347,15 @@ 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 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.
* 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.
*
* Any previous object stored under `key` in `obj` will have its refcount
* decremented, and be freed normally if that drops to zero.
* 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.
*
* @param obj the json_object instance
* @param key the object field name (a private copy will be duplicated)
@@ -404,7 +378,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
* (OPT1|OPT2)
* arithmetic or (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);
@@ -478,19 +452,19 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
* @param val the local name for the json_object* object variable defined in
* the body
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L

#define json_object_object_foreach(obj, key, val) \
char *key = NULL; \
struct json_object *val __attribute__((__unused__)) = NULL; \
for (struct lh_entry *entry##key = lh_table_head(json_object_get_object(obj)), \
for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \
*entry_next##key = NULL; \
({ \
if (entry##key) \
{ \
key = (char *)lh_entry_k(entry##key); \
val = (struct json_object *)lh_entry_v(entry##key); \
entry_next##key = lh_entry_next(entry##key); \
entry_next##key = entry##key->next; \
}; \
entry##key; \
}); \
@@ -503,30 +477,29 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
struct json_object *val = NULL; \
struct lh_entry *entry##key; \
struct lh_entry *entry_next##key = NULL; \
for (entry##key = lh_table_head(json_object_get_object(obj)); \
for (entry##key = json_object_get_object(obj)->head; \
(entry##key ? (key = (char *)lh_entry_k(entry##key), \
val = (struct json_object *)lh_entry_v(entry##key), \
entry_next##key = lh_entry_next(entry##key), entry##key) \
entry_next##key = entry##key->next, entry##key) \
: 0); \
entry##key = entry_next##key)

#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) */
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */

/** Iterate through all keys and values of an object (ANSI C Safe)
* @param obj the json_object instance
* @param iter the object iterator, use type json_object_iter
*/
#define json_object_object_foreachC(obj, iter) \
for (iter.entry = lh_table_head(json_object_get_object(obj)); \
for (iter.entry = json_object_get_object(obj)->head; \
(iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \
iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
: 0); \
iter.entry = lh_entry_next(iter.entry))
iter.entry = iter.entry->next)

/* 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()
@@ -535,12 +508,6 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
*/
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
@@ -613,15 +580,7 @@ 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 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.
*
/** Get the element at specified index of the array (a json_object of type json_type_array)
* @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)
@@ -664,9 +623,8 @@ 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 0 will be returned, even non-empty
* json_type_array and json_type_object objects.
* 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.
*
* @param obj the json_object instance
* @returns a json_bool
@@ -747,7 +705,7 @@ JSON_EXPORT int json_object_set_int(struct json_object *obj, int new_value);
*
* @param obj the json_object instance
* @param val the value to add
* @returns 1 if the increment succeeded, 0 otherwise
* @returns 1 if the increment succeded, 0 otherwise
*/
JSON_EXPORT int json_object_int_inc(struct json_object *obj, int64_t val);

@@ -1064,7 +1022,7 @@ JSON_EXPORT json_c_shallow_copy_fn json_c_shallow_copy_default;
* when custom serializers are in use. See also
* json_object set_serializer.
*
* @returns 0 if the copy went well, -1 if an error occurred during copy
* @returns 0 if the copy went well, -1 if an error occured during copy
* or if the destination pointer is non-NULL
*/



+ 2
- 2
json_object_iterator.c View File

@@ -71,7 +71,7 @@ struct json_object_iterator json_object_iter_begin(struct json_object *obj)

/// @note For a pair-less Object, head is NULL, which matches our
/// definition of the "end" iterator
iter.opaque_ = lh_table_head(pTable);
iter.opaque_ = pTable->head;
return iter;
}

@@ -98,7 +98,7 @@ void json_object_iter_next(struct json_object_iterator *iter)
JASSERT(NULL != iter);
JASSERT(kObjectEndIterValue != iter->opaque_);

iter->opaque_ = lh_entry_next(((const struct lh_entry *)iter->opaque_));
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
}

/**


+ 1
- 0
json_object_private.h View File

@@ -98,6 +98,7 @@ struct json_object_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


+ 11
- 16
json_pointer.c View File

@@ -10,6 +10,7 @@

#include "strerror_override.h"

#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -19,9 +20,6 @@
#include "strdup_compat.h"
#include "vasprintf_compat.h"

/* Avoid ctype.h and locale overhead */
#define is_plain_digit(c) ((c) >= '0' && (c) <= '9')

/**
* JavaScript Object Notation (JSON) Pointer
* RFC 6901 - https://tools.ietf.org/html/rfc6901
@@ -29,8 +27,8 @@

static void string_replace_all_occurrences_with_char(char *s, const char *occur, char repl_char)
{
size_t slen = strlen(s);
size_t skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
int slen = strlen(s);
int skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
char *p = s;
while ((p = strstr(p, occur)))
{
@@ -41,16 +39,15 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur,
}
}

static int is_valid_index(struct json_object *jo, const char *path, size_t *idx)
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx)
{
size_t i, len = strlen(path);
long int idx_val = -1;
int i, len = strlen(path);
/* this code-path optimizes a bit, for when we reference the 0-9 index range
* in a JSON array and because leading zeros not allowed
*/
if (len == 1)
{
if (is_plain_digit(path[0]))
if (isdigit((unsigned char)path[0]))
{
*idx = (path[0] - '0');
goto check_oob;
@@ -67,21 +64,19 @@ static int is_valid_index(struct json_object *jo, const char *path, size_t *idx)
/* RFC states base-10 decimals */
for (i = 0; i < len; i++)
{
if (!is_plain_digit(path[i]))
if (!isdigit((unsigned char)path[i]))
{
errno = EINVAL;
return 0;
}
}

idx_val = strtol(path, NULL, 10);
if (idx_val < 0)
*idx = strtol(path, NULL, 10);
if (*idx < 0)
{
errno = EINVAL;
return 0;
}
*idx = idx_val;

check_oob:
len = json_object_array_length(jo);
if (*idx >= len)
@@ -98,7 +93,7 @@ static int json_pointer_get_single_path(struct json_object *obj, char *path,
{
if (json_object_is_type(obj, json_type_array))
{
size_t idx;
int32_t idx;
if (!is_valid_index(obj, path, &idx))
return -1;
obj = json_object_array_get_idx(obj, idx);
@@ -131,7 +126,7 @@ static int json_pointer_set_single_path(struct json_object *parent, const char *
{
if (json_object_is_type(parent, json_type_array))
{
size_t idx;
int32_t idx;
/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
if (path[0] == '-' && path[1] == '\0')
return json_object_array_add(parent, value);


+ 211
- 299
json_tokener.c View File

@@ -10,14 +10,14 @@
*
* Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
* The copyrights to the contents of this file are licensed under the MIT License
* (https://www.opensource.org/licenses/mit-license.php)
* (http://www.opensource.org/licenses/mit-license.php)
*/

#include "config.h"

#include "math_compat.h"
#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <stddef.h>
@@ -53,34 +53,6 @@
#error You do not have strncasecmp on your system.
#endif /* HAVE_STRNCASECMP */

#if defined(_MSC_VER) && (_MSC_VER <= 1800)
/* VS2013 doesn't know about "inline" */
#define inline __inline
#elif defined(AIX_CC)
#define inline
#endif

/* The following helper functions are used to speed up parsing. They
* are faster than their ctype counterparts because they assume that
* the input is in ASCII and that the locale is set to "C". The
* compiler will also inline these functions, providing an additional
* speedup by saving on function calls.
*/
static inline int is_ws_char(char c)
{
return c == ' '
|| c == '\t'
|| c == '\n'
|| c == '\r';
}

static inline int is_hex_char(char c)
{
return (c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'F')
|| (c >= 'a' && c <= 'f');
}

/* Use C99 NAN by default; if not available, nan("") should work too. */
#ifndef NAN
#define NAN nan("")
@@ -89,8 +61,7 @@ static inline int is_hex_char(char c)
static const char json_null_str[] = "null";
static const int json_null_str_len = sizeof(json_null_str) - 1;
static const char json_inf_str[] = "Infinity";
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
static const char json_inf_str_invert[] = "iNFINITY";
static const char json_inf_str_lower[] = "infinity";
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
static const char json_nan_str[] = "NaN";
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
@@ -126,8 +97,6 @@ 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;
@@ -163,12 +132,6 @@ struct json_tokener *json_tokener_new_ex(int depth)
return NULL;
}
tok->pb = printbuf_new();
if (!tok->pb)
{
free(tok->stack);
free(tok);
return NULL;
}
tok->max_depth = depth;
json_tokener_reset(tok);
return tok;
@@ -228,17 +191,7 @@ 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 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 (tok->err != json_tokener_success)
{
if (obj != NULL)
json_object_put(obj);
@@ -270,7 +223,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, nBytesp vars
* Implicit inputs: str, len vars
*/
#define PEEK_CHAR(dest, tok) \
(((tok)->char_offset == len) \
@@ -342,7 +295,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
#endif

while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
while (PEEK_CHAR(c, tok))
{

redo_char:
@@ -351,7 +304,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *

case json_tokener_state_eatws:
/* Advance until we change state */
while (is_ws_char(c))
while (isspace((unsigned char)c))
{
if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
goto out;
@@ -456,15 +409,17 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
* complicated with likely little performance benefit.
*/
int is_negative = 0;
const char *_json_inf_str = json_inf_str;
if (!(tok->flags & JSON_TOKENER_STRICT))
_json_inf_str = json_inf_str_lower;

/* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
while (tok->st_pos < (int)json_inf_str_len)
{
char inf_char = *str;
if (inf_char != json_inf_str[tok->st_pos] &&
((tok->flags & JSON_TOKENER_STRICT) ||
inf_char != json_inf_str_invert[tok->st_pos])
)
if (!(tok->flags & JSON_TOKENER_STRICT))
inf_char = tolower((int)*str);
if (inf_char != _json_inf_str[tok->st_pos])
{
tok->err = json_tokener_error_parse_unexpected;
goto out;
@@ -673,165 +628,184 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
break;

// ===================================================

case json_tokener_state_escape_unicode:
{
/* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
/* Handle a 4-byte sequence, or two sequences if a surrogate pair */
while (1)
{
if (!c || !is_hex_char(c))
if (c && strchr(json_hex_chars, c))
{
tok->err = json_tokener_error_parse_string;
goto out;
tok->ucs_char += ((unsigned int)jt_hexdigit(c)
<< ((3 - tok->st_pos++) * 4));
if (tok->st_pos == 4)
{
unsigned char unescaped_utf[4];

if (tok->got_hi_surrogate)
{
if (IS_LOW_SURROGATE(tok->ucs_char))
{
/* remove the utf8_replacement_char */
/* which may generate during */
/* parsing the high surrogate pair. */
if (!strcmp(
tok->pb->buf,
(char *)
utf8_replacement_char))
{
printbuf_reset(tok->pb);
}
/* Recalculate the ucs_char, then fall thru to process normally */
tok->ucs_char =
DECODE_SURROGATE_PAIR(
tok->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);
}
tok->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.
*/
tok->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);
tok->ucs_char = 0;
tok->st_pos = 0;
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;
}
}
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))
else
{
/*
* 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.
*/
tok->err = json_tokener_error_parse_string;
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
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
{
/* 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);
/* Clean up any pending chars */
if (tok->got_hi_surrogate &&
strcmp(tok->pb->buf, (char *)utf8_replacement_char))
printbuf_memappend_fast(
tok->pb, (char *)utf8_replacement_char, 3);
goto out;
}
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 through 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;
@@ -881,38 +855,9 @@ 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 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 == '.')))
int negativesign_next_possible_location = 1;
while (c && strchr(json_number_chars, c))
{
pos_sign_ok = neg_sign_ok = 0;
++case_len;

/* non-digit characters checks */
@@ -921,21 +866,40 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
* protected from input starting with '.' or
* e/E.
*/
switch (c)
if (c == '.')
{
case '.':
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;
}
tok->is_double = 1;
pos_sign_ok = 1;
neg_sign_ok = 1;
break;
case 'e': /* FALLTHRU */
case 'E':
}
if (c == 'e' || c == 'E')
{
if (is_exponent != 0)
{
/* only one exponent possible */
tok->err = json_tokener_error_parse_number;
goto out;
}
is_exponent = 1;
tok->is_double = 1;
/* the exponent part can begin with a negative sign */
pos_sign_ok = neg_sign_ok = 1;
break;
default: break;
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;
}

if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
@@ -944,20 +908,6 @@ 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' && !is_ws_char(c))
{
tok->err = json_tokener_error_parse_number;
goto out;
}
if (case_len > 0)
printbuf_memappend_fast(tok->pb, case_start, case_len);

@@ -968,22 +918,6 @@ 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;
@@ -992,11 +926,6 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
if (!tok->is_double && tok->pb->buf[0] == '-' &&
json_parse_int64(tok->pb->buf, &num64) == 0)
{
if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
{
tok->err = json_tokener_error_parse_number;
goto out;
}
current = json_object_new_int64(num64);
if (current == NULL)
goto out;
@@ -1004,11 +933,6 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
else if (!tok->is_double && tok->pb->buf[0] != '-' &&
json_parse_uint64(tok->pb->buf, &numuint64) == 0)
{
if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT))
{
tok->err = json_tokener_error_parse_number;
goto out;
}
if (numuint64 && tok->pb->buf[0] == '0' &&
(tok->flags & JSON_TOKENER_STRICT))
{
@@ -1030,8 +954,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
}
else if (tok->is_double &&
json_tokener_parse_double(
tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
json_parse_double(tok->pb->buf, &numd) == 0)
{
current = json_object_new_double_s(numd, tok->pb->buf);
if (current == NULL)
@@ -1216,9 +1139,8 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
}
break;
}
(void)ADVANCE_CHAR(str, tok);
if (!c) // This is the char *before* advancing
break;
if (!ADVANCE_CHAR(str, tok))
goto out;
} /* while(PEEK_CHAR) */

out:
@@ -1227,8 +1149,7 @@ 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;
@@ -1300,12 +1221,3 @@ 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;
}

+ 5
- 47
json_tokener.h View File

@@ -59,8 +59,6 @@ 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,
@@ -113,7 +111,7 @@ struct json_tokener
* @deprecated See json_tokener_get_error() instead.
*/
enum json_tokener_error err;
unsigned int ucs_char, high_surrogate;
unsigned int ucs_char, got_hi_surrogate;
char quote_char;
struct json_tokener_srec *stack;
int flags;
@@ -196,44 +194,11 @@ 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);

@@ -255,8 +220,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,
@@ -269,18 +234,13 @@ 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 a subsequent call to json_tokener_parse_ex with an
* appropriate str parameter starting with the extra characters.
* responsible for calling 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).
@@ -296,8 +256,6 @@ 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)


+ 1
- 1
json_types.h View File

@@ -18,7 +18,7 @@ extern "C" {
#endif

#ifndef JSON_EXPORT
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#if defined(_MSC_VER)
#define JSON_EXPORT __declspec(dllexport)
#else
#define JSON_EXPORT extern


+ 25
- 44
json_util.c View File

@@ -14,6 +14,7 @@

#include "strerror_override.h"

#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
@@ -60,7 +61,7 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const

static char _last_err[256] = "";

const char *json_util_get_last_err(void)
const char *json_util_get_last_err()
{
if (_last_err[0] == '\0')
return NULL;
@@ -85,13 +86,13 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
struct printbuf *pb;
struct json_object *obj;
char buf[JSON_FILE_BUF_SIZE];
ssize_t ret;
int ret;
int depth = JSON_TOKENER_DEFAULT_DEPTH;
json_tokener *tok;

if (!(pb = printbuf_new()))
{
_json_c_set_last_err("json_object_from_fd_ex: printbuf_new failed\n");
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
return NULL;
}

@@ -101,29 +102,19 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
if (!tok)
{
_json_c_set_last_err(
"json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n",
depth, strerror(errno));
"json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth,
strerror(errno));
printbuf_free(pb);
return NULL;
}

while ((ret = read(fd, buf, sizeof(buf))) > 0)
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
{
if (printbuf_memappend(pb, buf, ret) < 0)
{
#if JSON_FILE_BUF_SIZE > INT_MAX
#error "Can't append more than INT_MAX bytes at a time"
#endif
_json_c_set_last_err(
"json_object_from_fd_ex: failed to printbuf_memappend after reading %d+%d bytes: %s", printbuf_length(pb), (int)ret, strerror(errno));
json_tokener_free(tok);
printbuf_free(pb);
return NULL;
}
printbuf_memappend(pb, buf, ret);
}
if (ret < 0)
{
_json_c_set_last_err("json_object_from_fd_ex: error reading fd %d: %s\n", fd,
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd,
strerror(errno));
json_tokener_free(tok);
printbuf_free(pb);
@@ -147,8 +138,8 @@ struct json_object *json_object_from_file(const char *filename)

if ((fd = open(filename, O_RDONLY)) < 0)
{
_json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
filename, strerror(errno));
_json_c_set_last_err("json_object_from_file: error opening file %s: %s\n", filename,
strerror(errno));
return NULL;
}
obj = json_object_from_fd(fd);
@@ -165,14 +156,14 @@ int json_object_to_file_ext(const char *filename, struct json_object *obj, int f

if (!obj)
{
_json_c_set_last_err("json_object_to_file_ext: object is null\n");
_json_c_set_last_err("json_object_to_file: object is null\n");
return -1;
}

if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0)
{
_json_c_set_last_err("json_object_to_file_ext: error opening file %s: %s\n",
filename, strerror(errno));
_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", filename,
strerror(errno));
return -1;
}
ret = _json_object_to_fd(fd, obj, flags, filename);
@@ -194,9 +185,9 @@ int json_object_to_fd(int fd, struct json_object *obj, int flags)
}
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
{
ssize_t ret;
int ret;
const char *json_str;
size_t wpos, wsize;
unsigned int wpos, wsize;

filename = filename ? filename : "(fd)";

@@ -205,19 +196,20 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const
return -1;
}

wsize = strlen(json_str);
/* CAW: probably unnecessary, but the most 64bit safe */
wsize = (unsigned int)(strlen(json_str) & UINT_MAX);
wpos = 0;
while (wpos < wsize)
{
if ((ret = write(fd, json_str + wpos, wsize - wpos)) < 0)
{
_json_c_set_last_err("json_object_to_fd: error writing file %s: %s\n",
_json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
filename, strerror(errno));
return -1;
}

/* because of the above check for ret < 0, we can safely cast and add */
wpos += (size_t)ret;
wpos += (unsigned int)ret;
}

return 0;
@@ -230,7 +222,6 @@ 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;
@@ -247,12 +238,7 @@ int json_parse_int64(const char *buf, int64_t *retval)
val = strtoll(buf, &end, 10);
if (end != buf)
*retval = val;
if ((val == 0 && errno != 0) || (end == buf))
{
errno = EINVAL;
return 1;
}
return 0;
return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
}

int json_parse_uint64(const char *buf, uint64_t *retval)
@@ -264,17 +250,12 @@ 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)
*retval = val;
if ((val == 0 && errno != 0) || (end == buf))
{
errno = EINVAL;
return 1;
}
return 0;
return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
}

#ifndef HAVE_REALLOC
@@ -307,8 +288,8 @@ const char *json_type_to_name(enum json_type o_type)
int o_type_int = (int)o_type;
if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
{
_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%u]\n", o_type,
(unsigned)NELEM(json_type_name));
_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type,
NELEM(json_type_name));
return NULL;
}
return json_type_name[o_type];


+ 1
- 13
json_util.h View File

@@ -100,21 +100,9 @@ JSON_EXPORT int json_object_to_fd(int fd, struct json_object *obj, int flags);
*/
JSON_EXPORT const char *json_util_get_last_err(void);

/**
* A parsing helper for integer values. Returns 0 on success,
* with the parsed value assigned to *retval. Overflow/underflow
* are NOT considered errors, but errno will be set to ERANGE,
* just like the strtol/strtoll functions do.
*/
/* these parsing helpers return zero on success */
JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval);
/**
* A parsing help for integer values, providing one extra bit of
* magnitude beyond json_parse_int64().
*/
JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval);
/**
* @deprecated
*/
JSON_EXPORT int json_parse_double(const char *buf, double *retval);

/**


+ 13
- 13
linkhash.c View File

@@ -65,9 +65,9 @@ int lh_ptr_equal(const void *k1, const void *k2)

/*
* hashlittle from lookup3.c, by Bob Jenkins, May 2006, Public Domain.
* https://burtleburtle.net/bob/c/lookup3.c
* http://burtleburtle.net/bob/c/lookup3.c
* minor modifications to make functions static so no symbols are exported
* minor modifications to compile with -Werror
* minor mofifications to compile with -Werror
*/

/*
@@ -81,7 +81,7 @@ if SELF_TEST is defined. You can use this free for any purpose. It's in
the public domain. It has no warranty.

You probably want to use hashlittle(). hashlittle() and hashbig()
hash byte arrays. hashlittle() is faster than hashbig() on
hash byte arrays. hashlittle() is is faster than hashbig() on
little-endian machines. Intel and AMD are little-endian machines.
On second thought, you probably want hashlittle2(), which is identical to
hashlittle() except it returns two 32-bit hashes for the price of one.
@@ -156,7 +156,7 @@ satisfy this are
14 9 3 7 17 3
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
for "differ" defined as + with a one-bit base and a two-bit delta. I
used https://burtleburtle.net/bob/hash/avalanche.html to choose
used http://burtleburtle.net/bob/hash/avalanche.html to choose
the operations, constants, and arrangements of the variables.

This does not achieve avalanche. There are input bits of (a,b,c)
@@ -285,9 +285,9 @@ static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticeably faster for short strings (like English words).
* noticably faster for short strings (like English words).
* AddressSanitizer is similarly picky about overrunning
* the buffer. (https://clang.llvm.org/docs/AddressSanitizer.html)
* the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html
*/
#ifdef VALGRIND
#define PRECISE_MEMORY_ACCESS 1
@@ -439,8 +439,8 @@ static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
}
/* clang-format on */

/* a simple hash function similar to what perl does for strings.
* for good results, the string should not be excessively large.
/* a simple hash function similiar to what perl does for strings.
* for good results, the string should not be excessivly large.
*/
static unsigned long lh_perllike_str_hash(const void *k)
{
@@ -465,7 +465,7 @@ static unsigned long lh_char_hash(const void *k)
if (random_seed == -1)
{
RANDOM_SEED_TYPE seed;
/* we can't use -1 as it is the uninitialized sentinel */
/* we can't use -1 as it is the unitialized sentinel */
while ((seed = json_c_get_random_seed()) == -1) {}
#if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#define USE_SYNC_COMPARE_AND_SWAP 1
@@ -481,12 +481,12 @@ static unsigned long lh_char_hash(const void *k)
#elif defined _MSC_VER || defined __MINGW32__
InterlockedCompareExchange(&random_seed, seed, -1);
#else
//#warning "racy random seed initialization if used by multiple threads"
//#warning "racy random seed initializtion if used by multiple threads"
random_seed = seed; /* potentially racy */
#endif
}

return hashlittle((const char *)k, strlen((const char *)k), (uint32_t)random_seed);
return hashlittle((const char *)k, strlen((const char *)k), random_seed);
}

int lh_char_equal(const void *k1, const void *k2)
@@ -546,7 +546,7 @@ int lh_table_resize(struct lh_table *t, int new_size)
unsigned long h = lh_get_hash(new_t, ent->k);
unsigned int opts = 0;
if (ent->k_is_constant)
opts = JSON_C_OBJECT_ADD_CONSTANT_KEY;
opts = JSON_C_OBJECT_KEY_IS_CONSTANT;
if (lh_table_insert_w_hash(new_t, ent->k, ent->v, h, opts) != 0)
{
lh_table_free(new_t);
@@ -599,7 +599,7 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con
}

t->table[n].k = k;
t->table[n].k_is_constant = (opts & JSON_C_OBJECT_ADD_CONSTANT_KEY);
t->table[n].k_is_constant = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT);
t->table[n].v = v;
t->count++;



+ 16
- 94
linkhash.h View File

@@ -16,8 +16,8 @@
* this is exposed by the json_object_get_object() function and within the
* json_object_iter type, it is not recommended for direct use.
*/
#ifndef _json_c_linkhash_h_
#define _json_c_linkhash_h_
#ifndef _linkhash_h_
#define _linkhash_h_

#include "json_object.h"

@@ -80,84 +80,64 @@ typedef unsigned long(lh_hash_fn)(const void *k);
typedef int(lh_equal_fn)(const void *k1, const void *k2);

/**
* An entry in the hash table. Outside of linkhash.c, treat this as opaque.
* An entry in the hash table
*/
struct lh_entry
{
/**
* The key.
* @deprecated Use lh_entry_k() instead of accessing this directly.
* The key. Use lh_entry_k() instead of accessing this directly.
*/
const void *k;
/**
* A flag for users of linkhash to know whether or not they
* need to free k.
* @deprecated use lh_entry_k_is_constant() instead.
*/
int k_is_constant;
/**
* The value.
* @deprecated Use lh_entry_v() instead of accessing this directly.
* The value. Use lh_entry_v() instead of accessing this directly.
*/
const void *v;
/**
* The next entry.
* @deprecated Use lh_entry_next() instead of accessing this directly.
* The next entry
*/
struct lh_entry *next;
/**
* The previous entry.
* @deprecated Use lh_entry_prev() instead of accessing this directly.
*/
struct lh_entry *prev;
};

/**
* The hash table structure. Outside of linkhash.c, treat this as opaque.
* The hash table structure.
*/
struct lh_table
{
/**
* Size of our hash.
* @deprecated do not use outside of linkhash.c
*/
int size;
/**
* Numbers of entries.
* @deprecated Use lh_table_length() instead.
*/
int count;

/**
* The first entry.
* @deprecated Use lh_table_head() instead.
*/
struct lh_entry *head;

/**
* The last entry.
* @deprecated Do not use, may be removed in a future release.
*/
struct lh_entry *tail;

/**
* Internal storage of the actual table of entries.
* @deprecated do not use outside of linkhash.c
*/
struct lh_entry *table;

/**
* A pointer to the function responsible for freeing an entry.
* @deprecated do not use outside of linkhash.c
* A pointer onto the function responsible for freeing an entry.
*/
lh_entry_free_fn *free_fn;
/**
* @deprecated do not use outside of linkhash.c
*/
lh_hash_fn *hash_fn;
/**
* @deprecated do not use outside of linkhash.c
*/
lh_equal_fn *equal_fn;
};
typedef struct lh_table lh_table;
@@ -165,7 +145,7 @@ typedef struct lh_table lh_table;
/**
* Convenience list iterator.
*/
#define lh_foreach(table, entry) for (entry = lh_table_head(table); entry; entry = lh_entry_next(entry))
#define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next)

/**
* lh_foreach_safe allows calling of deletion routine while iterating.
@@ -175,7 +155,7 @@ typedef struct lh_table lh_table;
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
*/
#define lh_foreach_safe(table, entry, tmp) \
for (entry = lh_table_head(table); entry && ((tmp = lh_entry_next(entry)) || 1); entry = tmp)
for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)

/**
* Create a new linkhash table.
@@ -251,7 +231,7 @@ extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
* @param k a pointer to the key to insert.
* @param v a pointer to the value to insert.
* @param h hash value of the key to insert
* @param opts if set to JSON_C_OBJECT_ADD_CONSTANT_KEY, sets lh_entry.k_is_constant
* @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant
* so t's free function knows to avoid freeing the key.
*/
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v,
@@ -315,9 +295,6 @@ extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
*/
extern int lh_table_delete(struct lh_table *t, const void *k);

/**
* Return the number of entries in the table.
*/
extern int lh_table_length(struct lh_table *t);

/**
@@ -341,19 +318,10 @@ int lh_table_resize(struct lh_table *t, int new_size);
#define _LH_INLINE inline
#endif

/**
* Return the first entry in the lh_table.
* @see lh_entry_next()
*/
static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
{
return t->head;
}

/**
* Calculate the hash of a key for a given table.
*
* This is an extension to support functions that need to calculate
* This is an exension to support functions that need to calculate
* the hash several times and allows them to do it just once and then pass
* in the hash to all utility functions. Depending on use case, this can be a
* considerable performance improvement.
@@ -366,6 +334,7 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void
return t->hash_fn(k);
}

#undef _LH_INLINE

/**
* @deprecated Don't use this outside of linkhash.h:
@@ -381,22 +350,9 @@ static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void
*
* lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
* it, but callers are allowed to do what they want with it.
* @see lh_entry_k_is_constant()
*/
static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
{
return _LH_UNCONST(e->k);
}

/**
* Returns 1 if the key for the given entry is constant, and thus
* does not need to be freed when the lh_entry is freed.
* @see lh_table_insert_w_hash()
* See also lh_entry.k_is_constant
*/
static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
{
return e->k_is_constant;
}
#define lh_entry_k(entry) _LH_UNCONST((entry)->k)

/**
* Return a non-const version of lh_entry.v.
@@ -404,41 +360,7 @@ static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
* v is const to indicate and help ensure that linkhash itself doesn't modify
* it, but callers are allowed to do what they want with it.
*/
static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
{
return _LH_UNCONST(e->v);
}

/**
* Change the value for an entry. The caller is responsible for freeing
* the previous value.
*/
static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
{
e->v = newval;
}

/**
* Return the next element, or NULL if there is no next element.
* @see lh_table_head()
* @see lh_entry_prev()
*/
static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
{
return e->next;
}

/**
* Return the previous element, or NULL if there is no previous element.
* @see lh_table_head()
* @see lh_entry_next()
*/
static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
{
return e->prev;
}

#undef _LH_INLINE
#define lh_entry_v(entry) _LH_UNCONST((entry)->v)

#ifdef __cplusplus
}


+ 11
- 24
printbuf.c View File

@@ -10,12 +10,11 @@
*
* Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
* The copyrights to the contents of this file are licensed under the MIT License
* (https://www.opensource.org/licenses/mit-license.php)
* (http://www.opensource.org/licenses/mit-license.php)
*/

#include "config.h"

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -57,8 +56,6 @@ struct printbuf *printbuf_new(void)
*
* If the current size is large enough, nothing is changed.
*
* If extension failed, errno is set to indicate the error.
*
* Note: this does not check the available space! The caller
* is responsible for performing those calculations.
*/
@@ -71,10 +68,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
return 0;
/* Prevent signed integer overflows with large buffers. */
if (min_size > INT_MAX - 8)
{
errno = EFBIG;
return -1;
}
if (p->size > INT_MAX / 2)
new_size = min_size + 8;
else {
@@ -83,7 +77,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
new_size = min_size + 8;
}
#ifdef PRINTBUF_DEBUG
MC_DEBUG("printbuf_extend: realloc "
MC_DEBUG("printbuf_memappend: realloc "
"bpos=%d min_size=%d old_size=%d new_size=%d\n",
p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
@@ -97,11 +91,8 @@ static int printbuf_extend(struct printbuf *p, int min_size)
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
{
/* Prevent signed integer overflows with large buffers. */
if (size < 0 || size > INT_MAX - p->bpos - 1)
{
errno = EFBIG;
if (size > INT_MAX - p->bpos - 1)
return -1;
}
if (p->size <= p->bpos + size + 1)
{
if (printbuf_extend(p, p->bpos + size + 1) < 0)
@@ -120,11 +111,8 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
if (offset == -1)
offset = pb->bpos;
/* Prevent signed integer overflows with large buffers. */
if (len < 0 || offset < -1 || len > INT_MAX - offset)
{
errno = EFBIG;
if (len > INT_MAX - offset)
return -1;
}
size_needed = offset + len;
if (pb->size < size_needed)
{
@@ -132,8 +120,6 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
return -1;
}

if (pb->bpos < offset)
memset(pb->buf + pb->bpos, '\0', offset - pb->bpos);
memset(pb->buf + offset, charvalue, len);
if (pb->bpos < size_needed)
pb->bpos = size_needed;
@@ -148,16 +134,16 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
int size;
char buf[128];

/* use stack buffer first */
/* user stack buffer first */
va_start(ap, msg);
size = vsnprintf(buf, 128, msg, ap);
va_end(ap);
/* if string is greater than stack buffer, then use dynamic string
* with vasprintf. Note: some implementations of vsnprintf return -1
* with vasprintf. Note: some implementation of vsnprintf return -1
* if output is truncated whereas some return the number of bytes that
* would have been written - this code handles both cases.
*/
if (size < 0 || size > 127)
if (size == -1 || size > 127)
{
va_start(ap, msg);
if ((size = vasprintf(&t, msg, ap)) < 0)
@@ -166,14 +152,15 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
return -1;
}
va_end(ap);
size = printbuf_memappend(p, t, size);
printbuf_memappend(p, t, size);
free(t);
return size;
}
else
{
size = printbuf_memappend(p, buf, size);
printbuf_memappend(p, buf, size);
return size;
}
return size;
}

void printbuf_reset(struct printbuf *p)


+ 5
- 5
printbuf.h View File

@@ -10,21 +10,21 @@
*
* Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
* The copyrights to the contents of this file are licensed under the MIT License
* (https://www.opensource.org/licenses/mit-license.php)
* (http://www.opensource.org/licenses/mit-license.php)
*/

/**
* @file
* @brief Internal string buffer handling. Unless you're writing a
* @brief Internal string buffer handing. Unless you're writing a
* json_object_to_json_string_fn implementation for use with
* json_object_set_serializer() direct use of this is not
* recommended.
*/
#ifndef _json_c_printbuf_h_
#define _json_c_printbuf_h_
#ifndef _printbuf_h_
#define _printbuf_h_

#ifndef JSON_EXPORT
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#if defined(_MSC_VER)
#define JSON_EXPORT __declspec(dllexport)
#else
#define JSON_EXPORT extern


+ 35
- 100
random_seed.c View File

@@ -13,23 +13,9 @@
#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 */
@@ -169,45 +155,9 @@ retry:

#endif /* defined ENABLE_RDRAND */

#ifdef HAVE_GETRANDOM
/* has_dev_urandom */

#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
#if defined(__APPLE__) || defined(__unix__) || defined(__linux__)

#include <fcntl.h>
#include <string.h>
@@ -217,36 +167,43 @@ static int get_getrandom_seed(int *seed)
#include <stdlib.h>
#include <sys/stat.h>

#define HAVE_DEV_RANDOM 1

static const char *dev_random_file = "/dev/urandom";

static int get_dev_random_seed(int *seed)
static int has_dev_urandom(void)
{
DEBUG_SEED("get_dev_random_seed");

struct stat buf;
if (stat(dev_random_file, &buf))
return -1;
if ((buf.st_mode & S_IFCHR) == 0)
return -1;
{
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");

int fd = open(dev_random_file, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
return -1;
exit(1);
}

ssize_t nread = read(fd, seed, sizeof(*seed));

close(fd);

if (nread != sizeof(*seed))
int r;
ssize_t nread = read(fd, &r, sizeof(r));
if (nread != sizeof(r))
{
fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
return -1;
exit(1);
}

return 0;
close(fd);
return r;
}

#endif
@@ -269,10 +226,13 @@ static int get_dev_random_seed(int *seed)
#pragma comment(lib, "advapi32.lib")
#endif

static int get_cryptgenrandom_seed(int *seed)
static int get_time_seed(void);

static int get_cryptgenrandom_seed(void)
{
HCRYPTPROV hProvider = 0;
DWORD dwFlags = CRYPT_VERIFYCONTEXT;
int r;

DEBUG_SEED("get_cryptgenrandom_seed");

@@ -283,74 +243,49 @@ static int get_cryptgenrandom_seed(int *seed)
if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags))
{
fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError());
return -1;
r = get_time_seed();
}
else
{
BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed);
BOOL ret = CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r);
CryptReleaseContext(hProvider, 0);
if (!ret)
{
fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError());
return -1;
r = get_time_seed();
}
}

return 0;
return r;
}

#endif

/* get_time_seed */

#ifndef HAVE_ARC4RANDOM
#include <time.h>

static int get_time_seed(void)
{
DEBUG_SEED("get_time_seed");

/* coverity[store_truncates_time_t] */
return (unsigned)time(NULL) * 433494437;
return (int)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 = 0;
if (get_getrandom_seed(&seed) == 0)
return seed;
}
#endif
#if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM
{
int seed = 0;
if (get_dev_random_seed(&seed) == 0)
return seed;
}
if (has_dev_urandom())
return get_dev_random_seed();
#endif
#if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM
{
int seed = 0;
if (get_cryptgenrandom_seed(&seed) == 0)
return seed;
}
return get_cryptgenrandom_seed();
#endif
return get_time_seed();
#endif /* !HAVE_ARC4RANDOM */
}

+ 2
- 6
strerror_override.c View File

@@ -59,8 +59,7 @@ static struct
/* clang-format on */

// Enabled during tests
static int _json_c_strerror_enable = 0;
extern char *getenv(const char *name); // Avoid including stdlib.h
int _json_c_strerror_enable = 0;

#define PREFIX "ERRNO="
static char errno_buf[128] = PREFIX;
@@ -71,8 +70,6 @@ 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
@@ -94,7 +91,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)];
}
@@ -105,6 +102,5 @@ char *_json_c_strerror(int errno_in)
{
errno_buf[start_idx] = digbuf[ii];
}
errno_buf[start_idx] = '\0';
return errno_buf;
}

+ 24
- 34
tests/CMakeLists.txt View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1)
add_executable(test1Formatted test1.c parse_flags.c parse_flags.h)
target_compile_definitions(test1Formatted PRIVATE TEST_FORMATTED=1)
target_link_libraries(test1Formatted PRIVATE ${PROJECT_NAME})
@@ -12,41 +12,31 @@ target_link_libraries(test2Formatted PRIVATE ${PROJECT_NAME})

include_directories(PUBLIC ${CMAKE_SOURCE_DIR})

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})
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)

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 :(


+ 0
- 3
tests/parse_flags.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"

#include <stdio.h>


+ 4
- 36
tests/test1.c View File

@@ -1,15 +1,9 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#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"

@@ -61,7 +55,7 @@ static const char *to_json_string(json_object *obj, int flags)
#endif

json_object *make_array(void);
json_object *make_array(void)
json_object *make_array()
{
json_object *my_array;

@@ -77,7 +71,7 @@ json_object *make_array(void)
}

void test_array_del_idx(void);
void test_array_del_idx(void)
void test_array_del_idx()
{
int rc;
size_t ii;
@@ -143,7 +137,7 @@ void test_array_del_idx(void)
}

void test_array_list_expand_internal(void);
void test_array_list_expand_internal(void)
void test_array_list_expand_internal()
{
int rc;
size_t ii;
@@ -256,7 +250,7 @@ int main(int argc, char **argv)
test_array_del_idx();
test_array_list_expand_internal();

my_array = json_object_new_array_ext(5);
my_array = json_object_new_array();
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));
@@ -311,34 +305,8 @@ int main(int argc, char **argv)
{
printf("\t%s: %s\n", key, json_object_to_json_string(val));
}

json_object *empty_array = json_object_new_array();
json_object *empty_obj = json_object_new_object();
json_object_object_add(my_object, "empty_array", empty_array);
json_object_object_add(my_object, "empty_obj", empty_obj);
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);


+ 1
- 1
tests/test1.expected View File

@@ -75,4 +75,4 @@ my_object=
foo: "bar"
bool0: false
bool1: true
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "empty_array": [ ], "empty_obj": { } }
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }

+ 1
- 1
tests/test1Formatted_plain.expected View File

@@ -75,4 +75,4 @@ my_object=
foo: "bar"
bool0: false
bool1: true
my_object.to_string()={"abc":12,"foo":"bar","bool0":false,"bool1":true,"empty_array":[],"empty_obj":{}}
my_object.to_string()={"abc":12,"foo":"bar","bool0":false,"bool1":true}

+ 1
- 3
tests/test1Formatted_pretty.expected View File

@@ -97,7 +97,5 @@ my_object.to_string()={
"abc":12,
"foo":"bar",
"bool0":false,
"bool1":true,
"empty_array":[],
"empty_obj":{}
"bool1":true
}

+ 1
- 1
tests/test1Formatted_spaced.expected View File

@@ -75,4 +75,4 @@ my_object=
foo: "bar"
bool0: false
bool1: true
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "empty_array": [ ], "empty_obj": { } }
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }

+ 1
- 3
tests/test1Formatted_spaced_pretty.expected View File

@@ -97,7 +97,5 @@ my_object.to_string()={
"abc": 12,
"foo": "bar",
"bool0": false,
"bool1": true,
"empty_array": [],
"empty_obj": {}
"bool1": true
}

+ 1
- 3
tests/test1Formatted_spaced_pretty_pretty_tab.expected View File

@@ -97,7 +97,5 @@ my_object.to_string()={
"abc": 12,
"foo": "bar",
"bool0": false,
"bool1": true,
"empty_array": [],
"empty_obj": {}
"bool1": true
}

+ 0
- 3
tests/test2.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>


+ 1
- 4
tests/test4.c View File

@@ -2,9 +2,6 @@
* gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson
*/

#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <assert.h>
#include <stdio.h>
@@ -31,7 +28,7 @@ void print_hex(const char *s)
}

static void test_lot_of_adds(void);
static void test_lot_of_adds(void)
static void test_lot_of_adds()
{
int ii;
char key[50];


+ 0
- 3
tests/testReplaceExisting.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>


+ 0
- 2
tests/test_basic.test View File

@@ -1,7 +1,5 @@
#!/bin/sh

export _JSON_C_STRERROR_ENABLE=1

# Common definitions
if test -z "$srcdir"; then
srcdir="${0%/*}"


+ 1
- 14
tests/test_cast.c View File

@@ -3,9 +3,6 @@
* Also checks the json_object_get_type and json_object_is_type functions.
*/

#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
@@ -31,11 +28,6 @@ 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 */
@@ -57,11 +49,6 @@ 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");
@@ -97,7 +84,7 @@ static void getit(struct json_object *new_obj, const char *field)
printf("new_obj.%s json_object_get_double()=%f\n", field, json_object_get_double(o));
}

static void checktype_header(void)
static void checktype_header()
{
printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n", json_type_to_name(json_type_null),
json_type_to_name(json_type_boolean), json_type_to_name(json_type_double),


+ 0
- 35
tests/test_cast.expected View File

@@ -7,11 +7,6 @@ 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
@@ -62,36 +57,6 @@ 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


+ 1
- 4
tests/test_charcase.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
@@ -22,7 +19,7 @@ int main(int argc, char **argv)
}

/* make sure only lowercase forms are parsed in strict mode */
static void test_case_parse(void)
static void test_case_parse()
{
struct json_tokener *tok;
json_object *new_obj;


+ 1
- 4
tests/test_compare.c View File

@@ -2,9 +2,6 @@
* Tests if json_object_equal behaves correct.
*/

#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <stdio.h>
#include <string.h>
@@ -12,7 +9,7 @@
#include "json_inttypes.h"
#include "json_object.h"

int main(int argc, char **argv)
int main()
{
/* integer tests */
struct json_object *int1 = json_object_new_int(0);


+ 3
- 3
tests/test_deep_copy.c View File

@@ -22,7 +22,7 @@ static const char *json_str1 =
" \"number\": 16446744073709551615,"
" \"title\": \"S\","
" \"null_obj\": null, "
" \"exist\": false,"
" \"exixt\": false,"
" \"quantity\":20,"
" \"univalent\":19.8,"
" \"GlossList\": {"
@@ -136,7 +136,7 @@ int main(int argc, char **argv)
assert(0 == json_object_deep_copy(src2, &dst2, NULL));
assert(0 == json_object_deep_copy(src3, &dst3, NULL));

printf("PASSED - all json_object_deep_copy() returned successful\n");
printf("PASSED - all json_object_deep_copy() returned succesful\n");

assert(-1 == json_object_deep_copy(src1, &dst1, NULL));
assert(errno == EINVAL);
@@ -151,7 +151,7 @@ int main(int argc, char **argv)
assert(1 == json_object_equal(src2, dst2));
assert(1 == json_object_equal(src3, dst3));

printf("PASSED - all json_object_equal() tests returned successful\n");
printf("PASSED - all json_object_equal() tests returned succesful\n");

assert(0 == strcmp(json_object_to_json_string_ext(src1, JSON_C_TO_STRING_PRETTY),
json_object_to_json_string_ext(dst1, JSON_C_TO_STRING_PRETTY)));


+ 3
- 3
tests/test_deep_copy.expected View File

@@ -1,7 +1,7 @@
PASSED - loaded input data
PASSED - all json_object_deep_copy() returned successful
PASSED - all json_object_deep_copy() returned succesful
PASSED - all json_object_deep_copy() returned EINVAL for non-null pointer
PASSED - all json_object_equal() tests returned successful
PASSED - all json_object_equal() tests returned succesful
PASSED - comparison of string output
PASSED - trying to overrwrite an object that has refcount > 1
Printing JSON objects for visual inspection
@@ -14,7 +14,7 @@ Printing JSON objects for visual inspection
"number":16446744073709551615,
"title":"S",
"null_obj":null,
"exist":false,
"exixt":false,
"quantity":20,
"univalent":19.8,
"GlossList":{


+ 1
- 4
tests/test_double_serializer.c View File

@@ -2,9 +2,6 @@
* Tests if the format string for double serialization is handled correctly
*/

#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <stdio.h>

@@ -14,7 +11,7 @@
/* Avoid compiler warnings about diving by constant zero */
double zero_dot_zero = 0.0;

int main(int argc, char **argv)
int main()
{
struct json_object *obj = json_object_new_double(0.5);
char udata[] = "test";


+ 0
- 3
tests/test_float.c View File

@@ -1,8 +1,5 @@
/* Copyright (C) 2016 by Rainer Gerhards
* Released under ASL 2.0 */
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include "json_object.h"
#include "json_tokener.h"


+ 0
- 3
tests/test_int_add.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>



+ 5
- 2
tests/test_json_pointer.c View File

@@ -1,8 +1,9 @@
#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>

@@ -124,7 +125,7 @@ static void test_example_get(void)
json_object_put(jo1);
}

/* I'm not too happy with the RFC example to test the recursion of the json_pointer_get() function */
/* I'm not too happy with the RFC example to test the recusion of the json_pointer_get() function */
static void test_recursion_get(void)
{
struct json_object *jo2, *jo1 = json_tokener_parse(rec_input_json_str);
@@ -319,6 +320,8 @@ 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();


+ 2
- 3
tests/test_locale.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
@@ -24,6 +21,8 @@ int main(int argc, char **argv)
json_object *new_obj;
#ifdef HAVE_SETLOCALE
setlocale(LC_NUMERIC, "de_DE");
#else
printf("No locale\n");
#endif

char buf1[10], buf2[10];


+ 0
- 3
tests/test_null.c View File

@@ -2,9 +2,6 @@
* Tests if binary strings are supported.
*/

#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <stdio.h>
#include <string.h>


+ 0
- 3
tests/test_object_iterator.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "config.h"
#include <stdio.h>
#include <stdlib.h>


+ 149
- 292
tests/test_parse.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
@@ -36,53 +33,6 @@ 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)
{
size_t 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;

new_obj = NULL;
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();
size_t 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;
@@ -92,11 +42,8 @@ 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(void)
static void test_basic_parse()
{
single_basic_parse("\"\003\"", 0);
single_basic_parse("/* hello */\"foo\"", 0);
@@ -146,18 +93,16 @@ static void test_basic_parse(void)

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);

/* 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)
/* ...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.
*/

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);
@@ -199,13 +144,13 @@ static void test_basic_parse(void)
single_basic_parse("[18446744073709551616]", 1);
}

static void test_utf8_parse(void)
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.
const char *utf8_bom = "\xEF\xBB\xBF";
const 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);
}
@@ -226,7 +171,7 @@ static int clear_serializer(json_object *jso, int flags, json_object *parent_jso
return JSON_C_VISIT_RETURN_CONTINUE;
}

static void test_verbose_parse(void)
static void test_verbose_parse()
{
json_object *new_obj;
enum json_tokener_error error = json_tokener_success;
@@ -256,85 +201,71 @@ 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 */
{"{ \"foo\": 123 }", -1, -1, json_tokener_success, 0, 0},
{"{ \"foo\": 456 }", -1, -1, json_tokener_success, 1, 0},
{"{ \"foo\": 789 }", -1, -1, json_tokener_success, 1, 0},
{"{ \"foo\": 123 }", -1, -1, json_tokener_success, 0},
{"{ \"foo\": 456 }", -1, -1, json_tokener_success, 1},
{"{ \"foo\": 789 }", -1, -1, json_tokener_success, 1},

/* Check the comment parse*/
{"/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0, 0},
{"/* hello */:/* hello */", -1, -1, json_tokener_continue, 0, 0},
{"\"bar\"/* hello */", -1, -1, json_tokener_continue, 0, 0},
{"}/* hello */", -1, -1, json_tokener_success, 1, 0},
{"/ hello ", -1, 1, json_tokener_error_parse_comment, 1, 0},
{"/* hello\"foo\"", -1, -1, json_tokener_continue, 1, 0},
{"/* hello*\"foo\"", -1, -1, json_tokener_continue, 1, 0},
{"// hello\"foo\"", -1, -1, json_tokener_continue, 1, 0},
{"/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0},
{"/* hello */:/* hello */", -1, -1, json_tokener_continue, 0},
{"\"bar\"/* hello */", -1, -1, json_tokener_continue, 0},
{"}/* hello */", -1, -1, json_tokener_success, 1},
{"/ hello ", -1, 1, json_tokener_error_parse_comment, 1},
{"/* hello\"foo\"", -1, -1, json_tokener_continue, 1},
{"/* hello*\"foo\"", -1, -1, json_tokener_continue, 1},
{"// hello\"foo\"", -1, -1, json_tokener_continue, 1},

/* Check a basic incremental parse */
{"{ \"foo", -1, -1, json_tokener_continue, 0, 0},
{"\": {\"bar", -1, -1, json_tokener_continue, 0, 0},
{"\":13}}", -1, -1, json_tokener_success, 1, 0},

/* 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.
*/
{"{ \"foo", -1, -1, json_tokener_continue, 0},
{"\": {\"bar", -1, -1, json_tokener_continue, 0},
{"\":13}}", -1, -1, json_tokener_success, 1},

/* Check the UTF-16 surrogate pair */
/* parse one char at every time */
{"\"\\", -1, -1, json_tokener_continue, 0, 0},
{"u", -1, -1, json_tokener_continue, 0, 0},
{"d", -1, -1, json_tokener_continue, 0, 0},
{"8", -1, -1, json_tokener_continue, 0, 0},
{"3", -1, -1, json_tokener_continue, 0, 0},
{"4", -1, -1, json_tokener_continue, 0, 0},
{"\\", -1, -1, json_tokener_continue, 0, 0},
{"u", -1, -1, json_tokener_continue, 0, 0},
{"d", -1, -1, json_tokener_continue, 0, 0},
{"d", -1, -1, json_tokener_continue, 0, 0},
{"1", -1, -1, json_tokener_continue, 0, 0},
{"e\"", -1, -1, json_tokener_success, 1, 0},
{"\"\\", -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, 0},
{"d8", -1, -1, json_tokener_continue, 0, 0},
{"34", -1, -1, json_tokener_continue, 0, 0},
{"\\u", -1, -1, json_tokener_continue, 0, 0},
{"dd", -1, -1, json_tokener_continue, 0, 0},
{"1e\"", -1, -1, json_tokener_success, 1, 0},
{"\"\\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, 0},
{"\\udd1e\"", -1, -1, json_tokener_success, 1, 0},
{"\"\\ud834\\", -1, -1, json_tokener_continue, 0, 0},
{"udd1e\"", -1, -1, json_tokener_success, 1, 0},
{"\"\\ud834\\u", -1, -1, json_tokener_continue, 0, 0},
{"dd1e\"", -1, -1, json_tokener_success, 1, 0},
{"\"fff \\ud834\\ud", -1, -1, json_tokener_continue, 0, 0},
{"d1e bar\"", -1, -1, json_tokener_success, 1, 0},
{"\"fff \\ud834\\udd", -1, -1, json_tokener_continue, 0, 0},
{"1e bar\"", -1, -1, json_tokener_success, 1, 0},

/* \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, 0},
{"00 bar\"", -1, -1, json_tokener_success, 1, 0},
{"\"\\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},

/* Check that json_tokener_reset actually resets */
{"{ \"foo", -1, -1, json_tokener_continue, 1, 0},
{": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1, 0},
{"{ \"foo", -1, -1, json_tokener_continue, 1},
{": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1},

/* Check incremental parsing with trailing characters */
{"{ \"foo", -1, -1, json_tokener_continue, 0, 0},
{"\": {\"bar", -1, -1, json_tokener_continue, 0, 0},
{"\":13}}XXXX", 10, 6, json_tokener_success, 0, 0},
{"XXXX", 4, 0, json_tokener_error_parse_unexpected, 1, 0},
{"{ \"foo", -1, -1, json_tokener_continue, 0},
{"\": {\"bar", -1, -1, json_tokener_continue, 0},
{"\":13}}XXXX", 10, 6, json_tokener_success, 0},
{"XXXX", 4, 0, json_tokener_error_parse_unexpected, 1},

/* Check that trailing characters can change w/o a reset */
{"{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0, 0},
{"\"Y\"", -1, -1, json_tokener_success, 1, 0},
{"{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0},
{"\"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},
@@ -346,205 +277,131 @@ struct incremental_step
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, 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, 0},
{"12{", 3, 2, json_tokener_success, 1, 0},
/* Parse number in strict mode */
{"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},

{"0e+0", 5, 4, json_tokener_success, 1, 0},
{"[0e+0]", -1, -1, json_tokener_success, 1, 0},

/* The behavior when missing the exponent varies slightly */
{"0e", 2, 2, json_tokener_continue, 1, 0},
{"0e", 3, 2, json_tokener_success, 1, 0},
{"0e", 3, 2, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT},
{"[0e]", -1, -1, json_tokener_success, 1, 0},
{"[0e]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},

{"0e+", 3, 3, json_tokener_continue, 1, 0},
{"0e+", 4, 3, json_tokener_success, 1, 0},
{"0e+", 4, 3, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT},
{"[0e+]", -1, -1, json_tokener_success, 1, 0},
{"[0e+]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},

{"0e-", 3, 3, json_tokener_continue, 1, 0},
{"0e-", 4, 3, json_tokener_success, 1, 0},
{"0e-", 4, 3, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT},
{"[0e-]", -1, -1, json_tokener_success, 1, 0},
{"[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, 0},
{"0e+-", 5, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
{"[0e+-]", -1, 4, json_tokener_error_parse_number, 1, 0},

/* Similar tests for other kinds of objects: */
/* These could all return success immediately, since regardless of
what follows the false/true/null token we *will* return a json object,
but it currently doesn't work that way. hmm... */
{"false", 5, 5, json_tokener_continue, 1, 0},
{"false", 6, 5, json_tokener_success, 1, 0},
{"true", 4, 4, json_tokener_continue, 1, 0},
{"true", 5, 4, json_tokener_success, 1, 0},
{"null", 4, 4, json_tokener_continue, 1, 0},
{"null", 5, 4, json_tokener_success, 1, 0},
{"Infinity", 9, 8, json_tokener_success, 1, 0},
{"infinity", 9, 8, json_tokener_success, 1, 0},
{"-infinity", 10, 9, json_tokener_success, 1, 0},
{"false", 5, 5, json_tokener_continue, 1},
{"false", 6, 5, json_tokener_success, 1},
{"true", 4, 4, json_tokener_continue, 1},
{"true", 5, 4, json_tokener_success, 1},
{"null", 4, 4, json_tokener_continue, 1},
{"null", 5, 4, json_tokener_success, 1},

{"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},

{"inf", 3, 3, json_tokener_continue, 0, 0},
{"inity", 6, 5, json_tokener_success, 1, 0},
{"-inf", 4, 4, json_tokener_continue, 0, 0},
{"inity", 6, 5, json_tokener_success, 1, 0},
{"inf", 3, 3, json_tokener_continue, 0},
{"inity", 6, 5, json_tokener_success, 1},
{"-inf", 4, 4, json_tokener_continue, 0},
{"inity", 6, 5, json_tokener_success, 1},

{"i", 1, 1, json_tokener_continue, 0, 0},
{"n", 1, 1, json_tokener_continue, 0, 0},
{"f", 1, 1, json_tokener_continue, 0, 0},
{"i", 1, 1, json_tokener_continue, 0, 0},
{"n", 1, 1, json_tokener_continue, 0, 0},
{"i", 1, 1, json_tokener_continue, 0, 0},
{"t", 1, 1, json_tokener_continue, 0, 0},
{"y", 1, 1, json_tokener_continue, 0, 0},
{"", 1, 0, json_tokener_success, 1, 0},
{"i", 1, 1, json_tokener_continue, 0},
{"n", 1, 1, json_tokener_continue, 0},
{"f", 1, 1, json_tokener_continue, 0},
{"i", 1, 1, json_tokener_continue, 0},
{"n", 1, 1, json_tokener_continue, 0},
{"i", 1, 1, json_tokener_continue, 0},
{"t", 1, 1, json_tokener_continue, 0},
{"y", 1, 1, json_tokener_continue, 0},
{"", 1, 0, json_tokener_success, 1},

{"-", 1, 1, json_tokener_continue, 0, 0},
{"inf", 3, 3, json_tokener_continue, 0, 0},
{"ini", 3, 3, json_tokener_continue, 0, 0},
{"ty", 3, 2, json_tokener_success, 1, 0},
{"-", 1, 1, json_tokener_continue, 0},
{"inf", 3, 3, json_tokener_continue, 0},
{"ini", 3, 3, json_tokener_continue, 0},
{"ty", 3, 2, json_tokener_success, 1},

{"-", 1, 1, json_tokener_continue, 0, 0},
{"i", 1, 1, json_tokener_continue, 0, 0},
{"nfini", 5, 5, json_tokener_continue, 0, 0},
{"ty", 3, 2, json_tokener_success, 1, 0},
{"-", 1, 1, json_tokener_continue, 0},
{"i", 1, 1, json_tokener_continue, 0},
{"nfini", 5, 5, json_tokener_continue, 0},
{"ty", 3, 2, json_tokener_success, 1},

{"-i", 2, 2, json_tokener_continue, 0, 0},
{"nfinity", 8, 7, json_tokener_success, 1, 0},
{"-i", 2, 2, json_tokener_continue, 0},
{"nfinity", 8, 7, json_tokener_success, 1},

{"InfinityX", 10, 8, json_tokener_success, 0, 0},
{"X", 1, 0, json_tokener_error_parse_unexpected, 1, 0},
{"InfinityX", 10, 8, json_tokener_success, 0},
{"X", 1, 0, json_tokener_error_parse_unexpected, 1},

{"Infinity1234", 13, 8, json_tokener_success, 0, 0},
{"1234", 5, 4, json_tokener_success, 1, 0},
{"Infinity1234", 13, 8, json_tokener_success, 0},
{"1234", 5, 4, json_tokener_success, 1},

{"Infinity9999", 8, 8, json_tokener_continue, 0, 0},
{"Infinity9999", 8, 8, json_tokener_continue, 0},

/* returns the Infinity loaded up by the previous call: */
{"1234", 5, 0, json_tokener_success, 0, 0},
{"1234", 5, 4, json_tokener_success, 1, 0},

/* INT64_MAX */
{"[9223372036854775807]", 22, 21, json_tokener_success, 1, 0},
/* INT64_MAX+1 => parsed as uint64 */
{"[9223372036854775808]", 22, 21, json_tokener_success, 1, 0},

/* INT64_MIN */
{"[-9223372036854775808]", 23, 22, json_tokener_success, 1, 0},

/* INT64_MIN-1 => success, but value ends up capped */
{"[-9223372036854775809]", 23, 22, json_tokener_success, 1, 0},

/* INT64_MIN-1 => failure due to underflow detected */
{"[-9223372036854775809]", 23, 21, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},

/* UINT64_MAX */
{"[18446744073709551615]", 23, 22, json_tokener_success, 1, 0},

/* UINT64_MAX+1 => success, but value ends up capped */
{"[18446744073709551616]", 23, 22, json_tokener_success, 1, 0},

/* UINT64_MAX+1 => failure due to overflow detected */
{"[18446744073709551616]", 23, 21, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},

/* XXX this seems like a bug, should fail with _error_parse_number instead */
{"18446744073709551616", 21, 20, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT},

/* Exceeding integer limits as double parse OK */
{"[9223372036854775808.0]", 24, 23, json_tokener_success, 1, 0},
{"[-9223372036854775809.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT},
{"[18446744073709551615.0]", 25, 24, json_tokener_success, 1, 0},
{"[18446744073709551616.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT},
{"1234", 5, 0, json_tokener_success, 0},
{"1234", 5, 4, json_tokener_success, 1},

/* offset=1 because "n" is the start of "null". hmm... */
{"noodle", 7, 1, json_tokener_error_parse_null, 1, 0},
{"noodle", 7, 1, json_tokener_error_parse_null, 1},
/* offset=2 because "na" is the start of "nan". hmm... */
{"naodle", 7, 2, json_tokener_error_parse_null, 1, 0},
{"naodle", 7, 2, json_tokener_error_parse_null, 1},
/* offset=2 because "tr" is the start of "true". hmm... */
{"track", 6, 2, json_tokener_error_parse_boolean, 1, 0},
{"fail", 5, 2, json_tokener_error_parse_boolean, 1, 0},
{"track", 6, 2, json_tokener_error_parse_boolean, 1},
{"fail", 5, 2, json_tokener_error_parse_boolean, 1},

/* Although they may initially look like they should fail,
* the next few tests check that parsing multiple sequential
* json objects in the input works as expected
*/
{"null123", 8, 4, json_tokener_success, 0, 0},
{&"null123"[4], 4, 3, json_tokener_success, 1, 0},
{"nullx", 6, 4, json_tokener_success, 0, 0},
{&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1, 0},
{"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0, 0},
{&"{\"a\":1}{\"b\":2}"[7], 8, 7, json_tokener_success, 1, 0},

/*
* 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, 0},
{&"2015-01-15"[4], 7, 3, json_tokener_success, 1, 0},
{&"2015-01-15"[7], 4, 3, json_tokener_success, 1, 0},
{&"2015 01 15"[0], 11, 5, json_tokener_success, 1, 0},
{&"2015 01 15"[4], 7, 4, json_tokener_success, 1, 0},
{&"2015 01 15"[7], 4, 3, json_tokener_success, 1, 0},
{"null123", 9, 4, json_tokener_success, 0},
{&"null123"[4], 4, 3, json_tokener_success, 1},
{"nullx", 5, 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},

/* Strings have a well defined end point, so we can stop at the quote */
{"\"blue\"", -1, -1, json_tokener_success, 0, 0},
{"\"blue\"", -1, -1, json_tokener_success, 0},

/* Check each of the escape sequences defined by the spec */
{"\"\\\"\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\\\\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\b\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\f\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\n\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\r\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\t\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\/\"", -1, -1, json_tokener_success, 0, 0},
{"\"\\\"\"", -1, -1, json_tokener_success, 0},
{"\"\\\\\"", -1, -1, json_tokener_success, 0},
{"\"\\b\"", -1, -1, json_tokener_success, 0},
{"\"\\f\"", -1, -1, json_tokener_success, 0},
{"\"\\n\"", -1, -1, json_tokener_success, 0},
{"\"\\r\"", -1, -1, json_tokener_success, 0},
{"\"\\t\"", -1, -1, json_tokener_success, 0},
{"\"\\/\"", -1, -1, json_tokener_success, 0},
// Escaping a forward slash is optional
{"\"/\"", -1, -1, json_tokener_success, 0, 0},
{"\"/\"", -1, -1, json_tokener_success, 0},
/* Check wrong escape sequences */
{"\"\\a\"", -1, 2, json_tokener_error_parse_string, 1, 0},
{"\"\\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},

/* Parse array/object */
{"[1,2,3]", -1, -1, json_tokener_success, 0, 0},
{"[1,2,3}", -1, 6, json_tokener_error_parse_array, 1, 0},
{"{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1, 0},
{"{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1, 0},
{"{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1, 0},
{"{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1, 0},
{"{\"a\":1,\"a\":2}", -1, -1, json_tokener_success, 1, 0},
{"\"a\":1}", -1, 3, json_tokener_success, 1, 0},
{"{\"a\":1", -1, -1, json_tokener_continue, 1, 0},
{"[,]", -1, 1, json_tokener_error_parse_unexpected, 1, 0},
{"[,1]", -1, 1, json_tokener_error_parse_unexpected, 1, 0},
{"[1,2,3]", -1, -1, json_tokener_success, 0},
{"[1,2,3}", -1, 6, json_tokener_error_parse_array, 1},
{"{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1},
{"{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1},
{"{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1},
{"{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1},
{"{\"a\":1,\"a\":2}", -1, -1, json_tokener_success, 1},
{"\"a\":1}", -1, 3, json_tokener_success, 1},
{"{\"a\":1", -1, -1, json_tokener_continue, 1},
{"[,]", -1, 1, json_tokener_error_parse_unexpected, 1},
{"[,1]", -1, 1, json_tokener_error_parse_unexpected, 1},

/* This behaviour doesn't entirely follow the json spec, but until we have
* a way to specify how strict to be we follow Postel's Law and be liberal
* in what we accept (up to a point).
*/
{"[1,2,3,]", -1, -1, json_tokener_success, 0, 0},
{"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0, 0},
{"[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},
@@ -553,24 +410,24 @@ struct incremental_step
// 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, 0},
{"\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, 0},
{"\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},
// 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, 5, json_tokener_success, 1, 0},
{"\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, 6, json_tokener_success, 1, 0},
{"\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,
@@ -578,7 +435,7 @@ struct incremental_step
{"\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, 0},
{"\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},
// char in escape unicode
@@ -595,10 +452,10 @@ struct incremental_step
{"\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, 0},
{NULL, -1, -1, json_tokener_success, 0},
};

static void test_incremental_parse(void)
static void test_incremental_parse()
{
json_object *new_obj;
enum json_tokener_error jerr;


+ 6
- 54
tests/test_parse.expected View File

@@ -40,13 +40,9 @@ 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)=12.3
new_obj.to_string(2015-01-15)=2015
new_obj.to_string(12.3.4)=null
new_obj.to_string(2015-01-15)=null
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
@@ -128,12 +124,6 @@ json_tokener_parse_ex(tok, "\ud834\ , 8) ... OK: got correct error: continu
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
@@ -149,26 +139,6 @@ 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
@@ -210,35 +180,17 @@ json_tokener_parse_ex(tok, 1234 , 5) ... OK: got object of type [int]:
json_tokener_parse_ex(tok, Infinity9999, 8) ... OK: got correct error: continue
json_tokener_parse_ex(tok, 1234 , 5) ... OK: got object of type [double]: Infinity
json_tokener_parse_ex(tok, 1234 , 5) ... OK: got object of type [int]: 1234
json_tokener_parse_ex(tok, [9223372036854775807], 22) ... OK: got object of type [array]: [ 9223372036854775807 ]
json_tokener_parse_ex(tok, [9223372036854775808], 22) ... OK: got object of type [array]: [ 9223372036854775808 ]
json_tokener_parse_ex(tok, [-9223372036854775808], 23) ... OK: got object of type [array]: [ -9223372036854775808 ]
json_tokener_parse_ex(tok, [-9223372036854775809], 23) ... OK: got object of type [array]: [ -9223372036854775808 ]
json_tokener_parse_ex(tok, [-9223372036854775809], 23) ... OK: got correct error: number expected
json_tokener_parse_ex(tok, [18446744073709551615], 23) ... OK: got object of type [array]: [ 18446744073709551615 ]
json_tokener_parse_ex(tok, [18446744073709551616], 23) ... OK: got object of type [array]: [ 18446744073709551615 ]
json_tokener_parse_ex(tok, [18446744073709551616], 23) ... OK: got correct error: number expected
json_tokener_parse_ex(tok, 18446744073709551616, 21) ... OK: got correct error: unexpected end of data
json_tokener_parse_ex(tok, [9223372036854775808.0], 24) ... OK: got object of type [array]: [ 9223372036854775808.0 ]
json_tokener_parse_ex(tok, [-9223372036854775809.0], 25) ... OK: got object of type [array]: [ -9223372036854775809.0 ]
json_tokener_parse_ex(tok, [18446744073709551615.0], 25) ... OK: got object of type [array]: [ 18446744073709551615.0 ]
json_tokener_parse_ex(tok, [18446744073709551616.0], 25) ... OK: got object of type [array]: [ 18446744073709551616.0 ]
json_tokener_parse_ex(tok, noodle , 7) ... OK: got correct error: null expected
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 , 8) ... OK: got object of type [null]: null
json_tokener_parse_ex(tok, null123 , 9) ... 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 , 6) ... OK: got object of type [null]: null
json_tokener_parse_ex(tok, nullx , 5) ... 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 , 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, 2015-01-15 , 10) ... OK: got correct error: number expected
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]: "\\"
@@ -288,5 +240,5 @@ json_tokener_parse_ex(tok, "\ud855
json_tokener_parse_ex(tok, "\ud0031À" , 10) ... OK: got correct error: invalid utf-8 string
json_tokener_parse_ex(tok, 11�11 , 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=198 ERROR=0
End Incremental Tests OK=154 ERROR=0
==================================

+ 1
- 4
tests/test_parse_int64.c View File

@@ -1,7 +1,4 @@

#ifdef NDEBUG
#undef NDEBUG
#endif
#include <stdio.h>
#include <string.h>

@@ -34,7 +31,7 @@ void checkit_uint(const char *buf)
* This always exits with a 0 exit value. The output should be compared
* against previously saved expected output.
*/
int main(int argc, char **argv)
int main()
{
char buf[100];



+ 2
- 5
tests/test_printbuf.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <limits.h>
#include <stddef.h>
@@ -19,7 +16,7 @@ static void test_printbuf_memset_length(void);
#define __func__ __FUNCTION__
#endif

static void test_basic_printbuf_memset(void)
static void test_basic_printbuf_memset()
{
struct printbuf *pb;

@@ -32,7 +29,7 @@ static void test_basic_printbuf_memset(void)
printf("%s: end test\n", __func__);
}

static void test_printbuf_memset_length(void)
static void test_printbuf_memset_length()
{
struct printbuf *pb;



+ 1
- 5
tests/test_set_serializer.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -76,8 +73,7 @@ int main(int argc, char **argv)
my_sub_object = json_object_new_double(1.0);
json_object_object_add(my_object, "double", my_sub_object);
printf("Check that the custom serializer does not include nul byte:\n");
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
json_object_set_serializer(my_sub_object, json_object_double_to_json_string, UNCONST("%125.0f"), NULL);
json_object_set_serializer(my_sub_object, json_object_double_to_json_string, "%125.0f,", NULL);
printf("my_object.to_string(custom serializer)=%s\n",
json_object_to_json_string_ext(my_object, JSON_C_TO_STRING_NOZERO));



+ 1
- 1
tests/test_set_serializer.expected View File

@@ -9,4 +9,4 @@ my_object.to_string(custom serializer)=Custom Output
Next line of output should be from the custom freeit function:
freeit, value=123
Check that the custom serializer does not include nul byte:
my_object.to_string(custom serializer)={"double": 1}
my_object.to_string(custom serializer)={"double": 1.}

+ 0
- 11
tests/test_set_value.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -71,14 +68,6 @@ int main(int argc, char **argv)
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);

// Set an empty string a couple times to try to trigger
// a case that used to leak memory.
json_object_set_string(tmp, "");
json_object_set_string(tmp, HUGE);
json_object_set_string(tmp, "");
json_object_set_string(tmp, HUGE);

json_object_put(tmp);
printf("STRING PASSED\n");



+ 10
- 11
tests/test_util_file.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "strerror_override.h"
#include "strerror_override_private.h"
#ifdef WIN32
@@ -38,7 +35,7 @@ static void test_read_fd_equal(const char *testdir);
#define PATH_MAX 256
#endif

static void test_write_to_file(void)
static void test_write_to_file()
{
json_object *jso;

@@ -93,7 +90,7 @@ static void test_write_to_file(void)
static void stat_and_cat(const char *file)
{
struct stat sb;
int d = open(file, O_RDONLY);
int d = open(file, O_RDONLY, 0600);
if (d < 0)
{
printf("FAIL: unable to open %s: %s\n", file, strerror(errno));
@@ -130,6 +127,8 @@ 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)
{
@@ -171,7 +170,7 @@ static void test_read_valid_with_fd(const char *testdir)
char filename[PATH_MAX];
(void)snprintf(filename, sizeof(filename), "%s/valid.json", testdir);

int d = open(filename, O_RDONLY);
int d = open(filename, O_RDONLY, 0);
if (d < 0)
{
fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno));
@@ -196,7 +195,7 @@ static void test_read_valid_nested_with_fd(const char *testdir)
char filename[PATH_MAX];
(void)snprintf(filename, sizeof(filename), "%s/valid_nested.json", testdir);

int d = open(filename, O_RDONLY);
int d = open(filename, O_RDONLY, 0);
if (d < 0)
{
fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno));
@@ -234,7 +233,7 @@ static void test_read_valid_nested_with_fd(const char *testdir)
close(d);
}

static void test_read_nonexistant(void)
static void test_read_nonexistant()
{
const char *filename = "./not_present.json";

@@ -252,10 +251,10 @@ static void test_read_nonexistant(void)
}
}

static void test_read_closed(void)
static void test_read_closed()
{
// Test reading from a closed fd
int d = open("/dev/null", O_RDONLY);
int d = open("/dev/null", O_RDONLY, 0);
if (d < 0)
{
puts("FAIL: unable to open");
@@ -290,7 +289,7 @@ static void test_read_fd_equal(const char *testdir)

json_object *jso = json_object_from_file(filename);

int d = open(filename, O_RDONLY);
int d = open(filename, O_RDONLY, 0);
if (d < 0)
{
fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno));


+ 1
- 1
tests/test_util_file.expected View File

@@ -4,7 +4,7 @@ OK: correctly unable to parse contents of valid_nested.json with low max depth:

OK: json_object_from_file(./not_present.json) correctly returned NULL: json_object_from_file: error opening file ./not_present.json: ERRNO=ENOENT

OK: json_object_from_fd(closed_fd), expecting NULL, EBADF, got:NULL, json_object_from_fd_ex: error reading fd 10: ERRNO=EBADF
OK: json_object_from_fd(closed_fd), expecting NULL, EBADF, got:NULL, json_object_from_fd: error reading fd 10: ERRNO=EBADF

OK: json_object_to_file(json.out, jso)=0
file[json.out], size=336, contents={"foo":1234,"foo1":"abcdefghijklmnopqrstuvwxyz","foo2":"abcdefghijklmnopqrstuvwxyz","foo3":"abcdefghijklmnopqrstuvwxyz","foo4":"abcdefghijklmnopqrstuvwxyz","foo5":"abcdefghijklmnopqrstuvwxyz","foo6":"abcdefghijklmnopqrstuvwxyz","foo7":"abcdefghijklmnopqrstuvwxyz","foo8":"abcdefghijklmnopqrstuvwxyz","foo9":"abcdefghijklmnopqrstuvwxyz"}


+ 0
- 3
tests/test_visit.c View File

@@ -1,6 +1,3 @@
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stddef.h>
#include <stdio.h>


+ 8
- 15
vasprintf_compat.h View File

@@ -8,10 +8,6 @@

#include "snprintf_compat.h"

#ifndef WIN32
#include <stdarg.h>
#endif /* !defined(WIN32) */
#include <stdint.h>
#include <stdlib.h>

#if !defined(HAVE_VASPRINTF)
@@ -20,7 +16,6 @@ static int vasprintf(char **buf, const char *fmt, va_list ap)
{
#ifndef WIN32
static char _T_emptybuffer = '\0';
va_list ap2;
#endif /* !defined(WIN32) */
int chars;
char *b;
@@ -31,21 +26,19 @@ static int vasprintf(char **buf, const char *fmt, va_list ap)
}

#ifdef WIN32
chars = _vscprintf(fmt, ap);
chars = _vscprintf(fmt, ap) + 1;
#else /* !defined(WIN32) */
/* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
* our buffer like on some 64bit sun systems... but hey, it's time to move on
* our buffer like on some 64bit sun systems.... but hey, its time to move on
*/
va_copy(ap2, ap);
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap2);
va_end(ap2);
#endif /* defined(WIN32) */
if (chars < 0 || (size_t)chars + 1 > SIZE_MAX / sizeof(char))
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap) + 1;
if (chars < 0)
{
return -1;
}
chars *= -1;
} /* CAW: old glibc versions have this problem */
#endif /* defined(WIN32) */

b = (char *)malloc(sizeof(char) * ((size_t)chars + 1));
b = (char *)malloc(sizeof(char) * chars);
if (!b)
{
return -1;


Loading…
Cancel
Save