Compare commits

...

54 commits

Author SHA1 Message Date
Petri Lehtinen
96d160df90
Merge pull request #692 from Andrew-Au/cmake_update/revised/merge
Some checks failed
tests / autotools (clang, no, macos-latest) (push) Has been cancelled
tests / autotools (clang, yes, macos-latest) (push) Has been cancelled
tests / autotools (gcc, no, macos-latest) (push) Has been cancelled
tests / autotools (gcc, yes, macos-latest) (push) Has been cancelled
tests / cmake (clang, macos-latest) (push) Has been cancelled
tests / cmake (gcc, macos-latest) (push) Has been cancelled
tests / cmake (msvc, windows-latest) (push) Has been cancelled
tests / lint (push) Failing after 4s
tests / autotools (clang, no, ubuntu-latest) (push) Failing after 3s
tests / autotools (clang, yes, ubuntu-latest) (push) Failing after 3s
tests / autotools (gcc, no, ubuntu-latest) (push) Failing after 3s
tests / autotools (gcc, yes, ubuntu-latest) (push) Failing after 3s
tests / cmake (clang, ubuntu-latest) (push) Successful in 23s
tests / cmake (gcc, ubuntu-latest) (push) Successful in 20s
tests / valgrind (push) Failing after 17m10s
Use target-based cmake settings
2025-04-04 07:18:04 +03:00
Petri Lehtinen
aef13f87f1 Set minimum cmake version to 3.10 2025-04-04 07:15:20 +03:00
Petri Lehtinen
c16ac732e4
Merge pull request #712 from akheron/fix-lint
Some checks failed
tests / lint (push) Failing after 31s
tests / autotools (clang, no, ubuntu-latest) (push) Failing after 30s
tests / autotools (clang, yes, ubuntu-latest) (push) Failing after 29s
tests / autotools (gcc, no, ubuntu-latest) (push) Failing after 30s
tests / autotools (gcc, yes, ubuntu-latest) (push) Failing after 28s
tests / cmake (clang, ubuntu-latest) (push) Failing after 39s
tests / cmake (gcc, ubuntu-latest) (push) Failing after 39s
tests / valgrind (push) Failing after 35s
tests / cmake (msvc, windows-latest) (push) Has been cancelled
tests / autotools (gcc, yes, macos-latest) (push) Has been cancelled
tests / cmake (clang, macos-latest) (push) Has been cancelled
tests / cmake (gcc, macos-latest) (push) Has been cancelled
tests / autotools (gcc, no, macos-latest) (push) Has been cancelled
tests / autotools (clang, no, macos-latest) (push) Has been cancelled
tests / autotools (clang, yes, macos-latest) (push) Has been cancelled
Fix code formatting
2025-03-23 22:39:12 +02:00
Petri Lehtinen
05a10aa8af Fix code formatting 2025-03-23 22:31:56 +02:00
Petri Lehtinen
4d7ac97b89
Merge pull request #710 from akheron/fix-readthedocs
Add readthedocs config
2025-03-23 21:59:36 +02:00
Petri Lehtinen
23905f372c Add readthedocs config 2025-03-23 21:58:05 +02:00
Petri Lehtinen
ed5cae4ed0 jansson 2.14.1
Some checks failed
tests / lint (push) Failing after 28s
tests / autotools (clang, no, ubuntu-latest) (push) Failing after 32s
tests / autotools (clang, yes, ubuntu-latest) (push) Failing after 30s
tests / autotools (gcc, no, ubuntu-latest) (push) Failing after 39s
tests / autotools (gcc, yes, ubuntu-latest) (push) Failing after 26s
tests / cmake (clang, ubuntu-latest) (push) Failing after 31s
tests / cmake (gcc, ubuntu-latest) (push) Failing after 23s
tests / valgrind (push) Failing after 29s
tests / autotools (gcc, yes, macos-latest) (push) Has been cancelled
tests / cmake (clang, macos-latest) (push) Has been cancelled
tests / cmake (gcc, macos-latest) (push) Has been cancelled
tests / cmake (msvc, windows-latest) (push) Has been cancelled
tests / autotools (clang, no, macos-latest) (push) Has been cancelled
tests / autotools (clang, yes, macos-latest) (push) Has been cancelled
tests / autotools (gcc, no, macos-latest) (push) Has been cancelled
2025-03-23 14:25:44 +02:00
Andrew White
0f9c18dd12 Use target-based cmake settings
- Update minimum required to CMake version 3.5 (versions older than 3.5 are
deprecated as of 3.27)
- update add_definitions to target_compile_definitions
- use target_include_directories for public library includes
- add jansson::jansson alias
2024-07-10 10:31:49 +10:00
Petri Lehtinen
61fc3d0e28
Merge pull request #686 from akheron/readme-badges
Update badges in README
2024-03-31 22:09:15 +03:00
Petri Lehtinen
cce8caba26 Update badges in README 2024-03-31 22:08:10 +03:00
Petri Lehtinen
50953fb1fa
Merge pull request #680 from akheron/dtoa
Use `dtoa()` for optimal encoding of reals
2024-03-31 22:02:09 +03:00
Petri Lehtinen
c780171cf3 Update CHANGES 2024-03-25 20:19:41 +02:00
Petri Lehtinen
2297a2e320 Update LICENSE to add an exception for src/dtoa.c 2024-03-25 20:19:23 +02:00
Petri Lehtinen
f5b3ab323c Add more tests 2024-03-25 20:08:23 +02:00
Petri Lehtinen
9d3abab610 Test with and without dtoa in CI 2024-03-25 20:08:23 +02:00
Petri Lehtinen
9699de8600 Fix tests 2024-03-25 20:08:23 +02:00
Petri Lehtinen
33a6c95d56 Fix compiler warnings 2024-03-25 20:08:23 +02:00
Petri Lehtinen
ed06f65412 Rename a symbol to avoid collision on Windows 2024-03-25 20:08:23 +02:00
Petri Lehtinen
8b975abca1 Use dtoa for double to string conversion 2024-03-25 20:08:23 +02:00
Petri Lehtinen
8660da0f7c
Merge pull request #685 from akheron/simplify-tests
Simplify tests even more
2024-03-25 20:07:53 +02:00
Petri Lehtinen
dcbeb58829 Simplify tests even more
Drop the useless `export` lines from `env` files.
2024-03-25 19:16:34 +02:00
Petri Lehtinen
53383b9e26
Merge pull request #683 from akheron/refactor-tests
Refactor tests
2024-03-21 20:43:31 +02:00
Petri Lehtinen
649c9357c6 Update CHANGES 2024-03-21 20:43:04 +02:00
Petri Lehtinen
73dc6960ad Show ctest output on failure in CI 2024-03-21 20:36:42 +02:00
Petri Lehtinen
88375fb10e Refactor tests to work better with CMake 2024-03-21 20:36:38 +02:00
Petri Lehtinen
0247b5e2e7 Improve clang-format scripts 2024-03-15 21:06:34 +02:00
Petri Lehtinen
842708ac0c
Merge pull request #677 from akheron/ditch-localeconv
Use sprintf() to determine locale's decimal point
2024-03-08 21:53:07 +02:00
Petri Lehtinen
2d1c13224f Use sprintf() to determine locale's decimal point
This should fix thread safety of encoding and decoding, since
localeconv() is not tread safe after all.
2024-03-08 21:36:21 +02:00
Petri Lehtinen
9b9b5e81cf
Merge pull request #679 from akheron/dependabot/github_actions/github-actions-cb1dee63db
Bump the github-actions group with 1 update
2024-03-08 06:42:02 +02:00
dependabot[bot]
0c9c11a89d
Bump the github-actions group with 1 update
Bumps the github-actions group with 1 update: [actions/upload-artifact](https://github.com/actions/upload-artifact).


Updates `actions/upload-artifact` from 3 to 4
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-07 20:09:47 +00:00
Petri Lehtinen
f52d79a4d3
Merge pull request #672 from pnacht/add-dependabot
Add dependabot, update GitHub Actions
2024-03-07 22:09:25 +02:00
Petri Lehtinen
2f1777ba80
Merge branch 'master' into add-dependabot 2024-03-07 22:08:46 +02:00
Petri Lehtinen
1e57cadbd3
Merge pull request #678 from akheron/ditch-coveralls
Ditch coveralls
2024-03-07 21:54:05 +02:00
Petri Lehtinen
0db4db1048 Ditch coveralls 2024-03-07 21:47:18 +02:00
Pedro Kaj Kjellerup Nacht
73d968feef
Bump GHA versions
Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
2023-12-06 23:10:14 +00:00
Pedro Kaj Kjellerup Nacht
0154c4af07
Add dependabot to update GHA
Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
2023-12-06 23:10:03 +00:00
Petri Lehtinen
60097f0096
Create SECURITY.md 2023-06-28 07:42:28 +03:00
Petri Lehtinen
bde28463f8
Merge pull request #646 from Bigpet/patch-1
Remove unused ${SOURCE_DIR}/include include path
2023-03-29 22:07:32 +03:00
Peter Tissen
e7c9ef8e52
Remove unused ${SOURCE_DIR}/include include path
The directory `${CMAKE_CURRENT_SOURCE_DIR}/include` is never created or used. Except in case of an in-source build but then  `${CMAKE_CURRENT_BINARY_DIR}/include` would be the same, so it would only duplicate the correct entry.

Not sure if the intermediary `JANSSON__INCLUDE_DIRS` is still necessary but I thought I'd change as little as possible.

The reason for eliminating this is that when you use CLion and sync into a docker container it will try to copy all include dirs back. Non-existant paths cause warnings every time.
2023-03-29 12:44:28 +02:00
Petri Lehtinen
a22dc95311
Merge pull request #640 from uniontech-lilinjie/master
fix typo
2023-01-11 22:25:45 +02:00
lilinjie
a7d04c8554 fix typo
Signed-off-by: lilinjie <lilinjie@uniontech.com>
2023-01-10 16:35:44 +08:00
Petri Lehtinen
e23f558007
Merge pull request #628 from neheb/patch-1
hashtable: change to ifdef
2022-08-24 17:10:48 +03:00
Rosen Penev
1894366598
hashtable: change to ifdef
All other usages use ifdef.
2022-08-22 18:13:57 -07:00
Petri Lehtinen
7e04530916 Remove the confusing vcpkg ad from README 2022-08-09 22:24:38 +03:00
Petri Lehtinen
011e625769
Merge pull request #626 from akheron/fix-example
Add a missing json_decref in the example
2022-08-09 22:05:05 +03:00
Petri Lehtinen
de5f2963ab Add a missing json_decref in the example 2022-08-09 22:00:45 +03:00
Petri Lehtinen
128e9c5f37
Merge pull request #610 from Thomas1664/master
Fix overwriting linker flags
2022-05-03 05:48:09 +03:00
Thomas Heinrichs
fe6e8eec7e Fix overwriting linker flags 2022-04-28 17:36:54 +02:00
Petri Lehtinen
addeeef408 Add some links to README 2021-11-22 16:30:12 +02:00
Petri Lehtinen
d82b436b2f
Merge pull request #598 from Mephistophiles/remove_internal_strlen
Reduce strlen's in jansson internals
2021-11-21 07:38:59 +02:00
Maxim Zhukov
586b4461e6 tests: add some cases in fixed size test
Signed-off-by: Maxim Zhukov <mussitantesmortem@gmail.com>
2021-11-20 22:57:10 +03:00
Maxim Zhukov
78418c84f1 value, pack: use key length from json_object iternals
Reduce the number of strlen calls in the jansson backend.

Test on my laptop (count of the instructions)

  Before:
  ❯ valgrind --tool=callgrind ./bin/test_object
  ==3105045== Events    : Ir
  ==3105045== Collected : 441453

  After:
  ❯ valgrind --tool=callgrind ./bin/test_object
  ==3144451== Events    : Ir
  ==3144451== Collected : 440597

Signed-off-by: Maxim Zhukov <mussitantesmortem@gmail.com>
2021-11-20 22:47:14 +03:00
Petri Lehtinen
eb81670881
Create CONTRIBUTING.md 2021-09-12 18:37:43 +03:00
Petri Lehtinen
0677666f65 Fix the check-exports tests for versioned symbols 2021-09-09 21:55:27 +03:00
55 changed files with 6693 additions and 352 deletions

15
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"

View file

@ -24,7 +24,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts

View file

@ -10,7 +10,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- run: ./scripts/clang-format-check
autotools:
@ -18,18 +18,19 @@ jobs:
matrix:
os: ["ubuntu-latest", "macos-latest"]
cc: ["gcc", "clang"]
dtoa: ["yes", "no"]
runs-on: ${{matrix.os}}
runs-on: ${{ matrix.os }}
steps:
- if: ${{runner.os == 'macOS'}}
run: brew install autoconf automake libtool
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- run: autoreconf -fi
- env:
CC: ${{matrix.cc}}
CC: ${{ matrix.cc }}
CFLAGS: -Werror
run: ./configure
run: ./configure --enable-dtoa=${{ matrix.dtoa }}
- run: make check
cmake:
@ -49,32 +50,18 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- env:
CC: ${{matrix.cc}}
run: cmake .
- run: cmake --build .
- run: ctest
- run: ctest --output-on-failure
valgrind:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- run: sudo apt update && sudo apt install valgrind
- run: cmake -DJANSSON_TEST_WITH_VALGRIND=ON .
- run: cmake --build .
- run: ctest
coveralls:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: sudo apt update && sudo apt install curl lcov
- run: cmake -DJANSSON_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug .
- run: cmake --build .
- run: cmake --build . --target coverage
- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: coverage.info
- run: ctest --output-on-failure

24
CHANGES
View file

@ -1,3 +1,25 @@
Version 2.14.1
==============
Released 2025-03-23
* Fixes:
- Fix thread safety of encoding and decoding when `uselocale` or `newlocale`
is used to switch locales inside the threads (#674, #675, #677. Thanks to
Bruno Haible for the report and help with fixing.)
- Use David M. Gay's `dtoa()` algorithm to avoid misprinting issues of real
numbers that are not exactly representable as a `double` (#680).
If this is not desirable, use `./configure --disable-dtoa` or `cmake
-DUSE_DTOA=OFF .`
* Build:
- Make test output nicer in CMake based builds (#683)
- Simplify tests (#685)
Version 2.14
============
@ -616,7 +638,7 @@ Released 2011-10-06
- Fix identifier decoding under non-UTF-8 locales. (#35)
- `json_load_file()`: Open the input file in binary mode for maximum
compatiblity.
compatibility.
* Documentation:

View file

@ -1,10 +1,11 @@
cmake_minimum_required (VERSION 3.1)
cmake_minimum_required (VERSION 3.10)
project(jansson C)
# Options
option(JANSSON_BUILD_SHARED_LIBS "Build shared libraries." OFF)
option(USE_URANDOM "Use /dev/urandom to seed the hash function." ON)
option(USE_WINDOWS_CRYPTOAPI "Use CryptGenRandom to seed the hash function." ON)
option(USE_DTOA "Use dtoa for optimal floating-point to string conversions." ON)
if (MSVC)
# This option must match the settings used in your program, in particular if you
@ -35,7 +36,7 @@ endif()
# set (JANSSON_VERSION "2.3.1")
# set (JANSSON_SOVERSION 2)
set(JANSSON_DISPLAY_VERSION "2.14")
set(JANSSON_DISPLAY_VERSION "2.14.1")
# This is what is required to match the same numbers as automake's
set(JANSSON_VERSION "4.14.0")
@ -93,6 +94,9 @@ check_function_exists (sched_yield HAVE_SCHED_YIELD)
# Check for the int-type includes
check_include_files (stdint.h HAVE_STDINT_H)
include (TestBigEndian)
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
# Check our 64 bit integer sizes
check_type_size (__int64 __INT64)
check_type_size (int64_t INT64_T)
@ -193,6 +197,8 @@ endif ()
# detect what to use for the 64 bit type.
# Note: I will prefer long long if I can get it, as that is what the automake system aimed for.
if (NOT DEFINED JSON_INT_T)
set (JSON_INTEGER_IS_LONG_LONG 1)
if (HAVE_LONG_LONG_INT AND (LONG_LONG_INT EQUAL 8))
set (JSON_INT_T "long long")
elseif (HAVE_INT64_T)
@ -215,18 +221,7 @@ if (NOT DEFINED JSON_INT_T)
endif ()
endif ()
# If locale.h and localeconv() are available, define to 1, otherwise to 0.
check_include_files (locale.h HAVE_LOCALE_H)
check_function_exists (localeconv HAVE_LOCALECONV)
if (HAVE_LOCALECONV AND HAVE_LOCALE_H)
set (JSON_HAVE_LOCALECONV 1)
else ()
set (JSON_HAVE_LOCALECONV 0)
endif()
# check if we have setlocale
check_function_exists(setlocale HAVE_SETLOCALE)
# Check what the inline keyword is.
@ -271,20 +266,20 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_config.h.cmake
file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/)
add_definitions(-DJANSSON_USING_CMAKE)
# configure the private config file
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_private_config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/private_include/jansson_private_config.h)
# and tell the source code to include it
add_definitions(-DHAVE_CONFIG_H)
include_directories (${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories (${CMAKE_CURRENT_BINARY_DIR}/private_include)
# Configuration flags will be set on project later once we have defined the target
# Add the lib sources.
file(GLOB JANSSON_SRC src/*.c)
if (NOT USE_DTOA)
list(FILTER JANSSON_SRC EXCLUDE REGEX ".*dtoa\\.c$")
endif()
set(JANSSON_HDR_PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/hashtable.h
@ -342,7 +337,7 @@ if(JANSSON_BUILD_SHARED_LIBS)
)
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/jansson.sym")
if (VSCRIPT_WORKS)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/jansson.sym")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/jansson.sym")
endif()
endif()
@ -358,6 +353,20 @@ else()
POSITION_INDEPENDENT_CODE true)
endif()
# Now target jansson is declared, set per-target values
target_compile_definitions(jansson PUBLIC JANSSON_USING_CMAKE)
target_compile_definitions(jansson PRIVATE HAVE_CONFIG_H)
target_include_directories(jansson
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
INTERFACE $<INSTALL_INTERFACE:include>
)
add_library( jansson::jansson ALIAS jansson )
if (JANSSON_EXAMPLES)
add_executable(simple_parse "${CMAKE_CURRENT_SOURCE_DIR}/examples/simple_parse.c")
target_link_libraries(simple_parse jansson)
@ -537,6 +546,11 @@ if (NOT JANSSON_WITHOUT_TESTS)
if (IS_DIRECTORY ${TESTDIR})
get_filename_component(TNAME ${TESTDIR} NAME)
if ((USE_DTOA AND EXISTS ${TESTDIR}/skip_if_dtoa) OR
(NOT USE_DTOA AND EXISTS ${TESTDIR}/skip_unless_dtoa))
continue()
endif()
if (JANSSON_TEST_WITH_VALGRIND)
add_test(memcheck__${SUITE}__${TNAME}
${MEMCHECK_COMMAND} ${SUITE_TEST_CMD} ${TESTDIR})
@ -602,9 +616,7 @@ foreach(p LIB BIN INCLUDE CMAKE)
endforeach()
# Generate the config file for the build-tree.
set(JANSSON__INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_BINARY_DIR}/include")
set(JANSSON__INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/include")
set(JANSSON_INCLUDE_DIRS ${JANSSON__INCLUDE_DIRS} CACHE PATH "Jansson include directories")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/janssonConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/janssonConfig.cmake

3
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,3 @@
Hi, and thanks for contributing!
Please remember to add tests and documentation for new functionality. Backwards incompatible changes or features that are not directly related to JSON are likely to be rejected.

26
LICENSE
View file

@ -1,4 +1,11 @@
Copyright (c) 2009-2020 Petri Lehtinen <petri@digip.org>
# License
This project is licensed under the MIT license, except where otherwise noted.
The full text of the MIT license is included below.
## MIT License
Copyright (c) 2009-2024 Petri Lehtinen <petri@digip.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -17,3 +24,20 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## Exceptions
### `src/dtoa.c`
Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice
is included in all copies of any software which is or includes a copy
or modification of this software and in all copies of the supporting
documentation for such software.
THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.

View file

@ -1,14 +1,10 @@
Jansson README
==============
.. image:: https://github.com/akheron/jansson/workflows/tests/badge.svg
:target: https://github.com/akheron/jansson/actions
.. |tests| image:: https://github.com/akheron/jansson/workflows/tests/badge.svg
.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/lmhkkc4q8cwc65ko
.. image:: https://ci.appveyor.com/api/projects/status/lmhkkc4q8cwc65ko
:target: https://ci.appveyor.com/project/akheron/jansson
.. image:: https://coveralls.io/repos/akheron/jansson/badge.png?branch=master
:target: https://coveralls.io/r/akheron/jansson?branch=master
|tests| |appveyor|
Jansson_ is a C library for encoding, decoding and manipulating JSON
data. Its main features and design principles are:
@ -26,24 +22,11 @@ data. Its main features and design principles are:
Jansson is licensed under the `MIT license`_; see LICENSE in the
source distribution for details.
Compilation and Installation
----------------------------
You can download and install Jansson using the `vcpkg <https://github.com/Microsoft/vcpkg/>`_ dependency manager:
.. code-block:: bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install jansson
The Jansson port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please `create an issue or pull request <https://github.com/Microsoft/vcpkg/>`_ on the vcpkg repository.
If you obtained a `source tarball`_ from the "Releases" section of the main
site just use the standard autotools commands::
If you obtained a ``jansson-X.Y.tar.*`` tarball from GitHub Releases, just use
the standard autotools commands::
$ ./configure
$ make
@ -53,9 +36,8 @@ To run the test suite, invoke::
$ make check
If the source has been checked out from a Git repository, the
./configure script has to be generated first. The easiest way is to
use autoreconf::
If the source has been checked out from a Git repository, the ``configure``
script has to be generated first. The easiest way is to use autoreconf::
$ autoreconf -i
@ -74,8 +56,15 @@ Then, point your browser to ``doc/_build/html/index.html``. Sphinx_
1.0 or newer is required to generate the documentation.
Community
---------
* `Documentation <http://jansson.readthedocs.io/en/latest/>`_
* `Issue tracker <https://github.com/akheron/jansson/issues>`_
* `Mailing list <http://groups.google.com/group/jansson-users>`_
* `Wiki <https://github.com/akheron/jansson/wiki>`_ contains some development documentation
.. _Jansson: http://www.digip.org/jansson/
.. _`Comprehensive documentation`: http://jansson.readthedocs.io/en/latest/
.. _`MIT license`: http://www.opensource.org/licenses/mit-license.php
.. _`source tarball`: http://www.digip.org/jansson#releases
.. _Sphinx: http://sphinx.pocoo.org/

9
SECURITY.md Normal file
View file

@ -0,0 +1,9 @@
# Security Policy
## Supported Versions
Latest released version.
## Reporting a Vulnerability
Send an email to petri@digip.org.

View file

@ -32,10 +32,6 @@
otherwise to 0. */
#define JSON_INTEGER_IS_LONG_LONG 1
/* If locale.h and localeconv() are available, define to 1,
otherwise to 0. */
#define JSON_HAVE_LOCALECONV 0
/* Maximum recursion depth for parsing JSON input.
This limits the depth of e.g. array-within-array constructions. */
#define JSON_PARSER_MAX_DEPTH 2048

View file

@ -21,9 +21,10 @@
#define JANSSON_USING_CMAKE
#endif
/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used,
* as we will also check for __int64 etc types.
* (the definition was used in the automake system) */
/* If your compiler supports the `long long` type and the strtoll()
library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
otherwise to 0. */
#cmakedefine JSON_INTEGER_IS_LONG_LONG 1
/* Bring in the cmake-detected defines */
#cmakedefine HAVE_STDINT_H 1
@ -56,9 +57,6 @@
#define JSON_INTEGER_FORMAT @JSON_INTEGER_FORMAT@
/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */
#define JSON_HAVE_LOCALECONV @JSON_HAVE_LOCALECONV@
/* If __atomic builtins are available they will be used to manage
reference counts of json_t. */
#define JSON_HAVE_ATOMIC_BUILTINS @JSON_HAVE_ATOMIC_BUILTINS@

View file

@ -21,6 +21,8 @@
#cmakedefine HAVE_LOCALE_H 1
#cmakedefine HAVE_SETLOCALE 1
#cmakedefine WORDS_BIGENDIAN 1
#cmakedefine HAVE_INT32_T 1
#ifndef HAVE_INT32_T
# define int32_t @JSON_INT32@
@ -50,4 +52,11 @@
#cmakedefine USE_URANDOM 1
#cmakedefine USE_WINDOWS_CRYPTOAPI 1
#cmakedefine USE_DTOA 1
#if USE_DTOA
# define DTOA_ENABLED 1
#else
# define DTOA_ENABLED 0
#endif
#define INITIAL_HASHTABLE_ORDER @JANSSON_INITIAL_HASHTABLE_ORDER@

View file

@ -1,5 +1,5 @@
AC_PREREQ([2.60])
AC_INIT([jansson], [2.14], [https://github.com/akheron/jansson/issues])
AC_INIT([jansson], [2.14.1], [https://github.com/akheron/jansson/issues])
AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE([1.10 foreign])
@ -25,6 +25,8 @@ AC_TYPE_UINT16_T
AC_TYPE_UINT8_T
AC_TYPE_LONG_LONG_INT
AC_C_BIGENDIAN
AC_C_INLINE
case $ac_cv_c_inline in
yes) json_inline=inline;;
@ -34,7 +36,7 @@ esac
AC_SUBST([json_inline])
# Checks for library functions.
AC_CHECK_FUNCS([close getpid gettimeofday localeconv open read sched_yield strtoll])
AC_CHECK_FUNCS([close getpid gettimeofday open read setlocale sched_yield strtoll])
AC_MSG_CHECKING([for gcc __sync builtins])
have_sync_builtins=no
@ -74,12 +76,6 @@ case "$ac_cv_type_long_long_int$ac_cv_func_strtoll" in
esac
AC_SUBST([json_have_long_long])
case "$ac_cv_header_locale_h$ac_cv_func_localeconv" in
yesyes) json_have_localeconv=1;;
*) json_have_localeconv=0;;
esac
AC_SUBST([json_have_localeconv])
# Features
AC_ARG_ENABLE([urandom],
[AS_HELP_STRING([--disable-urandom],
@ -142,6 +138,19 @@ JSON_SYMVER_LDFLAGS=
AC_CHECK_DECL([__GLIBC__], [JSON_SYMVER_LDFLAGS=-Wl,--default-symver])
AC_SUBST([JSON_SYMVER_LDFLAGS])
AC_ARG_ENABLE([dtoa],
[AS_HELP_STRING([--enable-dtoa], [Use dtoa for optimal floating point to string conversion])],
[case "$enableval" in
yes) dtoa=yes ;;
no) dtoa=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-dtoa]) ;;
esac], [dtoa=yes])
if test "$dtoa" = "yes"; then
AC_DEFINE([DTOA_ENABLED], [1],
[Define to 1 to use dtoa to convert floating points to strings])
fi
AM_CONDITIONAL([DTOA_ENABLED], [test "$dtoa" = "yes"])
AC_ARG_ENABLE([ossfuzzers],
[AS_HELP_STRING([--enable-ossfuzzers],
[Whether to generate the fuzzers for OSS-Fuzz])],

9
doc/.readthedocs.yaml Normal file
View file

@ -0,0 +1,9 @@
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
sphinx:
configuration: doc/conf.py

View file

@ -48,7 +48,7 @@ copyright = u'2009-2020, Petri Lehtinen'
# built documents.
#
# The short X.Y version.
version = '2.14'
version = '2.14.1'
# The full version, including alpha/beta/rc tags.
release = version

View file

@ -153,6 +153,7 @@ int main(int argc, char *argv[]) {
sha = json_object_get(data, "sha");
if (!json_is_string(sha)) {
fprintf(stderr, "error: commit %d: sha is not a string\n", (int)(i + 1));
json_decref(root);
return 1;
}

View file

@ -1,3 +1,3 @@
#!/bin/bash
find . -type f -a '(' -name '*.c' -o -name '*.h' ')' | xargs clang-format -i
git ls-files | grep '\.[ch]$' | xargs clang-format -i

View file

@ -12,13 +12,16 @@ fi
errors=0
paths=$(git ls-files | grep '\.[ch]$')
for path in $paths; do
echo "Checking $path"
$CLANG_FORMAT $path > $path.formatted
in=$(cat $path)
out=$($CLANG_FORMAT $path)
out=$(cat $path.formatted)
if [ "$in" != "$out" ]; then
diff -u -L $path -L "$path.formatted" $path - <<<$out
diff -u $path $path.formatted
errors=1
fi
rm $path.formatted
done
if [ $errors -ne 0 ]; then

View file

@ -1,4 +1,4 @@
EXTRA_DIST = jansson.def
EXTRA_DIST = jansson.def dtoa.c
include_HEADERS = jansson.h
nodist_include_HEADERS = jansson_config.h
@ -22,9 +22,14 @@ libjansson_la_SOURCES = \
utf.h \
value.c \
version.c
if DTOA_ENABLED
libjansson_la_SOURCES += dtoa.c
endif
libjansson_la_LDFLAGS = \
-no-undefined \
-export-symbols-regex '^json_|^jansson_' \
-version-info 18:0:14 \
-version-info 18:1:14 \
@JSON_SYMVER_LDFLAGS@ \
@JSON_BSYMBOLIC_LDFLAGS@

6265
src/dtoa.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -23,10 +23,10 @@
#include "strbuffer.h"
#include "utf.h"
#define MAX_INTEGER_STR_LENGTH 100
#define MAX_REAL_STR_LENGTH 100
#define MAX_INTEGER_STR_LENGTH 25
#define MAX_REAL_STR_LENGTH 25
#define FLAGS_TO_INDENT(f) ((f)&0x1F)
#define FLAGS_TO_INDENT(f) ((f) & 0x1F)
#define FLAGS_TO_PRECISION(f) (((f) >> 11) & 0x1F)
struct buffer {

View file

@ -5,14 +5,14 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <jansson_private_config.h>
#endif
#include <stdlib.h>
#include <string.h>
#if HAVE_STDINT_H
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

View file

@ -22,10 +22,10 @@ extern "C" {
#define JANSSON_MAJOR_VERSION 2
#define JANSSON_MINOR_VERSION 14
#define JANSSON_MICRO_VERSION 0
#define JANSSON_MICRO_VERSION 1
/* Micro version is omitted if it's 0 */
#define JANSSON_VERSION "2.14"
#define JANSSON_VERSION "2.14.1"
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
@ -379,14 +379,14 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla
/* encoding */
#define JSON_MAX_INDENT 0x1F
#define JSON_INDENT(n) ((n)&JSON_MAX_INDENT)
#define JSON_INDENT(n) ((n) & JSON_MAX_INDENT)
#define JSON_COMPACT 0x20
#define JSON_ENSURE_ASCII 0x40
#define JSON_SORT_KEYS 0x80
#define JSON_PRESERVE_ORDER 0x100
#define JSON_ENCODE_ANY 0x200
#define JSON_ESCAPE_SLASH 0x400
#define JSON_REAL_PRECISION(n) (((n)&0x1F) << 11)
#define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11)
#define JSON_EMBED 0x10000
typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);

View file

@ -32,10 +32,6 @@
otherwise to 0. */
#define JSON_INTEGER_IS_LONG_LONG @json_have_long_long@
/* If locale.h and localeconv() are available, define to 1,
otherwise to 0. */
#define JSON_HAVE_LOCALECONV @json_have_localeconv@
/* If __atomic builtins are available they will be used to manage
reference counts of json_t. */
#define JSON_HAVE_ATOMIC_BUILTINS @json_have_atomic_builtins@

View file

@ -562,8 +562,7 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap) {
long unpacked = 0;
if (gotopt || json_object_size(root) != key_set.size) {
json_object_foreach(root, key, value) {
key_len = strlen(key);
json_object_keylen_foreach(root, key, key_len, value) {
if (!hashtable_get(&key_set, key, key_len)) {
unpacked++;

View file

@ -16,7 +16,7 @@
#define STRBUFFER_MIN_SIZE 16
#define STRBUFFER_FACTOR 2
#define STRBUFFER_SIZE_MAX ((size_t)-1)
#define STRBUFFER_SIZE_MAX ((size_t)(-1))
int strbuffer_init(strbuffer_t *strbuff) {
strbuff->size = STRBUFFER_MIN_SIZE;

View file

@ -11,57 +11,42 @@
#include <jansson_private_config.h>
#endif
#if JSON_HAVE_LOCALECONV
#include <locale.h>
/*
- This code assumes that the decimal separator is exactly one
character.
- If setlocale() is called by another thread between the call to
localeconv() and the call to sprintf() or strtod(), the result may
be wrong. setlocale() is not thread-safe and should not be used
this way. Multi-threaded programs should use uselocale() instead.
get_decimal_point() and the call to sprintf() or strtod(), the
result may be wrong. setlocale() is not thread-safe and should
not be used this way. Multi-threaded programs should use
uselocale() instead.
*/
static char get_decimal_point() {
char buf[3];
sprintf(buf, "%#.0f", 1.0); // "1." in the current locale
return buf[1];
}
static void to_locale(strbuffer_t *strbuffer) {
const char *point;
char point;
char *pos;
point = localeconv()->decimal_point;
if (*point == '.') {
point = get_decimal_point();
if (point == '.') {
/* No conversion needed */
return;
}
pos = strchr(strbuffer->value, '.');
if (pos)
*pos = *point;
*pos = point;
}
static void from_locale(char *buffer) {
const char *point;
char *pos;
point = localeconv()->decimal_point;
if (*point == '.') {
/* No conversion needed */
return;
}
pos = strchr(buffer, *point);
if (pos)
*pos = '.';
}
#endif
int jsonp_strtod(strbuffer_t *strbuffer, double *out) {
double value;
char *end;
#if JSON_HAVE_LOCALECONV
to_locale(strbuffer);
#endif
errno = 0;
value = strtod(strbuffer->value, &end);
@ -76,6 +61,127 @@ int jsonp_strtod(strbuffer_t *strbuffer, double *out) {
return 0;
}
#if DTOA_ENABLED
/* see dtoa.c */
char *dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve,
char *buf, size_t blen);
int jsonp_dtostr(char *buffer, size_t size, double value, int precision) {
/* adapted from `format_float_short()` in
* https://github.com/python/cpython/blob/2cf18a44303b6d84faa8ecffaecc427b53ae121e/Python/pystrtod.c#L969
*/
char digits[25];
char *digits_end;
int mode = precision == 0 ? 0 : 2;
int decpt, sign, exp_len, exp = 0, use_exp = 0;
int digits_len, vdigits_start, vdigits_end;
char *p;
if (dtoa_r(value, mode, precision, &decpt, &sign, &digits_end, digits, 25) == NULL) {
// digits is too short => should not happen
return -1;
}
digits_len = digits_end - digits;
if (decpt <= -4 || decpt > 16) {
use_exp = 1;
exp = decpt - 1;
decpt = 1;
}
vdigits_start = decpt <= 0 ? decpt - 1 : 0;
vdigits_end = digits_len;
if (!use_exp) {
/* decpt + 1 to add ".0" if value is an integer */
vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1;
} else {
vdigits_end = vdigits_end > decpt ? vdigits_end : decpt;
}
if (
/* sign, decimal point and trailing 0 byte */
(size_t)(3 +
/* total digit count (including zero padding on both sides) */
(vdigits_end - vdigits_start) +
/* exponent "e+100", max 3 numerical digits */
(use_exp ? 5 : 0)) > size) {
/* buffer is too short */
return -1;
}
p = buffer;
if (sign == 1) {
*p++ = '-';
}
/* note that exactly one of the three 'if' conditions is true,
so we include exactly one decimal point */
/* Zero padding on left of digit string */
if (decpt <= 0) {
memset(p, '0', decpt - vdigits_start);
p += decpt - vdigits_start;
*p++ = '.';
memset(p, '0', 0 - decpt);
p += 0 - decpt;
} else {
memset(p, '0', 0 - vdigits_start);
p += 0 - vdigits_start;
}
/* Digits, with included decimal point */
if (0 < decpt && decpt <= digits_len) {
strncpy(p, digits, decpt - 0);
p += decpt - 0;
*p++ = '.';
strncpy(p, digits + decpt, digits_len - decpt);
p += digits_len - decpt;
} else {
strncpy(p, digits, digits_len);
p += digits_len;
}
/* And zeros on the right */
if (digits_len < decpt) {
memset(p, '0', decpt - digits_len);
p += decpt - digits_len;
*p++ = '.';
memset(p, '0', vdigits_end - decpt);
p += vdigits_end - decpt;
} else {
memset(p, '0', vdigits_end - digits_len);
p += vdigits_end - digits_len;
}
if (p[-1] == '.')
p--;
if (use_exp) {
*p++ = 'e';
exp_len = sprintf(p, "%d", exp);
p += exp_len;
}
*p = '\0';
return (int)(p - buffer);
}
#else /* DTOA_ENABLED == 0 */
static void from_locale(char *buffer) {
char point;
char *pos;
point = get_decimal_point();
if (point == '.') {
/* No conversion needed */
return;
}
pos = strchr(buffer, point);
if (pos)
*pos = '.';
}
int jsonp_dtostr(char *buffer, size_t size, double value, int precision) {
int ret;
char *start, *end;
@ -92,9 +198,7 @@ int jsonp_dtostr(char *buffer, size_t size, double value, int precision) {
if (length >= size)
return -1;
#if JSON_HAVE_LOCALECONV
from_locale(buffer);
#endif
/* Make sure there's a dot or 'e' in the output. Otherwise
a real is converted to an integer when decoding */
@ -130,3 +234,4 @@ int jsonp_dtostr(char *buffer, size_t size, double value, int precision) {
return (int)length;
}
#endif

View file

@ -191,13 +191,14 @@ int json_object_clear(json_t *json) {
int json_object_update(json_t *object, json_t *other) {
const char *key;
size_t key_len;
json_t *value;
if (!json_is_object(object) || !json_is_object(other))
return -1;
json_object_foreach(other, key, value) {
if (json_object_set_nocheck(object, key, value))
json_object_keylen_foreach(other, key, key_len, value) {
if (json_object_setn_nocheck(object, key, key_len, value))
return -1;
}
@ -222,14 +223,15 @@ int json_object_update_existing(json_t *object, json_t *other) {
int json_object_update_missing(json_t *object, json_t *other) {
const char *key;
size_t key_len;
json_t *value;
if (!json_is_object(object) || !json_is_object(other))
return -1;
json_object_foreach(other, key, value) {
if (!json_object_get(object, key))
json_object_set_nocheck(object, key, value);
json_object_keylen_foreach(other, key, key_len, value) {
if (!json_object_getn(object, key, key_len))
json_object_setn_nocheck(object, key, key_len, value);
}
return 0;
@ -250,7 +252,7 @@ int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *paren
return -1;
json_object_keylen_foreach(other, key, key_len, value) {
json_t *v = json_object_get(object, key);
json_t *v = json_object_getn(object, key, key_len);
if (json_is_object(v) && json_is_object(value)) {
if (do_object_update_recursive(v, value, parents)) {
@ -352,13 +354,14 @@ void *json_object_key_to_iter(const char *key) {
static int json_object_equal(const json_t *object1, const json_t *object2) {
const char *key;
size_t key_len;
const json_t *value1, *value2;
if (json_object_size(object1) != json_object_size(object2))
return 0;
json_object_foreach((json_t *)object1, key, value1) {
value2 = json_object_get(object2, key);
json_object_keylen_foreach((json_t *)object1, key, key_len, value1) {
value2 = json_object_getn(object2, key, key_len);
if (!json_equal(value1, value2))
return 0;
@ -371,13 +374,15 @@ static json_t *json_object_copy(json_t *object) {
json_t *result;
const char *key;
size_t key_len;
json_t *value;
result = json_object();
if (!result)
return NULL;
json_object_foreach(object, key, value) json_object_set_nocheck(result, key, value);
json_object_keylen_foreach(object, key, key_len, value)
json_object_setn_nocheck(result, key, key_len, value);
return result;
}
@ -400,11 +405,14 @@ static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents)
iter = json_object_iter((json_t *)object);
while (iter) {
const char *key;
size_t key_len;
const json_t *value;
key = json_object_iter_key(iter);
key_len = json_object_iter_key_len(iter);
value = json_object_iter_value(iter);
if (json_object_set_new_nocheck(result, key, do_deep_copy(value, parents))) {
if (json_object_setn_new_nocheck(result, key, key_len,
do_deep_copy(value, parents))) {
json_decref(result);
result = NULL;
break;

1
test/.gitignore vendored
View file

@ -7,6 +7,7 @@ suites/api/test_cpp
suites/api/test_dump
suites/api/test_dump_callback
suites/api/test_equal
suites/api/test_fixed_size
suites/api/test_load
suites/api/test_load_callback
suites/api/test_loadb

View file

@ -35,7 +35,6 @@ struct config {
int ensure_ascii;
int sort_keys;
int strip;
int use_env;
int have_hashseed;
int hashseed;
int precision;
@ -81,11 +80,10 @@ static char *loadfile(FILE *file) {
static void read_conf(FILE *conffile) {
char *buffer, *line, *val;
conf.have_hashseed = 0;
buffer = loadfile(conffile);
for (line = strtok(buffer, "\r\n"); line; line = strtok(NULL, "\r\n")) {
if (!strncmp(line, "export ", 7))
continue;
val = strchr(line, '=');
if (!val) {
printf("invalid configuration line\n");
@ -110,8 +108,6 @@ static void read_conf(FILE *conffile) {
if (!strcmp(line, "HASHSEED")) {
conf.have_hashseed = 1;
conf.hashseed = atoi(val);
} else {
conf.have_hashseed = 0;
}
}
@ -138,10 +134,16 @@ static int cmpfile(const char *str, const char *path, const char *fname) {
}
buffer = loadfile(file);
if (strcmp(buffer, str) != 0)
if (strcmp(buffer, str) != 0) {
fprintf(stderr, "=== Expected %s ===\n", fname);
fprintf(stderr, "%s\n", buffer);
fprintf(stderr, "=== Actual %s ===\n", fname);
fprintf(stderr, "%s\n", str);
ret = 1;
else
} else {
ret = 0;
}
free(buffer);
fclose(file);
@ -206,8 +208,9 @@ int use_conf(char *test_path) {
buffer = loadfile(infile);
json = json_loads(strip(buffer), 0, &error);
free(buffer);
} else
} else {
json = json_loadf(infile, 0, &error);
}
fclose(infile);
@ -227,108 +230,6 @@ int use_conf(char *test_path) {
return ret;
}
static int getenv_int(const char *name) {
char *value, *end;
long result;
value = getenv(name);
if (!value)
return 0;
result = strtol(value, &end, 10);
if (*end != '\0')
return 0;
return (int)result;
}
int use_env() {
int indent, precision;
size_t flags = 0;
json_t *json;
json_error_t error;
#ifdef _WIN32
/* On Windows, set stdout and stderr to binary mode to avoid
outputting DOS line terminators */
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
#endif
indent = getenv_int("JSON_INDENT");
if (indent < 0 || indent > 31) {
fprintf(stderr, "invalid value for JSON_INDENT: %d\n", indent);
return 2;
}
if (indent > 0)
flags |= JSON_INDENT(indent);
if (getenv_int("JSON_COMPACT") > 0)
flags |= JSON_COMPACT;
if (getenv_int("JSON_ENSURE_ASCII"))
flags |= JSON_ENSURE_ASCII;
if (getenv_int("JSON_PRESERVE_ORDER"))
flags |= JSON_PRESERVE_ORDER;
if (getenv_int("JSON_SORT_KEYS"))
flags |= JSON_SORT_KEYS;
precision = getenv_int("JSON_REAL_PRECISION");
if (precision < 0 || precision > 31) {
fprintf(stderr, "invalid value for JSON_REAL_PRECISION: %d\n", precision);
return 2;
}
if (getenv("HASHSEED"))
json_object_seed(getenv_int("HASHSEED"));
if (precision > 0)
flags |= JSON_REAL_PRECISION(precision);
if (getenv_int("STRIP")) {
/* Load to memory, strip leading and trailing whitespace */
size_t size = 0, used = 0;
char *buffer = NULL, *buf_ck = NULL;
while (1) {
size_t count;
size = (size == 0 ? 128 : size * 2);
buf_ck = realloc(buffer, size);
if (!buf_ck) {
fprintf(stderr, "Unable to allocate %d bytes\n", (int)size);
free(buffer);
return 1;
}
buffer = buf_ck;
count = fread(buffer + used, 1, size - used, stdin);
if (count < size - used) {
buffer[used + count] = '\0';
break;
}
used += count;
}
json = json_loads(strip(buffer), 0, &error);
free(buffer);
} else
json = json_loadf(stdin, 0, &error);
if (!json) {
fprintf(stderr, "%d %d %d\n%s\n", error.line, error.column, error.position,
error.text);
return 1;
}
json_dumpf(json, stdout, flags);
json_decref(json);
return 0;
}
int main(int argc, char *argv[]) {
int i;
char *test_path = NULL;
@ -344,23 +245,17 @@ int main(int argc, char *argv[]) {
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--strip"))
conf.strip = 1;
else if (!strcmp(argv[i], "--env"))
conf.use_env = 1;
else
test_path = argv[i];
}
if (conf.use_env)
return use_env();
else {
if (!test_path)
goto usage;
return use_conf(test_path);
if (!test_path) {
goto usage;
}
return use_conf(test_path);
usage:
fprintf(stderr, "argc =%d\n", argc);
fprintf(stderr, "usage: %s [--strip] [--env] test_dir\n", argv[0]);
fprintf(stderr, "usage: %s [--strip] test_dir\n", argv[0]);
return 2;
}

View file

@ -15,7 +15,7 @@ grep 'json_\|jansson_' $top_srcdir/src/jansson.def \
nm -D $SOFILE >/dev/null >$test_log/symbols 2>/dev/null \
|| exit 77 # Skip if "nm -D" doesn't seem to work
grep ' [DT] ' $test_log/symbols | cut -d' ' -f3 | grep -v '^_' | sort >$test_log/output
grep ' [DT] ' $test_log/symbols | cut -d' ' -f3 | grep -v '^_' | sed 's/@@libjansson.*//' | sort >$test_log/output
if ! cmp -s $test_log/exports $test_log/output; then
diff -u $test_log/exports $test_log/output >&2

View file

@ -127,6 +127,7 @@ static void test_keylen(void) {
static void test_invalid_keylen(void) {
json_t *obj = json_object();
json_t *empty_obj = json_object();
const char key[] = {'t', 'e', 's', 't', '1'};
json_object_set_new_nocheck(obj, "test1", json_true());
@ -149,7 +150,14 @@ static void test_invalid_keylen(void) {
if (!json_object_del(obj, NULL))
fail("json_object_del with NULL failed");
if (!json_object_deln(empty_obj, key, sizeof(key)))
fail("json_object_deln with empty object failed");
if (!json_object_deln(obj, key, sizeof(key) - 1))
fail("json_object_deln with incomplete key failed");
json_decref(obj);
json_decref(empty_obj);
}
static void test_binary_keys(void) {
@ -166,6 +174,21 @@ static void test_binary_keys(void) {
if (!json_is_true(json_object_getn(obj, (const char *)&key1, sizeof(key2))))
fail("cannot get integer key2");
if (json_object_size(obj) != 2)
fail("binary object size missmatch");
if (json_object_deln(obj, (const char *)&key1, sizeof(key1)))
fail("cannot del integer key1");
if (json_object_size(obj) != 1)
fail("binary object size missmatch");
if (json_object_deln(obj, (const char *)&key2, sizeof(key2)))
fail("cannot del integer key2");
if (json_object_size(obj) != 0)
fail("binary object size missmatch");
json_decref(obj);
}

View file

@ -1,2 +1 @@
JSON_COMPACT=1
export JSON_COMPACT

View file

@ -1,3 +1,2 @@
JSON_COMPACT=1
HASHSEED=1
export JSON_COMPACT HASHSEED

View file

@ -1,2 +1 @@
JSON_ENSURE_ASCII=1
export JSON_ENSURE_ASCII

View file

@ -1,2 +1 @@
JSON_INDENT=4
export JSON_INDENT

View file

@ -1,3 +1,2 @@
JSON_INDENT=4
JSON_COMPACT=1
export JSON_INDENT JSON_COMPACT

View file

@ -1,4 +1,3 @@
JSON_INDENT=4
JSON_COMPACT=1
HASHSEED=1
export JSON_INDENT JSON_COMPACT HASHSEED

View file

@ -1,3 +1,2 @@
JSON_INDENT=4
HASHSEED=1
export JSON_INDENT HASHSEED

View file

@ -1,2 +1 @@
HASHSEED=1
export HASHSEED

View file

@ -1,2 +1 @@
JSON_PRESERVE_ORDER=1
export JSON_PRESERVE_ORDER

View file

@ -1,2 +1 @@
JSON_REAL_PRECISION=4
export JSON_REAL_PRECISION

View file

@ -1 +1 @@
[1.23456789, 1.0, 1.0000000000000002]
[1.23456789, 1.0, 1.0000000000000002, 1.23456e99, 1.23456e-99, 0.0000000000012345]

View file

@ -1 +1 @@
[1.235, 1.0, 1.0]
[1.235, 1.0, 1.0, 1.235e99, 1.235e-99, 1.235e-12]

View file

@ -10,23 +10,13 @@ is_test() {
}
run_test() {
(
if [ -f $test_path/env ]; then
. $test_path/env
fi
$json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
)
$json_process $test_path >$test_log/stdout 2>$test_log/stderr || return 1
valgrind_check $test_log/stderr || return 1
cmp -s $test_path/output $test_log/stdout
}
show_error() {
valgrind_show_error && return
echo "EXPECTED OUTPUT:"
nl -bn $test_path/output
echo "ACTUAL OUTPUT:"
nl -bn $test_log/stdout
cat $test_log/stderr
}
. $top_srcdir/test/scripts/run-tests.sh

View file

@ -1,2 +1 @@
JSON_SORT_KEYS=1
export JSON_SORT_KEYS

View file

@ -10,18 +10,13 @@ is_test() {
}
run_test() {
$json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
valgrind_check $test_log/stderr || return 1
cmp -s $test_path/error $test_log/stderr
$json_process $test_path >$test_log/stdout 2>$test_log/stderr || return 1
valgrind_check $test_log/stderr$s || return 1
}
show_error() {
valgrind_show_error && return
echo "EXPECTED ERROR:"
nl -bn $test_path/error
echo "ACTUAL ERROR:"
nl -bn $test_log/stderr
cat $test_log/stderr
}
. $top_srcdir/test/scripts/run-tests.sh

View file

@ -13,24 +13,18 @@ do_run() {
variant=$1
s=".$1"
strip=0
strip=""
if [ "$variant" = "strip" ]; then
# This test should not be stripped
[ -f $test_path/nostrip ] && return
strip=1
strip="--strip"
fi
STRIP=$strip $json_process --env \
<$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
valgrind_check $test_log/stderr$s || return 1
ref=error
[ -f $test_path/error$s ] && ref=error$s
if ! cmp -s $test_path/$ref $test_log/stderr$s; then
echo $variant > $test_log/variant
if ! $json_process $strip $test_path >$test_log/stdout$s 2>$test_log/stderr$s; then
echo $variant >$test_log/variant
return 1
fi
valgrind_check $test_log/stderr$s || return 1
}
run_test() {
@ -44,14 +38,7 @@ show_error() {
s=".$variant"
echo "VARIANT: $variant"
echo "EXPECTED ERROR:"
ref=error
[ -f $test_path/error$s ] && ref=error$s
nl -bn $test_path/$ref
echo "ACTUAL ERROR:"
nl -bn $test_log/stderr$s
cat $test_log/stderr$s
}
. $top_srcdir/test/scripts/run-tests.sh

View file

@ -0,0 +1 @@
[1.23e47, 0.1, 0.3, 9.99]

View file

@ -0,0 +1 @@
[1.2299999999999999e47, 0.10000000000000001, 0.29999999999999999, 9.9900000000000002]

View file

@ -1 +1 @@
[123e45]
[1.23e47, 0.1, 0.3, 9.99]

View file

@ -1 +1 @@
[1.2299999999999999e47]
[1.23e47, 0.1, 0.3, 9.99]

View file

@ -5,31 +5,33 @@
# Jansson is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
JSON_SORT_KEYS=1
export JSON_SORT_KEYS
dtoa_enabled() {
grep -q "DTOA_ENABLED 1" $top_builddir/jansson_private_config.h
}
is_test() {
test -d $test_path
}
do_run() {
if [ -f $test_path/skip_unless_dtoa ]; then
dtoa_enabled || return 77
fi
if [ -f $test_path/skip_if_dtoa ]; then
dtoa_enabled && return 77
fi
variant=$1
s=".$1"
strip=0
[ "$variant" = "strip" ] && strip=1
strip=""
[ "$variant" = "strip" ] && strip="--strip"
STRIP=$strip $json_process --env \
<$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
valgrind_check $test_log/stderr$s || return 1
ref=output
[ -f $test_path/output$s ] && ref=output$s
if ! cmp -s $test_path/$ref $test_log/stdout$s; then
echo $variant > $test_log/variant
if ! $json_process $strip $test_path >$test_log/stdout$s 2>$test_log/stderr$s; then
echo $variant >$test_log/variant
return 1
fi
valgrind_check $test_log/stderr$s || return 1
}
run_test() {
@ -43,14 +45,7 @@ show_error() {
s=".$variant"
echo "VARIANT: $variant"
echo "EXPECTED OUTPUT:"
ref=output
[ -f $test_path/output$s ] && ref=output$s
nl -bn $test_path/$ref
echo "ACTUAL OUTPUT:"
nl -bn $test_log/stdout$s
cat $test_log/stderr$s
}
. $top_srcdir/test/scripts/run-tests.sh