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