aws-crt 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (322) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/VERSION +1 -1
  4. data/aws-crt-ffi/CMakeLists.txt +49 -41
  5. data/aws-crt-ffi/crt/aws-c-auth/CMakeLists.txt +0 -10
  6. data/aws-crt-ffi/crt/aws-c-auth/include/aws/auth/credentials.h +3 -2
  7. data/aws-crt-ffi/crt/aws-c-auth/include/aws/auth/private/credentials_utils.h +4 -4
  8. data/aws-crt-ffi/crt/aws-c-auth/source/auth.c +1 -14
  9. data/aws-crt-ffi/crt/aws-c-auth/source/aws_imds_client.c +206 -68
  10. data/aws-crt-ffi/crt/aws-c-auth/source/aws_signing.c +5 -0
  11. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_cached.c +6 -6
  12. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_default_chain.c +16 -1
  13. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_ecs.c +0 -1
  14. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_process.c +0 -1
  15. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_sts_web_identity.c +0 -1
  16. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_provider_x509.c +10 -7
  17. data/aws-crt-ffi/crt/aws-c-auth/source/credentials_utils.c +35 -26
  18. data/aws-crt-ffi/crt/aws-c-auth/source/signable_chunk.c +3 -2
  19. data/aws-crt-ffi/crt/aws-c-auth/tests/CMakeLists.txt +3 -2
  20. data/aws-crt-ffi/crt/aws-c-auth/tests/aws_imds_client_test.c +1 -0
  21. data/aws-crt-ffi/crt/aws-c-auth/tests/credentials_provider_ecs_tests.c +3 -0
  22. data/aws-crt-ffi/crt/aws-c-auth/tests/credentials_provider_process_tests.c +65 -16
  23. data/aws-crt-ffi/crt/aws-c-auth/tests/credentials_tests.c +125 -0
  24. data/aws-crt-ffi/crt/aws-c-auth/tests/sigv4_signing_tests.c +68 -46
  25. data/aws-crt-ffi/crt/aws-c-cal/CMakeLists.txt +8 -3
  26. data/aws-crt-ffi/crt/aws-c-cal/bin/run_x_platform_fuzz_corpus/main.c +9 -0
  27. data/aws-crt-ffi/crt/aws-c-cal/builder.json +11 -3
  28. data/aws-crt-ffi/crt/aws-c-cal/cmake/aws-c-cal-config.cmake +14 -5
  29. data/aws-crt-ffi/crt/aws-c-cal/source/darwin/securityframework_ecc.c +6 -6
  30. data/aws-crt-ffi/crt/aws-c-cal/source/windows/bcrypt_ecc.c +12 -12
  31. data/aws-crt-ffi/crt/aws-c-cal/tests/test_case_helper.h +14 -14
  32. data/aws-crt-ffi/crt/aws-c-common/CMakeLists.txt +21 -1
  33. data/aws-crt-ffi/crt/aws-c-common/README.md +8 -0
  34. data/aws-crt-ffi/crt/aws-c-common/cmake/AwsCFlags.cmake +20 -5
  35. data/aws-crt-ffi/crt/aws-c-common/cmake/AwsFeatureTests.cmake +7 -1
  36. data/aws-crt-ffi/crt/aws-c-common/format-check.sh +1 -1
  37. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/byte_buf.h +14 -0
  38. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/config.h.in +1 -0
  39. data/aws-crt-ffi/crt/{aws-c-auth/include/aws/auth → aws-c-common/include/aws/common}/external/cJSON.h +82 -74
  40. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/json.h +335 -0
  41. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/logging.h +1 -0
  42. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/math.inl +2 -2
  43. data/aws-crt-ffi/crt/aws-c-common/include/aws/common/private/json_impl.h +22 -0
  44. data/aws-crt-ffi/crt/aws-c-common/include/aws/testing/aws_test_harness.h +2 -0
  45. data/aws-crt-ffi/crt/aws-c-common/source/byte_buf.c +36 -0
  46. data/aws-crt-ffi/crt/aws-c-common/source/common.c +5 -2
  47. data/aws-crt-ffi/crt/aws-c-common/source/external/cJSON.c +3113 -0
  48. data/aws-crt-ffi/crt/aws-c-common/source/file.c +9 -0
  49. data/aws-crt-ffi/crt/aws-c-common/source/json.c +348 -0
  50. data/aws-crt-ffi/crt/aws-c-common/source/logging.c +7 -2
  51. data/aws-crt-ffi/crt/aws-c-common/source/posix/system_info.c +8 -0
  52. data/aws-crt-ffi/crt/aws-c-common/source/ref_count.c +3 -1
  53. data/aws-crt-ffi/crt/aws-c-common/source/windows/file.c +47 -0
  54. data/aws-crt-ffi/crt/aws-c-common/source/windows/system_info.c +2 -1
  55. data/aws-crt-ffi/crt/aws-c-common/tests/CMakeLists.txt +5 -0
  56. data/aws-crt-ffi/crt/aws-c-common/tests/byte_buf_test.c +69 -0
  57. data/aws-crt-ffi/crt/aws-c-common/tests/json_test.c +134 -0
  58. data/aws-crt-ffi/crt/aws-c-common/tests/memtrace_test.c +6 -2
  59. data/aws-crt-ffi/crt/aws-c-event-stream/README.md +18 -35
  60. data/aws-crt-ffi/crt/aws-c-event-stream/include/aws/event-stream/event_stream.h +21 -2
  61. data/aws-crt-ffi/crt/aws-c-event-stream/include/aws/event-stream/event_stream_rpc_client.h +14 -2
  62. data/aws-crt-ffi/crt/aws-c-event-stream/include/aws/event-stream/event_stream_rpc_server.h +13 -0
  63. data/aws-crt-ffi/crt/aws-c-event-stream/include/aws/event-stream/private/event_stream_rpc_priv.h +7 -7
  64. data/aws-crt-ffi/crt/aws-c-event-stream/source/event_stream.c +257 -141
  65. data/aws-crt-ffi/crt/aws-c-event-stream/source/event_stream_channel_handler.c +1 -1
  66. data/aws-crt-ffi/crt/aws-c-event-stream/source/event_stream_rpc_client.c +31 -8
  67. data/aws-crt-ffi/crt/aws-c-event-stream/source/event_stream_rpc_server.c +63 -10
  68. data/aws-crt-ffi/crt/aws-c-event-stream/tests/CMakeLists.txt +2 -0
  69. data/aws-crt-ffi/crt/aws-c-event-stream/tests/event_stream_rpc_client_connection_test.c +157 -106
  70. data/aws-crt-ffi/crt/aws-c-event-stream/tests/event_stream_rpc_server_connection_test.c +168 -1
  71. data/aws-crt-ffi/crt/aws-c-event-stream/tests/message_deserializer_test.c +4 -2
  72. data/aws-crt-ffi/crt/aws-c-http/CMakeLists.txt +1 -0
  73. data/aws-crt-ffi/crt/aws-c-http/README.md +8 -0
  74. data/aws-crt-ffi/crt/aws-c-http/bin/elasticurl/main.c +1 -1
  75. data/aws-crt-ffi/crt/aws-c-http/builder.json +4 -3
  76. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/connection.h +8 -1
  77. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/connection_manager.h +45 -1
  78. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/http2_stream_manager.h +63 -12
  79. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/connection_impl.h +2 -1
  80. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/h2_connection.h +20 -2
  81. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/h2_frames.h +1 -0
  82. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/h2_stream.h +42 -13
  83. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/http2_stream_manager_impl.h +17 -0
  84. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/http_impl.h +3 -0
  85. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/random_access_set.h +10 -3
  86. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/private/request_response_impl.h +3 -17
  87. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/request_response.h +108 -4
  88. data/aws-crt-ffi/crt/aws-c-http/include/aws/http/statistics.h +22 -0
  89. data/aws-crt-ffi/crt/aws-c-http/source/connection.c +8 -3
  90. data/aws-crt-ffi/crt/aws-c-http/source/connection_manager.c +22 -3
  91. data/aws-crt-ffi/crt/aws-c-http/source/connection_monitor.c +32 -14
  92. data/aws-crt-ffi/crt/aws-c-http/source/h1_connection.c +14 -0
  93. data/aws-crt-ffi/crt/aws-c-http/source/h1_encoder.c +7 -4
  94. data/aws-crt-ffi/crt/aws-c-http/source/h2_connection.c +161 -45
  95. data/aws-crt-ffi/crt/aws-c-http/source/h2_decoder.c +37 -8
  96. data/aws-crt-ffi/crt/aws-c-http/source/h2_frames.c +13 -1
  97. data/aws-crt-ffi/crt/aws-c-http/source/h2_stream.c +345 -87
  98. data/aws-crt-ffi/crt/aws-c-http/source/hpack.c +3 -0
  99. data/aws-crt-ffi/crt/aws-c-http/source/http.c +3 -0
  100. data/aws-crt-ffi/crt/aws-c-http/source/http2_stream_manager.c +266 -39
  101. data/aws-crt-ffi/crt/aws-c-http/source/random_access_set.c +9 -3
  102. data/aws-crt-ffi/crt/aws-c-http/source/request_response.c +80 -20
  103. data/aws-crt-ffi/crt/aws-c-http/source/statistics.c +11 -0
  104. data/aws-crt-ffi/crt/aws-c-http/tests/CMakeLists.txt +28 -1
  105. data/aws-crt-ffi/crt/aws-c-http/tests/fuzz/fuzz_h2_decoder_correct.c +5 -3
  106. data/aws-crt-ffi/crt/aws-c-http/tests/h2_test_helper.c +133 -29
  107. data/aws-crt-ffi/crt/aws-c-http/tests/h2_test_helper.h +6 -0
  108. data/aws-crt-ffi/crt/aws-c-http/tests/py_localhost/README.md +40 -0
  109. data/aws-crt-ffi/crt/aws-c-http/tests/py_localhost/non_tls_server.py +56 -0
  110. data/aws-crt-ffi/crt/aws-c-http/tests/py_localhost/server.py +329 -0
  111. data/aws-crt-ffi/crt/aws-c-http/tests/test_connection_manager.c +1 -1
  112. data/aws-crt-ffi/crt/aws-c-http/tests/test_connection_monitor.c +2 -2
  113. data/aws-crt-ffi/crt/aws-c-http/tests/test_h1_client.c +47 -34
  114. data/aws-crt-ffi/crt/aws-c-http/tests/test_h1_encoder.c +4 -4
  115. data/aws-crt-ffi/crt/aws-c-http/tests/test_h1_server.c +15 -12
  116. data/aws-crt-ffi/crt/aws-c-http/tests/test_h2_client.c +582 -25
  117. data/aws-crt-ffi/crt/aws-c-http/tests/test_h2_encoder.c +3 -3
  118. data/aws-crt-ffi/crt/aws-c-http/tests/test_localhost_integ.c +530 -0
  119. data/aws-crt-ffi/crt/aws-c-http/tests/test_stream_manager.c +459 -67
  120. data/aws-crt-ffi/crt/aws-c-io/CMakeLists.txt +4 -0
  121. data/aws-crt-ffi/crt/aws-c-io/builder.json +3 -2
  122. data/aws-crt-ffi/crt/aws-c-io/include/aws/io/channel.h +21 -0
  123. data/aws-crt-ffi/crt/aws-c-io/include/aws/io/io.h +3 -0
  124. data/aws-crt-ffi/crt/aws-c-io/include/aws/io/socket.h +6 -0
  125. data/aws-crt-ffi/crt/aws-c-io/include/aws/io/stream.h +35 -5
  126. data/aws-crt-ffi/crt/aws-c-io/include/aws/io/tls_channel_handler.h +211 -15
  127. data/aws-crt-ffi/crt/aws-c-io/source/channel.c +56 -30
  128. data/aws-crt-ffi/crt/aws-c-io/source/darwin/secure_transport_tls_channel_handler.c +0 -24
  129. data/aws-crt-ffi/crt/aws-c-io/source/io.c +9 -0
  130. data/aws-crt-ffi/crt/aws-c-io/source/{pkcs11.c → pkcs11_lib.c} +162 -22
  131. data/aws-crt-ffi/crt/aws-c-io/source/pkcs11_private.h +18 -20
  132. data/aws-crt-ffi/crt/aws-c-io/source/pkcs11_tls_op_handler.c +221 -0
  133. data/aws-crt-ffi/crt/aws-c-io/source/posix/socket.c +135 -81
  134. data/aws-crt-ffi/crt/aws-c-io/source/retry_strategy.c +12 -8
  135. data/aws-crt-ffi/crt/aws-c-io/source/s2n/s2n_tls_channel_handler.c +252 -215
  136. data/aws-crt-ffi/crt/aws-c-io/source/stream.c +65 -82
  137. data/aws-crt-ffi/crt/aws-c-io/source/tls_channel_handler.c +188 -57
  138. data/aws-crt-ffi/crt/aws-c-io/source/windows/iocp/socket.c +271 -256
  139. data/aws-crt-ffi/crt/aws-c-io/tests/CMakeLists.txt +21 -12
  140. data/aws-crt-ffi/crt/aws-c-io/tests/channel_test.c +32 -4
  141. data/aws-crt-ffi/crt/aws-c-io/tests/io_lib_test.c +37 -0
  142. data/aws-crt-ffi/crt/aws-c-io/tests/pkcs11_test.c +412 -93
  143. data/aws-crt-ffi/crt/aws-c-io/tests/resources/ec_unittests.crt +15 -0
  144. data/aws-crt-ffi/crt/aws-c-io/tests/resources/ec_unittests.key +5 -0
  145. data/aws-crt-ffi/crt/aws-c-io/tests/resources/ec_unittests.p12 +0 -0
  146. data/aws-crt-ffi/crt/aws-c-io/tests/resources/ec_unittests.p8 +5 -0
  147. data/aws-crt-ffi/crt/aws-c-io/tests/resources/generateCerts.sh +24 -15
  148. data/aws-crt-ffi/crt/aws-c-io/tests/socket_test.c +72 -1
  149. data/aws-crt-ffi/crt/s2n/CMakeLists.txt +6 -1
  150. data/aws-crt-ffi/crt/s2n/bindings/rust/Cargo.toml +1 -0
  151. data/aws-crt-ffi/crt/s2n/bindings/rust/generate/src/main.rs +105 -82
  152. data/aws-crt-ffi/crt/s2n/bindings/rust/generate.sh +1 -0
  153. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls/Cargo.toml +2 -2
  154. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls/src/raw/config.rs +1 -1
  155. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-sys/Cargo.toml +1 -1
  156. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-sys/build.rs +84 -30
  157. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-sys/src/lib.rs +4 -0
  158. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/Cargo.toml +21 -0
  159. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/examples/certs/cert.pem +14 -0
  160. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/examples/certs/key.pem +8 -0
  161. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/examples/client.rs +45 -0
  162. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/examples/server.rs +60 -0
  163. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/src/lib.rs +150 -0
  164. data/aws-crt-ffi/crt/s2n/bindings/rust/s2n-tls-tokio/tests/handshake.rs +51 -0
  165. data/aws-crt-ffi/crt/s2n/crypto/s2n_drbg.c +98 -77
  166. data/aws-crt-ffi/crt/s2n/crypto/s2n_drbg.h +10 -7
  167. data/aws-crt-ffi/crt/s2n/crypto/s2n_openssl.h +2 -0
  168. data/aws-crt-ffi/crt/s2n/error/s2n_errno.c +1 -1
  169. data/aws-crt-ffi/crt/s2n/error/s2n_errno.h +1 -0
  170. data/aws-crt-ffi/crt/s2n/s2n.mk +7 -0
  171. data/aws-crt-ffi/crt/s2n/tests/cbmc/templates/scripts/repository.py +233 -0
  172. data/aws-crt-ffi/crt/s2n/tests/cbmc/templates/scripts/setup-proof.py +8 -7
  173. data/aws-crt-ffi/crt/s2n/tests/cbmc/templates/scripts/setup.py +17 -18
  174. data/aws-crt-ffi/crt/s2n/tests/cbmc/templates/scripts/util.py +41 -23
  175. data/aws-crt-ffi/crt/s2n/tests/fuzz/LD_PRELOAD/global_overrides.c +3 -3
  176. data/aws-crt-ffi/crt/s2n/tests/integration/s2n_client_endpoint_handshake_test.py +2 -2
  177. data/aws-crt-ffi/crt/s2n/tests/integrationv2/Makefile +13 -42
  178. data/aws-crt-ffi/crt/s2n/tests/integrationv2/README.md +6 -1
  179. data/aws-crt-ffi/crt/s2n/tests/integrationv2/common.py +118 -53
  180. data/aws-crt-ffi/crt/s2n/tests/integrationv2/configuration.py +108 -88
  181. data/aws-crt-ffi/crt/s2n/tests/integrationv2/conftest.py +6 -3
  182. data/aws-crt-ffi/crt/s2n/tests/integrationv2/constants.py +6 -4
  183. data/aws-crt-ffi/crt/s2n/tests/integrationv2/fixtures.py +21 -12
  184. data/aws-crt-ffi/crt/s2n/tests/integrationv2/global_flags.py +1 -0
  185. data/aws-crt-ffi/crt/s2n/tests/integrationv2/processes.py +62 -19
  186. data/aws-crt-ffi/crt/s2n/tests/integrationv2/providers.py +304 -48
  187. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_client_authentication.py +20 -11
  188. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_cross_compatibility.py +41 -17
  189. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_dynamic_record_sizes.py +6 -3
  190. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_early_data.py +105 -48
  191. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_external_psk.py +160 -76
  192. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_fragmentation.py +59 -26
  193. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_happy_path.py +42 -28
  194. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_hello_retry_requests.py +33 -13
  195. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_key_update.py +29 -11
  196. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_ocsp.py +138 -0
  197. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_pq_handshake.py +103 -36
  198. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_session_resumption.py +52 -25
  199. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_signature_algorithms.py +47 -21
  200. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_sni_match.py +13 -9
  201. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_sslyze.py +88 -17
  202. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_version_negotiation.py +71 -22
  203. data/aws-crt-ffi/crt/s2n/tests/integrationv2/test_well_known_endpoints.py +4 -3
  204. data/aws-crt-ffi/crt/s2n/tests/integrationv2/tox.ini +1 -0
  205. data/aws-crt-ffi/crt/s2n/tests/integrationv2/utils.py +50 -15
  206. data/aws-crt-ffi/crt/s2n/tests/litani/CHANGELOG +131 -0
  207. data/aws-crt-ffi/crt/s2n/tests/litani/CONTRIBUTING.md +16 -0
  208. data/aws-crt-ffi/crt/s2n/tests/litani/README.md +36 -14
  209. data/aws-crt-ffi/crt/s2n/tests/litani/THIRD-PARTY +205 -41
  210. data/aws-crt-ffi/crt/s2n/tests/litani/doc/bin/build-html-doc +7 -7
  211. data/aws-crt-ffi/crt/s2n/tests/litani/doc/configure +27 -23
  212. data/aws-crt-ffi/crt/s2n/tests/litani/doc/src/man/litani-add-job.scdoc +7 -0
  213. data/aws-crt-ffi/crt/s2n/tests/litani/doc/src/man/litani-dump-run.scdoc +7 -5
  214. data/aws-crt-ffi/crt/s2n/tests/litani/doc/src/man/litani-transform-jobs.scdoc +248 -0
  215. data/aws-crt-ffi/crt/s2n/tests/litani/doc/src/man/litani.scdoc +2 -2
  216. data/aws-crt-ffi/crt/s2n/tests/litani/doc/templates/index.jinja.html +4 -0
  217. data/aws-crt-ffi/crt/s2n/tests/litani/examples/add-root-node/README +12 -0
  218. data/aws-crt-ffi/crt/s2n/tests/litani/examples/add-root-node/original-run.sh +52 -0
  219. data/aws-crt-ffi/crt/s2n/tests/litani/examples/add-root-node/run-all.py +71 -0
  220. data/aws-crt-ffi/crt/s2n/tests/litani/examples/no-standalone-transform/README +13 -0
  221. data/aws-crt-ffi/crt/s2n/tests/litani/examples/no-standalone-transform/run-1.sh +34 -0
  222. data/aws-crt-ffi/crt/s2n/tests/litani/examples/no-standalone-transform/run-2.sh +35 -0
  223. data/aws-crt-ffi/crt/s2n/tests/litani/examples/no-standalone-transform/run-3.sh +34 -0
  224. data/aws-crt-ffi/crt/s2n/tests/litani/examples/no-standalone-transform/run-all.py +60 -0
  225. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/README.md +10 -0
  226. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/assumptions.html +42 -0
  227. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/file.dat +7 -0
  228. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/histogram.dat +7 -0
  229. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/run-1.sh +41 -0
  230. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/run-2.sh +47 -0
  231. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/run-3.sh +41 -0
  232. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/run-all.py +34 -0
  233. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/fib-table.py +40 -0
  234. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/fib.plt +5 -0
  235. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/fib.py +32 -0
  236. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/sin-output.py +40 -0
  237. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/sin.plt +5 -0
  238. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/scripts/sin.py +30 -0
  239. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/templates/fib-table.jinja.html +45 -0
  240. data/aws-crt-ffi/crt/s2n/tests/litani/examples/rich-output/templates/sin-output.jinja.html +30 -0
  241. data/aws-crt-ffi/crt/s2n/tests/litani/lib/add_job.py +55 -0
  242. data/aws-crt-ffi/crt/s2n/tests/litani/lib/graph.py +2 -2
  243. data/aws-crt-ffi/crt/s2n/tests/litani/lib/litani.py +6 -1
  244. data/aws-crt-ffi/crt/s2n/tests/litani/lib/litani_report.py +18 -21
  245. data/aws-crt-ffi/crt/s2n/tests/litani/lib/ninja.py +2 -0
  246. data/aws-crt-ffi/crt/s2n/tests/litani/lib/run_printer.py +26 -7
  247. data/aws-crt-ffi/crt/s2n/tests/litani/lib/transform_jobs.py +84 -0
  248. data/aws-crt-ffi/crt/s2n/tests/litani/litani +28 -33
  249. data/aws-crt-ffi/crt/s2n/tests/litani/script/release +220 -0
  250. data/aws-crt-ffi/crt/s2n/tests/litani/templates/dashboard.jinja.html +78 -15
  251. data/aws-crt-ffi/crt/s2n/tests/litani/templates/pipeline.jinja.html +21 -5
  252. data/aws-crt-ffi/crt/s2n/tests/litani/test/README +15 -0
  253. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/run +56 -33
  254. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/custom_stages.py +1 -0
  255. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/cwd.py +1 -0
  256. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/dump_run.py +1 -0
  257. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/graph_line_break.py +1 -0
  258. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/html_node.py +1 -0
  259. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/job_id_env.py +1 -0
  260. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/multiproc_dump_run.py +1 -0
  261. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/no_pool_serialize.py +1 -0
  262. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/no_pool_serialize_graph.py +1 -0
  263. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/no_timed_out.py +1 -0
  264. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/no_timed_out_timeout_ignored.py +1 -0
  265. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/no_timed_out_timeout_ok.py +1 -0
  266. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/pipeline_order.py +53 -0
  267. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/pool_serialize.py +1 -0
  268. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/pool_serialize_graph.py +1 -0
  269. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/single_pool.py +1 -0
  270. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out.py +1 -0
  271. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out_subprocess.py +1 -0
  272. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out_subprocess_multi_shell.py +1 -0
  273. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out_subprocess_shell.py +1 -0
  274. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out_timeout_ignored.py +1 -0
  275. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/timed_out_timeout_ok.py +1 -0
  276. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/transform_delete_job.py +54 -0
  277. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/transform_modify_job.py +46 -0
  278. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/transform_no_change_job.py +44 -0
  279. data/aws-crt-ffi/crt/s2n/tests/litani/test/e2e/tests/zero_pool.py +1 -0
  280. data/aws-crt-ffi/crt/s2n/tests/litani/test/run +82 -12
  281. data/aws-crt-ffi/crt/s2n/tests/s2n_test.h +58 -33
  282. data/aws-crt-ffi/crt/s2n/tests/testlib/s2n_key_schedule_testlib.c +18 -6
  283. data/aws-crt-ffi/crt/s2n/tests/testlib/s2n_pq_kat_test_utils.c +4 -4
  284. data/aws-crt-ffi/crt/s2n/tests/testlib/s2n_testlib.h +2 -0
  285. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_client_hello_retry_test.c +66 -2
  286. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_connection_test.c +1 -1
  287. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_drbg_test.c +34 -14
  288. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_fork_generation_number_test.c +28 -5
  289. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_mem_usage_test.c +6 -0
  290. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_override_openssl_random_test.c +1 -1
  291. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_random_test.c +60 -41
  292. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_self_talk_broken_pipe_test.c +2 -2
  293. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_handshake_early_data_test.c +3 -1
  294. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_hybrid_shared_secret_test.c +9 -1
  295. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_key_schedule_rfc8448_test.c +31 -130
  296. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_key_schedule_test.c +2 -4
  297. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_pq_handshake_test.c +11 -6
  298. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_secrets_rfc8448_test.c +19 -21
  299. data/aws-crt-ffi/crt/s2n/tests/unit/s2n_tls13_secrets_test.c +109 -60
  300. data/aws-crt-ffi/crt/s2n/tls/s2n_config.c +1 -0
  301. data/aws-crt-ffi/crt/s2n/tls/s2n_config.h +1 -1
  302. data/aws-crt-ffi/crt/s2n/tls/s2n_connection.c +29 -24
  303. data/aws-crt-ffi/crt/s2n/tls/s2n_connection.h +5 -5
  304. data/aws-crt-ffi/crt/s2n/tls/s2n_handshake_hashes.h +1 -7
  305. data/aws-crt-ffi/crt/s2n/tls/s2n_handshake_io.c +2 -0
  306. data/aws-crt-ffi/crt/s2n/tls/s2n_handshake_transcript.c +0 -44
  307. data/aws-crt-ffi/crt/s2n/tls/s2n_internal.h +0 -1
  308. data/aws-crt-ffi/crt/s2n/tls/s2n_quic_support.h +1 -1
  309. data/aws-crt-ffi/crt/s2n/tls/s2n_tls13_key_schedule.c +1 -2
  310. data/aws-crt-ffi/crt/s2n/tls/s2n_tls13_secrets.c +84 -44
  311. data/aws-crt-ffi/crt/s2n/tls/s2n_tls13_secrets.h +3 -9
  312. data/aws-crt-ffi/crt/s2n/utils/s2n_blob.h +15 -8
  313. data/aws-crt-ffi/crt/s2n/utils/s2n_fork_detection.c +2 -6
  314. data/aws-crt-ffi/crt/s2n/utils/s2n_random.c +9 -9
  315. data/aws-crt-ffi/src/input_stream.c +32 -15
  316. data/ext/compile.rb +13 -5
  317. data/lib/aws-crt/platforms.rb +14 -5
  318. data/lib/aws-crt/string_blob.rb +3 -3
  319. metadata +61 -7
  320. data/aws-crt-ffi/crt/aws-c-auth/source/external/cJSON.c +0 -2987
  321. data/aws-crt-ffi/crt/aws-c-auth/tests/external/cJSON.c +0 -2986
  322. data/aws-crt-ffi/crt/aws-c-io/tests/error_test.c +0 -20
@@ -1,2987 +0,0 @@
1
- /*
2
- Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to deal
6
- in the Software without restriction, including without limitation the rights
7
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in
12
- all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- THE SOFTWARE.
21
-
22
- */
23
-
24
- /*
25
- This file has been modified from its original version by Amazon:
26
- * (1) Include path
27
- * (2) header order via clang-format
28
- * (3) Clang-tidy error removal: Added parens around macro params in a number of macro bodies
29
- * (4) NOLINT annotations to disable clang-tidy errors around raw/unsafe function use
30
- * (5) strcpy() replaced with memcpy()
31
- */
32
-
33
- /* clang-format off */
34
-
35
- /* cJSON */
36
- /* JSON parser in C. */
37
-
38
- /* disable warnings about old C89 functions in MSVC */
39
- #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
40
- #define _CRT_SECURE_NO_DEPRECATE
41
- #endif
42
-
43
- #ifdef __GNUC__
44
- #pragma GCC visibility push(default)
45
- #endif
46
- #if defined(_MSC_VER)
47
- #pragma warning (push)
48
- /* disable warning about single line comments in system headers */
49
- #pragma warning (disable : 4001)
50
- #endif
51
-
52
- #include <ctype.h>
53
- #include <limits.h>
54
- #include <math.h>
55
- #include <stdio.h>
56
- #include <stdlib.h>
57
- #include <string.h>
58
-
59
- #ifdef ENABLE_LOCALES
60
- #include <locale.h>
61
- #endif
62
-
63
- #if defined(_MSC_VER)
64
- #pragma warning (pop)
65
- #endif
66
- #ifdef __GNUC__
67
- #pragma GCC visibility pop
68
- #endif
69
-
70
- #include <aws/auth/external/cJSON.h>
71
-
72
- /* define our own boolean type */
73
- #ifdef true
74
- #undef true
75
- #endif
76
- #define true ((cJSON_bool)1)
77
-
78
- #ifdef false
79
- #undef false
80
- #endif
81
- #define false ((cJSON_bool)0)
82
-
83
- typedef struct {
84
- const unsigned char *json;
85
- size_t position;
86
- } error;
87
- static error global_error = { NULL, 0 };
88
-
89
- CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
90
- {
91
- return (const char*) (global_error.json + global_error.position);
92
- }
93
-
94
- CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
95
- if (!cJSON_IsString(item)) {
96
- return NULL;
97
- }
98
-
99
- return item->valuestring;
100
- }
101
-
102
- /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
103
- #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 12)
104
- #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
105
- #endif
106
-
107
- CJSON_PUBLIC(const char*) cJSON_Version(void)
108
- {
109
- static char version[15];
110
- snprintf(version, sizeof(version) / sizeof(char), "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
111
-
112
- return version;
113
- }
114
-
115
- /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
116
- static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
117
- {
118
- if ((string1 == NULL) || (string2 == NULL))
119
- {
120
- return 1;
121
- }
122
-
123
- if (string1 == string2)
124
- {
125
- return 0;
126
- }
127
-
128
- for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
129
- {
130
- if (*string1 == '\0')
131
- {
132
- return 0;
133
- }
134
- }
135
-
136
- return tolower(*string1) - tolower(*string2);
137
- }
138
-
139
- typedef struct internal_hooks
140
- {
141
- void *(CJSON_CDECL *allocate)(size_t size);
142
- void (CJSON_CDECL *deallocate)(void *pointer);
143
- void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
144
- } internal_hooks;
145
-
146
- #if defined(_MSC_VER)
147
- /* work around MSVC error C2322: '...' address of dillimport '...' is not static */
148
- static void * CJSON_CDECL internal_malloc(size_t size)
149
- {
150
- return malloc(size);
151
- }
152
- static void CJSON_CDECL internal_free(void *pointer)
153
- {
154
- free(pointer);
155
- }
156
- static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
157
- {
158
- return realloc(pointer, size);
159
- }
160
- #else
161
- #define internal_malloc malloc
162
- #define internal_free free
163
- #define internal_realloc realloc
164
- #endif
165
-
166
- /* strlen of character literals resolved at compile time */
167
- #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
168
-
169
- static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
170
-
171
- static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
172
- {
173
- size_t length = 0;
174
- unsigned char *copy = NULL;
175
-
176
- if (string == NULL)
177
- {
178
- return NULL;
179
- }
180
-
181
- length = strlen((const char*)string) + sizeof("");
182
- copy = (unsigned char*)hooks->allocate(length);
183
- if (copy == NULL)
184
- {
185
- return NULL;
186
- }
187
- memcpy(copy, string, length);
188
-
189
- return copy;
190
- }
191
-
192
- CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
193
- {
194
- if (hooks == NULL)
195
- {
196
- /* Reset hooks */
197
- global_hooks.allocate = malloc;
198
- global_hooks.deallocate = free;
199
- global_hooks.reallocate = realloc;
200
- return;
201
- }
202
-
203
- global_hooks.allocate = malloc;
204
- if (hooks->malloc_fn != NULL)
205
- {
206
- global_hooks.allocate = hooks->malloc_fn;
207
- }
208
-
209
- global_hooks.deallocate = free;
210
- if (hooks->free_fn != NULL)
211
- {
212
- global_hooks.deallocate = hooks->free_fn;
213
- }
214
-
215
- /* use realloc only if both free and malloc are used */
216
- global_hooks.reallocate = NULL;
217
- if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
218
- {
219
- global_hooks.reallocate = realloc;
220
- }
221
- }
222
-
223
- /* Internal constructor. */
224
- static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
225
- {
226
- cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
227
- if (node)
228
- {
229
- memset(node, '\0', sizeof(cJSON));
230
- }
231
-
232
- return node;
233
- }
234
-
235
- /* Delete a cJSON structure. */
236
- CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
237
- {
238
- cJSON *next = NULL;
239
- while (item != NULL)
240
- {
241
- next = item->next;
242
- if (!(item->type & cJSON_IsReference) && (item->child != NULL))
243
- {
244
- cJSON_Delete(item->child);
245
- }
246
- if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
247
- {
248
- global_hooks.deallocate(item->valuestring);
249
- }
250
- if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
251
- {
252
- global_hooks.deallocate(item->string);
253
- }
254
- global_hooks.deallocate(item);
255
- item = next;
256
- }
257
- }
258
-
259
- /* get the decimal point character of the current locale */
260
- static unsigned char get_decimal_point(void)
261
- {
262
- #ifdef ENABLE_LOCALES
263
- struct lconv *lconv = localeconv();
264
- return (unsigned char) lconv->decimal_point[0];
265
- #else
266
- return '.';
267
- #endif
268
- }
269
-
270
- typedef struct
271
- {
272
- const unsigned char *content;
273
- size_t length;
274
- size_t offset;
275
- size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
276
- internal_hooks hooks;
277
- } parse_buffer;
278
-
279
- /* check if the given size is left to read in a given parse buffer (starting with 1) */
280
- #define can_read(buffer, size) (((buffer) != NULL) && (((buffer)->offset + (size)) <= (buffer)->length))
281
- /* check if the buffer can be accessed at the given index (starting with 0) */
282
- #define can_access_at_index(buffer, index) (((buffer) != NULL) && (((buffer)->offset + (index)) < (buffer)->length))
283
- #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
284
- /* get a pointer to the buffer at the position */
285
- #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
286
-
287
- /* Parse the input text to generate a number, and populate the result into item. */
288
- static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
289
- {
290
- double number = 0;
291
- unsigned char *after_end = NULL;
292
- unsigned char number_c_string[64];
293
- unsigned char decimal_point = get_decimal_point();
294
- size_t i = 0;
295
-
296
- if ((input_buffer == NULL) || (input_buffer->content == NULL))
297
- {
298
- return false;
299
- }
300
-
301
- /* copy the number into a temporary buffer and replace '.' with the decimal point
302
- * of the current locale (for strtod)
303
- * This also takes care of '\0' not necessarily being available for marking the end of the input */
304
- for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
305
- {
306
- switch (buffer_at_offset(input_buffer)[i])
307
- {
308
- case '0':
309
- case '1':
310
- case '2':
311
- case '3':
312
- case '4':
313
- case '5':
314
- case '6':
315
- case '7':
316
- case '8':
317
- case '9':
318
- case '+':
319
- case '-':
320
- case 'e':
321
- case 'E':
322
- number_c_string[i] = buffer_at_offset(input_buffer)[i];
323
- break;
324
-
325
- case '.':
326
- number_c_string[i] = decimal_point;
327
- break;
328
-
329
- default:
330
- goto loop_end;
331
- }
332
- }
333
- loop_end:
334
- number_c_string[i] = '\0';
335
-
336
- number = strtod((const char*)number_c_string, (char**)&after_end);
337
- if (number_c_string == after_end)
338
- {
339
- return false; /* parse_error */
340
- }
341
-
342
- item->valuedouble = number;
343
-
344
- /* use saturation in case of overflow */
345
- if (number >= INT_MAX)
346
- {
347
- item->valueint = INT_MAX;
348
- }
349
- else if (number <= (double)INT_MIN)
350
- {
351
- item->valueint = INT_MIN;
352
- }
353
- else
354
- {
355
- item->valueint = (int)number;
356
- }
357
-
358
- item->type = cJSON_Number;
359
-
360
- input_buffer->offset += (size_t)(after_end - number_c_string);
361
- return true;
362
- }
363
-
364
- /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
365
- CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
366
- {
367
- if (number >= INT_MAX)
368
- {
369
- object->valueint = INT_MAX;
370
- }
371
- else if (number <= (double)INT_MIN)
372
- {
373
- object->valueint = INT_MIN;
374
- }
375
- else
376
- {
377
- object->valueint = (int)number;
378
- }
379
-
380
- return object->valuedouble = number;
381
- }
382
-
383
- typedef struct
384
- {
385
- unsigned char *buffer;
386
- size_t length;
387
- size_t offset;
388
- size_t depth; /* current nesting depth (for formatted printing) */
389
- cJSON_bool noalloc;
390
- cJSON_bool format; /* is this print a formatted print */
391
- internal_hooks hooks;
392
- } printbuffer;
393
-
394
- /* realloc printbuffer if necessary to have at least "needed" bytes more */
395
- static unsigned char* ensure(printbuffer * const p, size_t needed)
396
- {
397
- unsigned char *newbuffer = NULL;
398
- size_t newsize = 0;
399
-
400
- if ((p == NULL) || (p->buffer == NULL))
401
- {
402
- return NULL;
403
- }
404
-
405
- if ((p->length > 0) && (p->offset >= p->length))
406
- {
407
- /* make sure that offset is valid */
408
- return NULL;
409
- }
410
-
411
- if (needed > INT_MAX)
412
- {
413
- /* sizes bigger than INT_MAX are currently not supported */
414
- return NULL;
415
- }
416
-
417
- needed += p->offset + 1;
418
- if (needed <= p->length)
419
- {
420
- return p->buffer + p->offset;
421
- }
422
-
423
- if (p->noalloc) {
424
- return NULL;
425
- }
426
-
427
- /* calculate new buffer size */
428
- if (needed > (INT_MAX / 2))
429
- {
430
- /* overflow of int, use INT_MAX if possible */
431
- if (needed <= INT_MAX)
432
- {
433
- newsize = INT_MAX;
434
- }
435
- else
436
- {
437
- return NULL;
438
- }
439
- }
440
- else
441
- {
442
- newsize = needed * 2;
443
- }
444
-
445
- if (p->hooks.reallocate != NULL)
446
- {
447
- /* reallocate with realloc if available */
448
- newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
449
- if (newbuffer == NULL)
450
- {
451
- p->hooks.deallocate(p->buffer);
452
- p->length = 0;
453
- p->buffer = NULL;
454
-
455
- return NULL;
456
- }
457
- }
458
- else
459
- {
460
- /* otherwise reallocate manually */
461
- newbuffer = (unsigned char*)p->hooks.allocate(newsize);
462
- if (!newbuffer)
463
- {
464
- p->hooks.deallocate(p->buffer);
465
- p->length = 0;
466
- p->buffer = NULL;
467
-
468
- return NULL;
469
- }
470
- if (newbuffer)
471
- {
472
- memcpy(newbuffer, p->buffer, p->offset + 1);
473
- }
474
- p->hooks.deallocate(p->buffer);
475
- }
476
- p->length = newsize;
477
- p->buffer = newbuffer;
478
-
479
- return newbuffer + p->offset;
480
- }
481
-
482
- /* calculate the new length of the string in a printbuffer and update the offset */
483
- static void update_offset(printbuffer * const buffer)
484
- {
485
- const unsigned char *buffer_pointer = NULL;
486
- if ((buffer == NULL) || (buffer->buffer == NULL))
487
- {
488
- return;
489
- }
490
- buffer_pointer = buffer->buffer + buffer->offset;
491
-
492
- buffer->offset += strlen((const char*)buffer_pointer);
493
- }
494
-
495
- /* Render the number nicely from the given item into a string. */
496
- static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
497
- {
498
- unsigned char *output_pointer = NULL;
499
- double d = item->valuedouble;
500
- int length = 0;
501
- size_t i = 0;
502
- unsigned char number_buffer[26]; /* temporary buffer to print the number into */
503
- unsigned char decimal_point = get_decimal_point();
504
- double test;
505
-
506
- if (output_buffer == NULL)
507
- {
508
- return false;
509
- }
510
-
511
- /* This checks for NaN and Infinity */
512
- if ((d * 0) != 0)
513
- {
514
- length = snprintf((char*)number_buffer, sizeof(number_buffer) / sizeof(char), "null");
515
- }
516
- else
517
- {
518
- /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
519
- length = snprintf((char*)number_buffer, sizeof(number_buffer) / sizeof(char), "%1.15g", d);
520
-
521
- /* Check whether the original double can be recovered */
522
- if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
523
- {
524
- /* If not, print with 17 decimal places of precision */
525
- length = snprintf((char*)number_buffer, sizeof(number_buffer) / sizeof(char), "%1.17g", d);
526
- }
527
- }
528
-
529
- /* sprintf failed or buffer overrun occurred */
530
- if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
531
- {
532
- return false;
533
- }
534
-
535
- /* reserve appropriate space in the output */
536
- output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
537
- if (output_pointer == NULL)
538
- {
539
- return false;
540
- }
541
-
542
- /* copy the printed number to the output and replace locale
543
- * dependent decimal point with '.' */
544
- for (i = 0; i < ((size_t)length); i++)
545
- {
546
- if (number_buffer[i] == decimal_point)
547
- {
548
- output_pointer[i] = '.';
549
- continue;
550
- }
551
-
552
- output_pointer[i] = number_buffer[i];
553
- }
554
- output_pointer[i] = '\0';
555
-
556
- output_buffer->offset += (size_t)length;
557
-
558
- return true;
559
- }
560
-
561
- /* parse 4 digit hexadecimal number */
562
- static unsigned parse_hex4(const unsigned char * const input)
563
- {
564
- unsigned int h = 0;
565
- size_t i = 0;
566
-
567
- for (i = 0; i < 4; i++)
568
- {
569
- /* parse digit */
570
- if ((input[i] >= '0') && (input[i] <= '9'))
571
- {
572
- h += (unsigned int) input[i] - '0';
573
- }
574
- else if ((input[i] >= 'A') && (input[i] <= 'F'))
575
- {
576
- h += (unsigned int) 10 + input[i] - 'A';
577
- }
578
- else if ((input[i] >= 'a') && (input[i] <= 'f'))
579
- {
580
- h += (unsigned int) 10 + input[i] - 'a';
581
- }
582
- else /* invalid */
583
- {
584
- return 0;
585
- }
586
-
587
- if (i < 3)
588
- {
589
- /* shift left to make place for the next nibble */
590
- h = h << 4;
591
- }
592
- }
593
-
594
- return h;
595
- }
596
-
597
- /* converts a UTF-16 literal to UTF-8
598
- * A literal can be one or two sequences of the form \uXXXX */
599
- static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
600
- {
601
- long unsigned int codepoint = 0;
602
- unsigned int first_code = 0;
603
- const unsigned char *first_sequence = input_pointer;
604
- unsigned char utf8_length = 0;
605
- unsigned char utf8_position = 0;
606
- unsigned char sequence_length = 0;
607
- unsigned char first_byte_mark = 0;
608
-
609
- if ((input_end - first_sequence) < 6)
610
- {
611
- /* input ends unexpectedly */
612
- goto fail;
613
- }
614
-
615
- /* get the first utf16 sequence */
616
- first_code = parse_hex4(first_sequence + 2);
617
-
618
- /* check that the code is valid */
619
- if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
620
- {
621
- goto fail;
622
- }
623
-
624
- /* UTF16 surrogate pair */
625
- if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
626
- {
627
- const unsigned char *second_sequence = first_sequence + 6;
628
- unsigned int second_code = 0;
629
- sequence_length = 12; /* \uXXXX\uXXXX */
630
-
631
- if ((input_end - second_sequence) < 6)
632
- {
633
- /* input ends unexpectedly */
634
- goto fail;
635
- }
636
-
637
- if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
638
- {
639
- /* missing second half of the surrogate pair */
640
- goto fail;
641
- }
642
-
643
- /* get the second utf16 sequence */
644
- second_code = parse_hex4(second_sequence + 2);
645
- /* check that the code is valid */
646
- if ((second_code < 0xDC00) || (second_code > 0xDFFF))
647
- {
648
- /* invalid second half of the surrogate pair */
649
- goto fail;
650
- }
651
-
652
-
653
- /* calculate the unicode codepoint from the surrogate pair */
654
- codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
655
- }
656
- else
657
- {
658
- sequence_length = 6; /* \uXXXX */
659
- codepoint = first_code;
660
- }
661
-
662
- /* encode as UTF-8
663
- * takes at maximum 4 bytes to encode:
664
- * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
665
- if (codepoint < 0x80)
666
- {
667
- /* normal ascii, encoding 0xxxxxxx */
668
- utf8_length = 1;
669
- }
670
- else if (codepoint < 0x800)
671
- {
672
- /* two bytes, encoding 110xxxxx 10xxxxxx */
673
- utf8_length = 2;
674
- first_byte_mark = 0xC0; /* 11000000 */
675
- }
676
- else if (codepoint < 0x10000)
677
- {
678
- /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
679
- utf8_length = 3;
680
- first_byte_mark = 0xE0; /* 11100000 */
681
- }
682
- else if (codepoint <= 0x10FFFF)
683
- {
684
- /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
685
- utf8_length = 4;
686
- first_byte_mark = 0xF0; /* 11110000 */
687
- }
688
- else
689
- {
690
- /* invalid unicode codepoint */
691
- goto fail;
692
- }
693
-
694
- /* encode as utf8 */
695
- for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
696
- {
697
- /* 10xxxxxx */
698
- (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
699
- codepoint >>= 6;
700
- }
701
- /* encode first byte */
702
- if (utf8_length > 1)
703
- {
704
- (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
705
- }
706
- else
707
- {
708
- (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
709
- }
710
-
711
- *output_pointer += utf8_length;
712
-
713
- return sequence_length;
714
-
715
- fail:
716
- return 0;
717
- }
718
-
719
- /* Parse the input text into an unescaped cinput, and populate item. */
720
- static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
721
- {
722
- const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
723
- const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
724
- unsigned char *output_pointer = NULL;
725
- unsigned char *output = NULL;
726
-
727
- /* not a string */
728
- if (buffer_at_offset(input_buffer)[0] != '\"')
729
- {
730
- goto fail;
731
- }
732
-
733
- {
734
- /* calculate approximate size of the output (overestimate) */
735
- size_t allocation_length = 0;
736
- size_t skipped_bytes = 0;
737
- while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
738
- {
739
- /* is escape sequence */
740
- if (input_end[0] == '\\')
741
- {
742
- if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
743
- {
744
- /* prevent buffer overflow when last input character is a backslash */
745
- goto fail;
746
- }
747
- skipped_bytes++;
748
- input_end++;
749
- }
750
- input_end++;
751
- }
752
- if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
753
- {
754
- goto fail; /* string ended unexpectedly */
755
- }
756
-
757
- /* This is at most how much we need for the output */
758
- allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
759
- output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
760
- if (output == NULL)
761
- {
762
- goto fail; /* allocation failure */
763
- }
764
- }
765
-
766
- output_pointer = output;
767
- /* loop through the string literal */
768
- while (input_pointer < input_end)
769
- {
770
- if (*input_pointer != '\\')
771
- {
772
- *output_pointer++ = *input_pointer++;
773
- }
774
- /* escape sequence */
775
- else
776
- {
777
- unsigned char sequence_length = 2;
778
- if ((input_end - input_pointer) < 1)
779
- {
780
- goto fail;
781
- }
782
-
783
- switch (input_pointer[1])
784
- {
785
- case 'b':
786
- *output_pointer++ = '\b';
787
- break;
788
- case 'f':
789
- *output_pointer++ = '\f';
790
- break;
791
- case 'n':
792
- *output_pointer++ = '\n';
793
- break;
794
- case 'r':
795
- *output_pointer++ = '\r';
796
- break;
797
- case 't':
798
- *output_pointer++ = '\t';
799
- break;
800
- case '\"':
801
- case '\\':
802
- case '/':
803
- *output_pointer++ = input_pointer[1];
804
- break;
805
-
806
- /* UTF-16 literal */
807
- case 'u':
808
- sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
809
- if (sequence_length == 0)
810
- {
811
- /* failed to convert UTF16-literal to UTF-8 */
812
- goto fail;
813
- }
814
- break;
815
-
816
- default:
817
- goto fail;
818
- }
819
- input_pointer += sequence_length;
820
- }
821
- }
822
-
823
- /* zero terminate the output */
824
- *output_pointer = '\0';
825
-
826
- item->type = cJSON_String;
827
- item->valuestring = (char*)output;
828
-
829
- input_buffer->offset = (size_t) (input_end - input_buffer->content);
830
- input_buffer->offset++;
831
-
832
- return true;
833
-
834
- fail:
835
- if (output != NULL)
836
- {
837
- input_buffer->hooks.deallocate(output);
838
- }
839
-
840
- if (input_pointer != NULL)
841
- {
842
- input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
843
- }
844
-
845
- return false;
846
- }
847
-
848
- /* Render the cstring provided to an escaped version that can be printed. */
849
- static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
850
- {
851
- const unsigned char *input_pointer = NULL;
852
- unsigned char *output = NULL;
853
- unsigned char *output_pointer = NULL;
854
- size_t output_length = 0;
855
- /* numbers of additional characters needed for escaping */
856
- size_t escape_characters = 0;
857
-
858
- if (output_buffer == NULL)
859
- {
860
- return false;
861
- }
862
-
863
- /* empty string */
864
- if (input == NULL)
865
- {
866
- output = ensure(output_buffer, sizeof("\"\""));
867
- if (output == NULL)
868
- {
869
- return false;
870
- }
871
- memcpy(output, "\"\"", 3); /* NOLINT */
872
-
873
- return true;
874
- }
875
-
876
- /* set "flag" to 1 if something needs to be escaped */
877
- for (input_pointer = input; *input_pointer; input_pointer++)
878
- {
879
- switch (*input_pointer)
880
- {
881
- case '\"':
882
- case '\\':
883
- case '\b':
884
- case '\f':
885
- case '\n':
886
- case '\r':
887
- case '\t':
888
- /* one character escape sequence */
889
- escape_characters++;
890
- break;
891
- default:
892
- if (*input_pointer < 32)
893
- {
894
- /* UTF-16 escape sequence uXXXX */
895
- escape_characters += 5;
896
- }
897
- break;
898
- }
899
- }
900
- output_length = (size_t)(input_pointer - input) + escape_characters;
901
-
902
- output = ensure(output_buffer, output_length + sizeof("\"\""));
903
- if (output == NULL)
904
- {
905
- return false;
906
- }
907
-
908
- /* no characters have to be escaped */
909
- if (escape_characters == 0)
910
- {
911
- output[0] = '\"';
912
- memcpy(output + 1, input, output_length);
913
- output[output_length + 1] = '\"';
914
- output[output_length + 2] = '\0';
915
-
916
- return true;
917
- }
918
-
919
- output[0] = '\"';
920
- output_pointer = output + 1;
921
- /* copy the string */
922
- for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
923
- {
924
- if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
925
- {
926
- /* normal character, copy */
927
- *output_pointer = *input_pointer;
928
- }
929
- else
930
- {
931
- /* character needs to be escaped */
932
- *output_pointer++ = '\\';
933
- switch (*input_pointer)
934
- {
935
- case '\\':
936
- *output_pointer = '\\';
937
- break;
938
- case '\"':
939
- *output_pointer = '\"';
940
- break;
941
- case '\b':
942
- *output_pointer = 'b';
943
- break;
944
- case '\f':
945
- *output_pointer = 'f';
946
- break;
947
- case '\n':
948
- *output_pointer = 'n';
949
- break;
950
- case '\r':
951
- *output_pointer = 'r';
952
- break;
953
- case '\t':
954
- *output_pointer = 't';
955
- break;
956
- default:
957
- /* escape and print as unicode codepoint */
958
- snprintf((char*)output_pointer, 6 * sizeof(char), "u%04x", *input_pointer);
959
- output_pointer += 4;
960
- break;
961
- }
962
- }
963
- }
964
- output[output_length + 1] = '\"';
965
- output[output_length + 2] = '\0';
966
-
967
- return true;
968
- }
969
-
970
- /* Invoke print_string_ptr (which is useful) on an item. */
971
- static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
972
- {
973
- return print_string_ptr((unsigned char*)item->valuestring, p);
974
- }
975
-
976
- /* Predeclare these prototypes. */
977
- static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); /* NOLINT */
978
- static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); /* NOLINT */
979
- static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); /* NOLINT */
980
- static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); /* NOLINT */
981
- static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); /* NOLINT */
982
- static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); /* NOLINT */
983
-
984
- /* Utility to jump whitespace and cr/lf */
985
- static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
986
- {
987
- if ((buffer == NULL) || (buffer->content == NULL))
988
- {
989
- return NULL;
990
- }
991
-
992
- while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
993
- {
994
- buffer->offset++;
995
- }
996
-
997
- if (buffer->offset == buffer->length)
998
- {
999
- buffer->offset--;
1000
- }
1001
-
1002
- return buffer;
1003
- }
1004
-
1005
- /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
1006
- static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
1007
- {
1008
- if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
1009
- {
1010
- return NULL;
1011
- }
1012
-
1013
- if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
1014
- {
1015
- buffer->offset += 3;
1016
- }
1017
-
1018
- return buffer;
1019
- }
1020
-
1021
- /* Parse an object - create a new root, and populate. */
1022
- CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
1023
- {
1024
- parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1025
- cJSON *item = NULL;
1026
-
1027
- /* reset error position */
1028
- global_error.json = NULL;
1029
- global_error.position = 0;
1030
-
1031
- if (value == NULL)
1032
- {
1033
- goto fail;
1034
- }
1035
-
1036
- buffer.content = (const unsigned char*)value;
1037
- buffer.length = strlen((const char*)value) + sizeof("");
1038
- buffer.offset = 0;
1039
- buffer.hooks = global_hooks;
1040
-
1041
- item = cJSON_New_Item(&global_hooks);
1042
- if (item == NULL) /* memory fail */
1043
- {
1044
- goto fail;
1045
- }
1046
-
1047
- if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1048
- {
1049
- /* parse failure. ep is set. */
1050
- goto fail;
1051
- }
1052
-
1053
- /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1054
- if (require_null_terminated)
1055
- {
1056
- buffer_skip_whitespace(&buffer);
1057
- if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1058
- {
1059
- goto fail;
1060
- }
1061
- }
1062
- if (return_parse_end)
1063
- {
1064
- *return_parse_end = (const char*)buffer_at_offset(&buffer);
1065
- }
1066
-
1067
- return item;
1068
-
1069
- fail:
1070
- if (item != NULL)
1071
- {
1072
- cJSON_Delete(item);
1073
- }
1074
-
1075
- if (value != NULL)
1076
- {
1077
- error local_error;
1078
- local_error.json = (const unsigned char*)value;
1079
- local_error.position = 0;
1080
-
1081
- if (buffer.offset < buffer.length)
1082
- {
1083
- local_error.position = buffer.offset;
1084
- }
1085
- else if (buffer.length > 0)
1086
- {
1087
- local_error.position = buffer.length - 1;
1088
- }
1089
-
1090
- if (return_parse_end != NULL)
1091
- {
1092
- *return_parse_end = (const char*)local_error.json + local_error.position;
1093
- }
1094
-
1095
- global_error = local_error;
1096
- }
1097
-
1098
- return NULL;
1099
- }
1100
-
1101
- /* Default options for cJSON_Parse */
1102
- CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
1103
- {
1104
- return cJSON_ParseWithOpts(value, 0, 0);
1105
- }
1106
-
1107
- #define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
1108
-
1109
- static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
1110
- {
1111
- static const size_t default_buffer_size = 256;
1112
- printbuffer buffer[1];
1113
- unsigned char *printed = NULL;
1114
-
1115
- memset(buffer, 0, sizeof(buffer));
1116
-
1117
- /* create buffer */
1118
- buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1119
- buffer->length = default_buffer_size;
1120
- buffer->format = format;
1121
- buffer->hooks = *hooks;
1122
- if (buffer->buffer == NULL)
1123
- {
1124
- goto fail;
1125
- }
1126
-
1127
- /* print the value */
1128
- if (!print_value(item, buffer))
1129
- {
1130
- goto fail;
1131
- }
1132
- update_offset(buffer);
1133
-
1134
- /* check if reallocate is available */
1135
- if (hooks->reallocate != NULL)
1136
- {
1137
- printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
1138
- if (printed == NULL) {
1139
- goto fail;
1140
- }
1141
- buffer->buffer = NULL;
1142
- }
1143
- else /* otherwise copy the JSON over to a new buffer */
1144
- {
1145
- printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1146
- if (printed == NULL)
1147
- {
1148
- goto fail;
1149
- }
1150
- memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1151
- printed[buffer->offset] = '\0'; /* just to be sure */
1152
-
1153
- /* free the buffer */
1154
- hooks->deallocate(buffer->buffer);
1155
- }
1156
-
1157
- return printed;
1158
-
1159
- fail:
1160
- if (buffer->buffer != NULL)
1161
- {
1162
- hooks->deallocate(buffer->buffer);
1163
- }
1164
-
1165
- if (printed != NULL)
1166
- {
1167
- hooks->deallocate(printed);
1168
- }
1169
-
1170
- return NULL;
1171
- }
1172
-
1173
- /* Render a cJSON item/entity/structure to text. */
1174
- CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
1175
- {
1176
- return (char*)print(item, true, &global_hooks);
1177
- }
1178
-
1179
- CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
1180
- {
1181
- return (char*)print(item, false, &global_hooks);
1182
- }
1183
-
1184
- CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
1185
- {
1186
- printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1187
-
1188
- if (prebuffer < 0)
1189
- {
1190
- return NULL;
1191
- }
1192
-
1193
- p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
1194
- if (!p.buffer)
1195
- {
1196
- return NULL;
1197
- }
1198
-
1199
- p.length = (size_t)prebuffer;
1200
- p.offset = 0;
1201
- p.noalloc = false;
1202
- p.format = fmt;
1203
- p.hooks = global_hooks;
1204
-
1205
- if (!print_value(item, &p))
1206
- {
1207
- global_hooks.deallocate(p.buffer);
1208
- return NULL;
1209
- }
1210
-
1211
- return (char*)p.buffer;
1212
- }
1213
-
1214
- CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt)
1215
- {
1216
- printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1217
-
1218
- if ((len < 0) || (buf == NULL))
1219
- {
1220
- return false;
1221
- }
1222
-
1223
- p.buffer = (unsigned char*)buf;
1224
- p.length = (size_t)len;
1225
- p.offset = 0;
1226
- p.noalloc = true;
1227
- p.format = fmt;
1228
- p.hooks = global_hooks;
1229
-
1230
- return print_value(item, &p);
1231
- }
1232
-
1233
- /* Parser core - when encountering text, process appropriately. */
1234
- static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
1235
- {
1236
- if ((input_buffer == NULL) || (input_buffer->content == NULL))
1237
- {
1238
- return false; /* no input */
1239
- }
1240
-
1241
- /* parse the different types of values */
1242
- /* null */
1243
- if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1244
- {
1245
- item->type = cJSON_NULL;
1246
- input_buffer->offset += 4;
1247
- return true;
1248
- }
1249
- /* false */
1250
- if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1251
- {
1252
- item->type = cJSON_False;
1253
- input_buffer->offset += 5;
1254
- return true;
1255
- }
1256
- /* true */
1257
- if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1258
- {
1259
- item->type = cJSON_True;
1260
- item->valueint = 1;
1261
- input_buffer->offset += 4;
1262
- return true;
1263
- }
1264
- /* string */
1265
- if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1266
- {
1267
- return parse_string(item, input_buffer);
1268
- }
1269
- /* number */
1270
- if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
1271
- {
1272
- return parse_number(item, input_buffer);
1273
- }
1274
- /* array */
1275
- if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1276
- {
1277
- return parse_array(item, input_buffer);
1278
- }
1279
- /* object */
1280
- if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1281
- {
1282
- return parse_object(item, input_buffer);
1283
- }
1284
-
1285
- return false;
1286
- }
1287
-
1288
- /* Render a value to text. */
1289
- static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
1290
- {
1291
- unsigned char *output = NULL;
1292
-
1293
- if ((item == NULL) || (output_buffer == NULL))
1294
- {
1295
- return false;
1296
- }
1297
-
1298
- switch ((item->type) & 0xFF)
1299
- {
1300
- case cJSON_NULL:
1301
- output = ensure(output_buffer, 5);
1302
- if (output == NULL)
1303
- {
1304
- return false;
1305
- }
1306
- memcpy(output, "null", 5); /* NOLINT */
1307
- return true;
1308
-
1309
- case cJSON_False:
1310
- output = ensure(output_buffer, 6);
1311
- if (output == NULL)
1312
- {
1313
- return false;
1314
- }
1315
- memcpy(output, "false", 6); /* NOLINT */
1316
- return true;
1317
-
1318
- case cJSON_True:
1319
- output = ensure(output_buffer, 5);
1320
- if (output == NULL)
1321
- {
1322
- return false;
1323
- }
1324
- memcpy(output, "true", 5); /* NOLINT */
1325
- return true;
1326
-
1327
- case cJSON_Number:
1328
- return print_number(item, output_buffer);
1329
-
1330
- case cJSON_Raw:
1331
- {
1332
- size_t raw_length = 0;
1333
- if (item->valuestring == NULL)
1334
- {
1335
- return false;
1336
- }
1337
-
1338
- raw_length = strlen(item->valuestring) + sizeof("");
1339
- output = ensure(output_buffer, raw_length);
1340
- if (output == NULL)
1341
- {
1342
- return false;
1343
- }
1344
- memcpy(output, item->valuestring, raw_length);
1345
- return true;
1346
- }
1347
-
1348
- case cJSON_String:
1349
- return print_string(item, output_buffer);
1350
-
1351
- case cJSON_Array:
1352
- return print_array(item, output_buffer);
1353
-
1354
- case cJSON_Object:
1355
- return print_object(item, output_buffer);
1356
-
1357
- default:
1358
- return false;
1359
- }
1360
- }
1361
-
1362
- /* Build an array from input text. */
1363
- static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
1364
- {
1365
- cJSON *head = NULL; /* head of the linked list */
1366
- cJSON *current_item = NULL;
1367
-
1368
- if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1369
- {
1370
- return false; /* to deeply nested */
1371
- }
1372
- input_buffer->depth++;
1373
-
1374
- if (buffer_at_offset(input_buffer)[0] != '[')
1375
- {
1376
- /* not an array */
1377
- goto fail;
1378
- }
1379
-
1380
- input_buffer->offset++;
1381
- buffer_skip_whitespace(input_buffer);
1382
- if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1383
- {
1384
- /* empty array */
1385
- goto success;
1386
- }
1387
-
1388
- /* check if we skipped to the end of the buffer */
1389
- if (cannot_access_at_index(input_buffer, 0))
1390
- {
1391
- input_buffer->offset--;
1392
- goto fail;
1393
- }
1394
-
1395
- /* step back to character in front of the first element */
1396
- input_buffer->offset--;
1397
- /* loop through the comma separated array elements */
1398
- do
1399
- {
1400
- /* allocate next item */
1401
- cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1402
- if (new_item == NULL)
1403
- {
1404
- goto fail; /* allocation failure */
1405
- }
1406
-
1407
- /* attach next item to list */
1408
- if (head == NULL)
1409
- {
1410
- /* start the linked list */
1411
- current_item = head = new_item;
1412
- }
1413
- else
1414
- {
1415
- /* add to the end and advance */
1416
- current_item->next = new_item;
1417
- new_item->prev = current_item;
1418
- current_item = new_item;
1419
- }
1420
-
1421
- /* parse next value */
1422
- input_buffer->offset++;
1423
- buffer_skip_whitespace(input_buffer);
1424
- if (!parse_value(current_item, input_buffer))
1425
- {
1426
- goto fail; /* failed to parse value */
1427
- }
1428
- buffer_skip_whitespace(input_buffer);
1429
- }
1430
- while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1431
-
1432
- if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1433
- {
1434
- goto fail; /* expected end of array */
1435
- }
1436
-
1437
- success:
1438
- input_buffer->depth--;
1439
-
1440
- item->type = cJSON_Array;
1441
- item->child = head;
1442
-
1443
- input_buffer->offset++;
1444
-
1445
- return true;
1446
-
1447
- fail:
1448
- if (head != NULL)
1449
- {
1450
- cJSON_Delete(head);
1451
- }
1452
-
1453
- return false;
1454
- }
1455
-
1456
- /* Render an array to text */
1457
- static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
1458
- {
1459
- unsigned char *output_pointer = NULL;
1460
- size_t length = 0;
1461
- cJSON *current_element = item->child;
1462
-
1463
- if (output_buffer == NULL)
1464
- {
1465
- return false;
1466
- }
1467
-
1468
- /* Compose the output array. */
1469
- /* opening square bracket */
1470
- output_pointer = ensure(output_buffer, 1);
1471
- if (output_pointer == NULL)
1472
- {
1473
- return false;
1474
- }
1475
-
1476
- *output_pointer = '[';
1477
- output_buffer->offset++;
1478
- output_buffer->depth++;
1479
-
1480
- while (current_element != NULL)
1481
- {
1482
- if (!print_value(current_element, output_buffer))
1483
- {
1484
- return false;
1485
- }
1486
- update_offset(output_buffer);
1487
- if (current_element->next)
1488
- {
1489
- length = (size_t) (output_buffer->format ? 2 : 1);
1490
- output_pointer = ensure(output_buffer, length + 1);
1491
- if (output_pointer == NULL)
1492
- {
1493
- return false;
1494
- }
1495
- *output_pointer++ = ',';
1496
- if(output_buffer->format)
1497
- {
1498
- *output_pointer++ = ' ';
1499
- }
1500
- *output_pointer = '\0';
1501
- output_buffer->offset += length;
1502
- }
1503
- current_element = current_element->next;
1504
- }
1505
-
1506
- output_pointer = ensure(output_buffer, 2);
1507
- if (output_pointer == NULL)
1508
- {
1509
- return false;
1510
- }
1511
- *output_pointer++ = ']';
1512
- *output_pointer = '\0';
1513
- output_buffer->depth--;
1514
-
1515
- return true;
1516
- }
1517
-
1518
- /* Build an object from the text. */
1519
- static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
1520
- {
1521
- cJSON *head = NULL; /* linked list head */
1522
- cJSON *current_item = NULL;
1523
-
1524
- if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1525
- {
1526
- return false; /* to deeply nested */
1527
- }
1528
- input_buffer->depth++;
1529
-
1530
- if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1531
- {
1532
- goto fail; /* not an object */
1533
- }
1534
-
1535
- input_buffer->offset++;
1536
- buffer_skip_whitespace(input_buffer);
1537
- if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1538
- {
1539
- goto success; /* empty object */
1540
- }
1541
-
1542
- /* check if we skipped to the end of the buffer */
1543
- if (cannot_access_at_index(input_buffer, 0))
1544
- {
1545
- input_buffer->offset--;
1546
- goto fail;
1547
- }
1548
-
1549
- /* step back to character in front of the first element */
1550
- input_buffer->offset--;
1551
- /* loop through the comma separated array elements */
1552
- do
1553
- {
1554
- /* allocate next item */
1555
- cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1556
- if (new_item == NULL)
1557
- {
1558
- goto fail; /* allocation failure */
1559
- }
1560
-
1561
- /* attach next item to list */
1562
- if (head == NULL)
1563
- {
1564
- /* start the linked list */
1565
- current_item = head = new_item;
1566
- }
1567
- else
1568
- {
1569
- /* add to the end and advance */
1570
- current_item->next = new_item;
1571
- new_item->prev = current_item;
1572
- current_item = new_item;
1573
- }
1574
-
1575
- /* parse the name of the child */
1576
- input_buffer->offset++;
1577
- buffer_skip_whitespace(input_buffer);
1578
- if (!parse_string(current_item, input_buffer))
1579
- {
1580
- goto fail; /* failed to parse name */
1581
- }
1582
- buffer_skip_whitespace(input_buffer);
1583
-
1584
- /* swap valuestring and string, because we parsed the name */
1585
- current_item->string = current_item->valuestring;
1586
- current_item->valuestring = NULL;
1587
-
1588
- if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1589
- {
1590
- goto fail; /* invalid object */
1591
- }
1592
-
1593
- /* parse the value */
1594
- input_buffer->offset++;
1595
- buffer_skip_whitespace(input_buffer);
1596
- if (!parse_value(current_item, input_buffer))
1597
- {
1598
- goto fail; /* failed to parse value */
1599
- }
1600
- buffer_skip_whitespace(input_buffer);
1601
- }
1602
- while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1603
-
1604
- if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1605
- {
1606
- goto fail; /* expected end of object */
1607
- }
1608
-
1609
- success:
1610
- input_buffer->depth--;
1611
-
1612
- item->type = cJSON_Object;
1613
- item->child = head;
1614
-
1615
- input_buffer->offset++;
1616
- return true;
1617
-
1618
- fail:
1619
- if (head != NULL)
1620
- {
1621
- cJSON_Delete(head);
1622
- }
1623
-
1624
- return false;
1625
- }
1626
-
1627
- /* Render an object to text. */
1628
- static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
1629
- {
1630
- unsigned char *output_pointer = NULL;
1631
- size_t length = 0;
1632
- cJSON *current_item = item->child;
1633
-
1634
- if (output_buffer == NULL)
1635
- {
1636
- return false;
1637
- }
1638
-
1639
- /* Compose the output: */
1640
- length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1641
- output_pointer = ensure(output_buffer, length + 1);
1642
- if (output_pointer == NULL)
1643
- {
1644
- return false;
1645
- }
1646
-
1647
- *output_pointer++ = '{';
1648
- output_buffer->depth++;
1649
- if (output_buffer->format)
1650
- {
1651
- *output_pointer++ = '\n';
1652
- }
1653
- output_buffer->offset += length;
1654
-
1655
- while (current_item)
1656
- {
1657
- if (output_buffer->format)
1658
- {
1659
- size_t i;
1660
- output_pointer = ensure(output_buffer, output_buffer->depth);
1661
- if (output_pointer == NULL)
1662
- {
1663
- return false;
1664
- }
1665
- for (i = 0; i < output_buffer->depth; i++)
1666
- {
1667
- *output_pointer++ = '\t';
1668
- }
1669
- output_buffer->offset += output_buffer->depth;
1670
- }
1671
-
1672
- /* print key */
1673
- if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1674
- {
1675
- return false;
1676
- }
1677
- update_offset(output_buffer);
1678
-
1679
- length = (size_t) (output_buffer->format ? 2 : 1);
1680
- output_pointer = ensure(output_buffer, length);
1681
- if (output_pointer == NULL)
1682
- {
1683
- return false;
1684
- }
1685
- *output_pointer++ = ':';
1686
- if (output_buffer->format)
1687
- {
1688
- *output_pointer++ = '\t';
1689
- }
1690
- output_buffer->offset += length;
1691
-
1692
- /* print value */
1693
- if (!print_value(current_item, output_buffer))
1694
- {
1695
- return false;
1696
- }
1697
- update_offset(output_buffer);
1698
-
1699
- /* print comma if not last */
1700
- length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
1701
- output_pointer = ensure(output_buffer, length + 1);
1702
- if (output_pointer == NULL)
1703
- {
1704
- return false;
1705
- }
1706
- if (current_item->next)
1707
- {
1708
- *output_pointer++ = ',';
1709
- }
1710
-
1711
- if (output_buffer->format)
1712
- {
1713
- *output_pointer++ = '\n';
1714
- }
1715
- *output_pointer = '\0';
1716
- output_buffer->offset += length;
1717
-
1718
- current_item = current_item->next;
1719
- }
1720
-
1721
- output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1722
- if (output_pointer == NULL)
1723
- {
1724
- return false;
1725
- }
1726
- if (output_buffer->format)
1727
- {
1728
- size_t i;
1729
- for (i = 0; i < (output_buffer->depth - 1); i++)
1730
- {
1731
- *output_pointer++ = '\t';
1732
- }
1733
- }
1734
- *output_pointer++ = '}';
1735
- *output_pointer = '\0';
1736
- output_buffer->depth--;
1737
-
1738
- return true;
1739
- }
1740
-
1741
- /* Get Array size/item / object item. */
1742
- CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
1743
- {
1744
- cJSON *child = NULL;
1745
- size_t size = 0;
1746
-
1747
- if (array == NULL)
1748
- {
1749
- return 0;
1750
- }
1751
-
1752
- child = array->child;
1753
-
1754
- while(child != NULL)
1755
- {
1756
- size++;
1757
- child = child->next;
1758
- }
1759
-
1760
- /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1761
-
1762
- return (int)size;
1763
- }
1764
-
1765
- static cJSON* get_array_item(const cJSON *array, size_t index)
1766
- {
1767
- cJSON *current_child = NULL;
1768
-
1769
- if (array == NULL)
1770
- {
1771
- return NULL;
1772
- }
1773
-
1774
- current_child = array->child;
1775
- while ((current_child != NULL) && (index > 0))
1776
- {
1777
- index--;
1778
- current_child = current_child->next;
1779
- }
1780
-
1781
- return current_child;
1782
- }
1783
-
1784
- CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
1785
- {
1786
- if (index < 0)
1787
- {
1788
- return NULL;
1789
- }
1790
-
1791
- return get_array_item(array, (size_t)index);
1792
- }
1793
-
1794
- static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
1795
- {
1796
- cJSON *current_element = NULL;
1797
-
1798
- if ((object == NULL) || (name == NULL))
1799
- {
1800
- return NULL;
1801
- }
1802
-
1803
- current_element = object->child;
1804
- if (case_sensitive)
1805
- {
1806
- while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
1807
- {
1808
- current_element = current_element->next;
1809
- }
1810
- }
1811
- else
1812
- {
1813
- while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1814
- {
1815
- current_element = current_element->next;
1816
- }
1817
- }
1818
-
1819
- if ((current_element == NULL) || (current_element->string == NULL)) {
1820
- return NULL;
1821
- }
1822
-
1823
- return current_element;
1824
- }
1825
-
1826
- CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
1827
- {
1828
- return get_object_item(object, string, false);
1829
- }
1830
-
1831
- CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
1832
- {
1833
- return get_object_item(object, string, true);
1834
- }
1835
-
1836
- CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
1837
- {
1838
- return cJSON_GetObjectItem(object, string) ? 1 : 0;
1839
- }
1840
-
1841
- /* Utility for array list handling. */
1842
- static void suffix_object(cJSON *prev, cJSON *item)
1843
- {
1844
- prev->next = item;
1845
- item->prev = prev;
1846
- }
1847
-
1848
- /* Utility for handling references. */
1849
- static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
1850
- {
1851
- cJSON *reference = NULL;
1852
- if (item == NULL)
1853
- {
1854
- return NULL;
1855
- }
1856
-
1857
- reference = cJSON_New_Item(hooks);
1858
- if (reference == NULL)
1859
- {
1860
- return NULL;
1861
- }
1862
-
1863
- memcpy(reference, item, sizeof(cJSON));
1864
- reference->string = NULL;
1865
- reference->type |= cJSON_IsReference;
1866
- reference->next = reference->prev = NULL;
1867
- return reference;
1868
- }
1869
-
1870
- static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
1871
- {
1872
- cJSON *child = NULL;
1873
-
1874
- if ((item == NULL) || (array == NULL))
1875
- {
1876
- return false;
1877
- }
1878
-
1879
- child = array->child;
1880
-
1881
- if (child == NULL)
1882
- {
1883
- /* list is empty, start new one */
1884
- array->child = item;
1885
- }
1886
- else
1887
- {
1888
- /* append to the end */
1889
- while (child->next)
1890
- {
1891
- child = child->next;
1892
- }
1893
- suffix_object(child, item);
1894
- }
1895
-
1896
- return true;
1897
- }
1898
-
1899
- /* Add item to array/object. */
1900
- CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
1901
- {
1902
- add_item_to_array(array, item);
1903
- }
1904
-
1905
- #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1906
- #pragma GCC diagnostic push
1907
- #endif
1908
- #ifdef __GNUC__
1909
- #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)))
1910
- #pragma GCC diagnostic ignored "-Wcast-qual"
1911
- #endif
1912
- #endif
1913
- /* helper function to cast away const */
1914
- static void* cast_away_const(const void* string)
1915
- {
1916
- return (void*)string;
1917
- }
1918
- #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1919
- #pragma GCC diagnostic pop
1920
- #endif
1921
-
1922
-
1923
- static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
1924
- {
1925
- char *new_key = NULL;
1926
- int new_type = cJSON_Invalid;
1927
-
1928
- if ((object == NULL) || (string == NULL) || (item == NULL))
1929
- {
1930
- return false;
1931
- }
1932
-
1933
- if (constant_key)
1934
- {
1935
- new_key = (char*)cast_away_const(string);
1936
- new_type = item->type | cJSON_StringIsConst;
1937
- }
1938
- else
1939
- {
1940
- new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
1941
- if (new_key == NULL)
1942
- {
1943
- return false;
1944
- }
1945
-
1946
- new_type = item->type & ~cJSON_StringIsConst;
1947
- }
1948
-
1949
- if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
1950
- {
1951
- hooks->deallocate(item->string);
1952
- }
1953
-
1954
- item->string = new_key;
1955
- item->type = new_type;
1956
-
1957
- return add_item_to_array(object, item);
1958
- }
1959
-
1960
- CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
1961
- {
1962
- add_item_to_object(object, string, item, &global_hooks, false);
1963
- }
1964
-
1965
- /* Add an item to an object with constant string as key */
1966
- CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
1967
- {
1968
- add_item_to_object(object, string, item, &global_hooks, true);
1969
- }
1970
-
1971
- CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
1972
- {
1973
- if (array == NULL)
1974
- {
1975
- return;
1976
- }
1977
-
1978
- add_item_to_array(array, create_reference(item, &global_hooks));
1979
- }
1980
-
1981
- CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
1982
- {
1983
- if ((object == NULL) || (string == NULL))
1984
- {
1985
- return;
1986
- }
1987
-
1988
- add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
1989
- }
1990
-
1991
- CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
1992
- {
1993
- cJSON *null = cJSON_CreateNull();
1994
- if (add_item_to_object(object, name, null, &global_hooks, false))
1995
- {
1996
- return null;
1997
- }
1998
-
1999
- cJSON_Delete(null);
2000
- return NULL;
2001
- }
2002
-
2003
- CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
2004
- {
2005
- cJSON *true_item = cJSON_CreateTrue();
2006
- if (add_item_to_object(object, name, true_item, &global_hooks, false))
2007
- {
2008
- return true_item;
2009
- }
2010
-
2011
- cJSON_Delete(true_item);
2012
- return NULL;
2013
- }
2014
-
2015
- CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
2016
- {
2017
- cJSON *false_item = cJSON_CreateFalse();
2018
- if (add_item_to_object(object, name, false_item, &global_hooks, false))
2019
- {
2020
- return false_item;
2021
- }
2022
-
2023
- cJSON_Delete(false_item);
2024
- return NULL;
2025
- }
2026
-
2027
- CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
2028
- {
2029
- cJSON *bool_item = cJSON_CreateBool(boolean);
2030
- if (add_item_to_object(object, name, bool_item, &global_hooks, false))
2031
- {
2032
- return bool_item;
2033
- }
2034
-
2035
- cJSON_Delete(bool_item);
2036
- return NULL;
2037
- }
2038
-
2039
- CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
2040
- {
2041
- cJSON *number_item = cJSON_CreateNumber(number);
2042
- if (add_item_to_object(object, name, number_item, &global_hooks, false))
2043
- {
2044
- return number_item;
2045
- }
2046
-
2047
- cJSON_Delete(number_item);
2048
- return NULL;
2049
- }
2050
-
2051
- CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
2052
- {
2053
- cJSON *string_item = cJSON_CreateString(string);
2054
- if (add_item_to_object(object, name, string_item, &global_hooks, false))
2055
- {
2056
- return string_item;
2057
- }
2058
-
2059
- cJSON_Delete(string_item);
2060
- return NULL;
2061
- }
2062
-
2063
- CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
2064
- {
2065
- cJSON *raw_item = cJSON_CreateRaw(raw);
2066
- if (add_item_to_object(object, name, raw_item, &global_hooks, false))
2067
- {
2068
- return raw_item;
2069
- }
2070
-
2071
- cJSON_Delete(raw_item);
2072
- return NULL;
2073
- }
2074
-
2075
- CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
2076
- {
2077
- cJSON *object_item = cJSON_CreateObject();
2078
- if (add_item_to_object(object, name, object_item, &global_hooks, false))
2079
- {
2080
- return object_item;
2081
- }
2082
-
2083
- cJSON_Delete(object_item);
2084
- return NULL;
2085
- }
2086
-
2087
- CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
2088
- {
2089
- cJSON *array = cJSON_CreateArray();
2090
- if (add_item_to_object(object, name, array, &global_hooks, false))
2091
- {
2092
- return array;
2093
- }
2094
-
2095
- cJSON_Delete(array);
2096
- return NULL;
2097
- }
2098
-
2099
- CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2100
- {
2101
- if ((parent == NULL) || (item == NULL))
2102
- {
2103
- return NULL;
2104
- }
2105
-
2106
- if (item->prev != NULL)
2107
- {
2108
- /* not the first element */
2109
- item->prev->next = item->next;
2110
- }
2111
- if (item->next != NULL)
2112
- {
2113
- /* not the last element */
2114
- item->next->prev = item->prev;
2115
- }
2116
-
2117
- if (item == parent->child)
2118
- {
2119
- /* first element */
2120
- parent->child = item->next;
2121
- }
2122
- /* make sure the detached item doesn't point anywhere anymore */
2123
- item->prev = NULL;
2124
- item->next = NULL;
2125
-
2126
- return item;
2127
- }
2128
-
2129
- CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
2130
- {
2131
- if (which < 0)
2132
- {
2133
- return NULL;
2134
- }
2135
-
2136
- return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
2137
- }
2138
-
2139
- CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
2140
- {
2141
- cJSON_Delete(cJSON_DetachItemFromArray(array, which));
2142
- }
2143
-
2144
- CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
2145
- {
2146
- cJSON *to_detach = cJSON_GetObjectItem(object, string);
2147
-
2148
- return cJSON_DetachItemViaPointer(object, to_detach);
2149
- }
2150
-
2151
- CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
2152
- {
2153
- cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
2154
-
2155
- return cJSON_DetachItemViaPointer(object, to_detach);
2156
- }
2157
-
2158
- CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2159
- {
2160
- cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2161
- }
2162
-
2163
- CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
2164
- {
2165
- cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
2166
- }
2167
-
2168
- /* Replace array/object items with new ones. */
2169
- CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2170
- {
2171
- cJSON *after_inserted = NULL;
2172
-
2173
- if (which < 0)
2174
- {
2175
- return;
2176
- }
2177
-
2178
- after_inserted = get_array_item(array, (size_t)which);
2179
- if (after_inserted == NULL)
2180
- {
2181
- add_item_to_array(array, newitem);
2182
- return;
2183
- }
2184
-
2185
- newitem->next = after_inserted;
2186
- newitem->prev = after_inserted->prev;
2187
- after_inserted->prev = newitem;
2188
- if (after_inserted == array->child)
2189
- {
2190
- array->child = newitem;
2191
- }
2192
- else
2193
- {
2194
- newitem->prev->next = newitem;
2195
- }
2196
- }
2197
-
2198
- CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2199
- {
2200
- if ((parent == NULL) || (replacement == NULL) || (item == NULL))
2201
- {
2202
- return false;
2203
- }
2204
-
2205
- if (replacement == item)
2206
- {
2207
- return true;
2208
- }
2209
-
2210
- replacement->next = item->next;
2211
- replacement->prev = item->prev;
2212
-
2213
- if (replacement->next != NULL)
2214
- {
2215
- replacement->next->prev = replacement;
2216
- }
2217
- if (replacement->prev != NULL)
2218
- {
2219
- replacement->prev->next = replacement;
2220
- }
2221
- if (parent->child == item)
2222
- {
2223
- parent->child = replacement;
2224
- }
2225
-
2226
- item->next = NULL;
2227
- item->prev = NULL;
2228
- cJSON_Delete(item);
2229
-
2230
- return true;
2231
- }
2232
-
2233
- CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2234
- {
2235
- if (which < 0)
2236
- {
2237
- return;
2238
- }
2239
-
2240
- cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
2241
- }
2242
-
2243
- static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
2244
- {
2245
- if ((replacement == NULL) || (string == NULL))
2246
- {
2247
- return false;
2248
- }
2249
-
2250
- /* replace the name in the replacement */
2251
- if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2252
- {
2253
- cJSON_free(replacement->string);
2254
- }
2255
- replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2256
- replacement->type &= ~cJSON_StringIsConst;
2257
-
2258
- cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2259
-
2260
- return true;
2261
- }
2262
-
2263
- CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2264
- {
2265
- replace_item_in_object(object, string, newitem, false);
2266
- }
2267
-
2268
- CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
2269
- {
2270
- replace_item_in_object(object, string, newitem, true);
2271
- }
2272
-
2273
- /* Create basic types: */
2274
- CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
2275
- {
2276
- cJSON *item = cJSON_New_Item(&global_hooks);
2277
- if(item)
2278
- {
2279
- item->type = cJSON_NULL;
2280
- }
2281
-
2282
- return item;
2283
- }
2284
-
2285
- CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
2286
- {
2287
- cJSON *item = cJSON_New_Item(&global_hooks);
2288
- if(item)
2289
- {
2290
- item->type = cJSON_True;
2291
- }
2292
-
2293
- return item;
2294
- }
2295
-
2296
- CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
2297
- {
2298
- cJSON *item = cJSON_New_Item(&global_hooks);
2299
- if(item)
2300
- {
2301
- item->type = cJSON_False;
2302
- }
2303
-
2304
- return item;
2305
- }
2306
-
2307
- CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
2308
- {
2309
- cJSON *item = cJSON_New_Item(&global_hooks);
2310
- if(item)
2311
- {
2312
- item->type = b ? cJSON_True : cJSON_False;
2313
- }
2314
-
2315
- return item;
2316
- }
2317
-
2318
- CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
2319
- {
2320
- cJSON *item = cJSON_New_Item(&global_hooks);
2321
- if(item)
2322
- {
2323
- item->type = cJSON_Number;
2324
- item->valuedouble = num;
2325
-
2326
- /* use saturation in case of overflow */
2327
- if (num >= INT_MAX)
2328
- {
2329
- item->valueint = INT_MAX;
2330
- }
2331
- else if (num <= (double)INT_MIN)
2332
- {
2333
- item->valueint = INT_MIN;
2334
- }
2335
- else
2336
- {
2337
- item->valueint = (int)num;
2338
- }
2339
- }
2340
-
2341
- return item;
2342
- }
2343
-
2344
- CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
2345
- {
2346
- cJSON *item = cJSON_New_Item(&global_hooks);
2347
- if(item)
2348
- {
2349
- item->type = cJSON_String;
2350
- item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2351
- if(!item->valuestring)
2352
- {
2353
- cJSON_Delete(item);
2354
- return NULL;
2355
- }
2356
- }
2357
-
2358
- return item;
2359
- }
2360
-
2361
- CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
2362
- {
2363
- cJSON *item = cJSON_New_Item(&global_hooks);
2364
- if (item != NULL)
2365
- {
2366
- item->type = cJSON_String | cJSON_IsReference;
2367
- item->valuestring = (char*)cast_away_const(string);
2368
- }
2369
-
2370
- return item;
2371
- }
2372
-
2373
- CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
2374
- {
2375
- cJSON *item = cJSON_New_Item(&global_hooks);
2376
- if (item != NULL) {
2377
- item->type = cJSON_Object | cJSON_IsReference;
2378
- item->child = (cJSON*)cast_away_const(child);
2379
- }
2380
-
2381
- return item;
2382
- }
2383
-
2384
- CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
2385
- cJSON *item = cJSON_New_Item(&global_hooks);
2386
- if (item != NULL) {
2387
- item->type = cJSON_Array | cJSON_IsReference;
2388
- item->child = (cJSON*)cast_away_const(child);
2389
- }
2390
-
2391
- return item;
2392
- }
2393
-
2394
- CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
2395
- {
2396
- cJSON *item = cJSON_New_Item(&global_hooks);
2397
- if(item)
2398
- {
2399
- item->type = cJSON_Raw;
2400
- item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
2401
- if(!item->valuestring)
2402
- {
2403
- cJSON_Delete(item);
2404
- return NULL;
2405
- }
2406
- }
2407
-
2408
- return item;
2409
- }
2410
-
2411
- CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
2412
- {
2413
- cJSON *item = cJSON_New_Item(&global_hooks);
2414
- if(item)
2415
- {
2416
- item->type=cJSON_Array;
2417
- }
2418
-
2419
- return item;
2420
- }
2421
-
2422
- CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
2423
- {
2424
- cJSON *item = cJSON_New_Item(&global_hooks);
2425
- if (item)
2426
- {
2427
- item->type = cJSON_Object;
2428
- }
2429
-
2430
- return item;
2431
- }
2432
-
2433
- /* Create Arrays: */
2434
- CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
2435
- {
2436
- size_t i = 0;
2437
- cJSON *n = NULL;
2438
- cJSON *p = NULL;
2439
- cJSON *a = NULL;
2440
-
2441
- if ((count < 0) || (numbers == NULL))
2442
- {
2443
- return NULL;
2444
- }
2445
-
2446
- a = cJSON_CreateArray();
2447
- for(i = 0; a && (i < (size_t)count); i++)
2448
- {
2449
- n = cJSON_CreateNumber(numbers[i]);
2450
- if (!n)
2451
- {
2452
- cJSON_Delete(a);
2453
- return NULL;
2454
- }
2455
- if(!i)
2456
- {
2457
- a->child = n;
2458
- }
2459
- else
2460
- {
2461
- suffix_object(p, n);
2462
- }
2463
- p = n;
2464
- }
2465
-
2466
- return a;
2467
- }
2468
-
2469
- CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
2470
- {
2471
- size_t i = 0;
2472
- cJSON *n = NULL;
2473
- cJSON *p = NULL;
2474
- cJSON *a = NULL;
2475
-
2476
- if ((count < 0) || (numbers == NULL))
2477
- {
2478
- return NULL;
2479
- }
2480
-
2481
- a = cJSON_CreateArray();
2482
-
2483
- for(i = 0; a && (i < (size_t)count); i++)
2484
- {
2485
- n = cJSON_CreateNumber((double)numbers[i]);
2486
- if(!n)
2487
- {
2488
- cJSON_Delete(a);
2489
- return NULL;
2490
- }
2491
- if(!i)
2492
- {
2493
- a->child = n;
2494
- }
2495
- else
2496
- {
2497
- suffix_object(p, n);
2498
- }
2499
- p = n;
2500
- }
2501
-
2502
- return a;
2503
- }
2504
-
2505
- CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
2506
- {
2507
- size_t i = 0;
2508
- cJSON *n = NULL;
2509
- cJSON *p = NULL;
2510
- cJSON *a = NULL;
2511
-
2512
- if ((count < 0) || (numbers == NULL))
2513
- {
2514
- return NULL;
2515
- }
2516
-
2517
- a = cJSON_CreateArray();
2518
-
2519
- for(i = 0;a && (i < (size_t)count); i++)
2520
- {
2521
- n = cJSON_CreateNumber(numbers[i]);
2522
- if(!n)
2523
- {
2524
- cJSON_Delete(a);
2525
- return NULL;
2526
- }
2527
- if(!i)
2528
- {
2529
- a->child = n;
2530
- }
2531
- else
2532
- {
2533
- suffix_object(p, n);
2534
- }
2535
- p = n;
2536
- }
2537
-
2538
- return a;
2539
- }
2540
-
2541
- CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
2542
- {
2543
- size_t i = 0;
2544
- cJSON *n = NULL;
2545
- cJSON *p = NULL;
2546
- cJSON *a = NULL;
2547
-
2548
- if ((count < 0) || (strings == NULL))
2549
- {
2550
- return NULL;
2551
- }
2552
-
2553
- a = cJSON_CreateArray();
2554
-
2555
- for (i = 0; a && (i < (size_t)count); i++)
2556
- {
2557
- n = cJSON_CreateString(strings[i]);
2558
- if(!n)
2559
- {
2560
- cJSON_Delete(a);
2561
- return NULL;
2562
- }
2563
- if(!i)
2564
- {
2565
- a->child = n;
2566
- }
2567
- else
2568
- {
2569
- suffix_object(p,n);
2570
- }
2571
- p = n;
2572
- }
2573
-
2574
- return a;
2575
- }
2576
-
2577
- /* Duplication */
2578
- CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2579
- {
2580
- cJSON *newitem = NULL;
2581
- cJSON *child = NULL;
2582
- cJSON *next = NULL;
2583
- cJSON *newchild = NULL;
2584
-
2585
- /* Bail on bad ptr */
2586
- if (!item)
2587
- {
2588
- goto fail;
2589
- }
2590
- /* Create new item */
2591
- newitem = cJSON_New_Item(&global_hooks);
2592
- if (!newitem)
2593
- {
2594
- goto fail;
2595
- }
2596
- /* Copy over all vars */
2597
- newitem->type = item->type & (~cJSON_IsReference);
2598
- newitem->valueint = item->valueint;
2599
- newitem->valuedouble = item->valuedouble;
2600
- if (item->valuestring)
2601
- {
2602
- newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
2603
- if (!newitem->valuestring)
2604
- {
2605
- goto fail;
2606
- }
2607
- }
2608
- if (item->string)
2609
- {
2610
- newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
2611
- if (!newitem->string)
2612
- {
2613
- goto fail;
2614
- }
2615
- }
2616
- /* If non-recursive, then we're done! */
2617
- if (!recurse)
2618
- {
2619
- return newitem;
2620
- }
2621
- /* Walk the ->next chain for the child. */
2622
- child = item->child;
2623
- while (child != NULL)
2624
- {
2625
- newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2626
- if (!newchild)
2627
- {
2628
- goto fail;
2629
- }
2630
- if (next != NULL)
2631
- {
2632
- /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2633
- next->next = newchild;
2634
- newchild->prev = next;
2635
- next = newchild;
2636
- }
2637
- else
2638
- {
2639
- /* Set newitem->child and move to it */
2640
- newitem->child = newchild;
2641
- next = newchild;
2642
- }
2643
- child = child->next;
2644
- }
2645
-
2646
- return newitem;
2647
-
2648
- fail:
2649
- if (newitem != NULL)
2650
- {
2651
- cJSON_Delete(newitem);
2652
- }
2653
-
2654
- return NULL;
2655
- }
2656
-
2657
- static void skip_oneline_comment(char **input)
2658
- {
2659
- *input += static_strlen("//");
2660
-
2661
- for (; (*input)[0] != '\0'; ++(*input))
2662
- {
2663
- if ((*input)[0] == '\n') {
2664
- *input += static_strlen("\n");
2665
- return;
2666
- }
2667
- }
2668
- }
2669
-
2670
- static void skip_multiline_comment(char **input)
2671
- {
2672
- *input += static_strlen("/*");
2673
-
2674
- for (; (*input)[0] != '\0'; ++(*input))
2675
- {
2676
- if (((*input)[0] == '*') && ((*input)[1] == '/'))
2677
- {
2678
- *input += static_strlen("*/");
2679
- return;
2680
- }
2681
- }
2682
- }
2683
-
2684
- static void minify_string(char **input, char **output) {
2685
- (*output)[0] = (*input)[0];
2686
- *input += static_strlen("\"");
2687
- *output += static_strlen("\"");
2688
-
2689
-
2690
- for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
2691
- (*output)[0] = (*input)[0];
2692
-
2693
- if ((*input)[0] == '\"') {
2694
- (*output)[0] = '\"';
2695
- *input += static_strlen("\"");
2696
- *output += static_strlen("\"");
2697
- return;
2698
- } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { /* NOLINT */
2699
- (*output)[1] = (*input)[1];
2700
- *input += static_strlen("\"");
2701
- *output += static_strlen("\"");
2702
- }
2703
- }
2704
- }
2705
-
2706
- CJSON_PUBLIC(void) cJSON_Minify(char *json)
2707
- {
2708
- char *into = json;
2709
-
2710
- if (json == NULL)
2711
- {
2712
- return;
2713
- }
2714
-
2715
- while (json[0] != '\0')
2716
- {
2717
- switch (json[0])
2718
- {
2719
- case ' ':
2720
- case '\t':
2721
- case '\r':
2722
- case '\n':
2723
- json++;
2724
- break;
2725
-
2726
- case '/':
2727
- if (json[1] == '/')
2728
- {
2729
- skip_oneline_comment(&json);
2730
- }
2731
- else if (json[1] == '*')
2732
- {
2733
- skip_multiline_comment(&json);
2734
- } else {
2735
- json++;
2736
- }
2737
- break;
2738
-
2739
- case '\"':
2740
- minify_string(&json, (char**)&into);
2741
- break;
2742
-
2743
- default:
2744
- into[0] = json[0];
2745
- json++;
2746
- into++;
2747
- }
2748
- }
2749
-
2750
- /* and null-terminate. */
2751
- *into = '\0';
2752
- }
2753
-
2754
- CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
2755
- {
2756
- if (item == NULL)
2757
- {
2758
- return false;
2759
- }
2760
-
2761
- return (item->type & 0xFF) == cJSON_Invalid;
2762
- }
2763
-
2764
- CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
2765
- {
2766
- if (item == NULL)
2767
- {
2768
- return false;
2769
- }
2770
-
2771
- return (item->type & 0xFF) == cJSON_False;
2772
- }
2773
-
2774
- CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
2775
- {
2776
- if (item == NULL)
2777
- {
2778
- return false;
2779
- }
2780
-
2781
- return (item->type & 0xff) == cJSON_True;
2782
- }
2783
-
2784
-
2785
- CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
2786
- {
2787
- if (item == NULL)
2788
- {
2789
- return false;
2790
- }
2791
-
2792
- return (item->type & (cJSON_True | cJSON_False)) != 0;
2793
- }
2794
- CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
2795
- {
2796
- if (item == NULL)
2797
- {
2798
- return false;
2799
- }
2800
-
2801
- return (item->type & 0xFF) == cJSON_NULL;
2802
- }
2803
-
2804
- CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
2805
- {
2806
- if (item == NULL)
2807
- {
2808
- return false;
2809
- }
2810
-
2811
- return (item->type & 0xFF) == cJSON_Number;
2812
- }
2813
-
2814
- CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
2815
- {
2816
- if (item == NULL)
2817
- {
2818
- return false;
2819
- }
2820
-
2821
- return (item->type & 0xFF) == cJSON_String;
2822
- }
2823
-
2824
- CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
2825
- {
2826
- if (item == NULL)
2827
- {
2828
- return false;
2829
- }
2830
-
2831
- return (item->type & 0xFF) == cJSON_Array;
2832
- }
2833
-
2834
- CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
2835
- {
2836
- if (item == NULL)
2837
- {
2838
- return false;
2839
- }
2840
-
2841
- return (item->type & 0xFF) == cJSON_Object;
2842
- }
2843
-
2844
- CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
2845
- {
2846
- if (item == NULL)
2847
- {
2848
- return false;
2849
- }
2850
-
2851
- return (item->type & 0xFF) == cJSON_Raw;
2852
- }
2853
-
2854
- CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
2855
- {
2856
- if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
2857
- {
2858
- return false;
2859
- }
2860
-
2861
- /* check if type is valid */
2862
- switch (a->type & 0xFF)
2863
- {
2864
- case cJSON_False:
2865
- case cJSON_True:
2866
- case cJSON_NULL:
2867
- case cJSON_Number:
2868
- case cJSON_String:
2869
- case cJSON_Raw:
2870
- case cJSON_Array:
2871
- case cJSON_Object:
2872
- break;
2873
-
2874
- default:
2875
- return false;
2876
- }
2877
-
2878
- /* identical objects are equal */
2879
- if (a == b)
2880
- {
2881
- return true;
2882
- }
2883
-
2884
- switch (a->type & 0xFF)
2885
- {
2886
- /* in these cases and equal type is enough */
2887
- case cJSON_False:
2888
- case cJSON_True:
2889
- case cJSON_NULL:
2890
- return true;
2891
-
2892
- case cJSON_Number:
2893
- if (a->valuedouble == b->valuedouble)
2894
- {
2895
- return true;
2896
- }
2897
- return false;
2898
-
2899
- case cJSON_String:
2900
- case cJSON_Raw:
2901
- if ((a->valuestring == NULL) || (b->valuestring == NULL))
2902
- {
2903
- return false;
2904
- }
2905
- if (strcmp(a->valuestring, b->valuestring) == 0)
2906
- {
2907
- return true;
2908
- }
2909
-
2910
- return false;
2911
-
2912
- case cJSON_Array:
2913
- {
2914
- cJSON *a_element = a->child;
2915
- cJSON *b_element = b->child;
2916
-
2917
- for (; (a_element != NULL) && (b_element != NULL);)
2918
- {
2919
- if (!cJSON_Compare(a_element, b_element, case_sensitive))
2920
- {
2921
- return false;
2922
- }
2923
-
2924
- a_element = a_element->next;
2925
- b_element = b_element->next;
2926
- }
2927
-
2928
- /* one of the arrays is longer than the other */
2929
- if (a_element != b_element) {
2930
- return false;
2931
- }
2932
-
2933
- return true;
2934
- }
2935
-
2936
- case cJSON_Object:
2937
- {
2938
- cJSON *a_element = NULL;
2939
- cJSON *b_element = NULL;
2940
- cJSON_ArrayForEach(a_element, a)
2941
- {
2942
- /* TODO This has O(n^2) runtime, which is horrible! */
2943
- b_element = get_object_item(b, a_element->string, case_sensitive);
2944
- if (b_element == NULL)
2945
- {
2946
- return false;
2947
- }
2948
-
2949
- if (!cJSON_Compare(a_element, b_element, case_sensitive))
2950
- {
2951
- return false;
2952
- }
2953
- }
2954
-
2955
- /* doing this twice, once on a and b to prevent true comparison if a subset of b
2956
- * TODO: Do this the proper way, this is just a fix for now */
2957
- cJSON_ArrayForEach(b_element, b)
2958
- {
2959
- a_element = get_object_item(a, b_element->string, case_sensitive);
2960
- if (a_element == NULL)
2961
- {
2962
- return false;
2963
- }
2964
-
2965
- if (!cJSON_Compare(b_element, a_element, case_sensitive))
2966
- {
2967
- return false;
2968
- }
2969
- }
2970
-
2971
- return true;
2972
- }
2973
-
2974
- default:
2975
- return false;
2976
- }
2977
- }
2978
-
2979
- CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
2980
- {
2981
- return global_hooks.allocate(size);
2982
- }
2983
-
2984
- CJSON_PUBLIC(void) cJSON_free(void *object)
2985
- {
2986
- global_hooks.deallocate(object);
2987
- }