diff --git a/CHANGELOG.md b/CHANGELOG.md index 2daae68..4297412 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ All notable changes to this project will be documented in this file. #### Changed - Add auto-type conversion (uint<->sint) to `yyjson_ptr_get_uint/sint()`: #152 +#### Fixed +- Fix incorrect output in environments lacking native `bool` type support: #161 + ## 0.8.0 (2023-09-13) #### Added diff --git a/src/yyjson.h b/src/yyjson.h index de4e327..8f727e9 100644 --- a/src/yyjson.h +++ b/src/yyjson.h @@ -5673,6 +5673,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_bool(yyjson_mut_doc *doc, if (yyjson_likely(doc)) { yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1); if (yyjson_likely(val)) { + _val = !!_val; val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3); return val; } @@ -5925,7 +5926,8 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc) { yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_bool( yyjson_mut_doc *doc, const bool *vals, size_t count) { yyjson_mut_arr_with_func({ - val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)vals[i] << 3); + bool _val = !!vals[i]; + val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3); }); } @@ -6877,6 +6879,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc, const char *_key, bool _val) { yyjson_mut_obj_add_func({ + _val = !!_val; val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)(_val) << 3); }); } diff --git a/test/test_json_writer.c b/test/test_json_writer.c index a34997e..4ac594c 100644 --- a/test/test_json_writer.c +++ b/test/test_json_writer.c @@ -976,6 +976,41 @@ yy_test_case(test_json_writer) { char *json = yyjson_mut_val_write_opts(&root, 0, &alc, NULL, NULL); yy_assert(strcmp(json, expect) == 0); } + + // test bool conversion + // some environments don't have a native bool type + // and the bool type may store values other than 0/1 + { + yyjson_mut_doc *mdoc = yyjson_mut_doc_new(NULL); + yyjson_mut_val *mobj = yyjson_mut_obj(mdoc); + yyjson_mut_doc_set_root(mdoc, mobj); + + for (u8 i = 0; i < 10; i++) { + char str[2]; + snprintf(str, sizeof(str), "%d", (int)i); + yyjson_mut_val *key = yyjson_mut_strcpy(mdoc, str); + yyjson_mut_val *val = yyjson_mut_bool(mdoc, (bool)i); + yyjson_mut_obj_add(mobj, key, val); + } + + char *json = yyjson_mut_write(mdoc, YYJSON_WRITE_PRETTY, NULL); + yy_assert(json != NULL); + + yyjson_doc *doc = yyjson_read(json, strlen(json), 0); + yyjson_val *obj = yyjson_doc_get_root(doc); + yy_assert(yyjson_obj_size(obj) == 10); + for (u8 i = 0; i < 10; i++) { + char str[2]; + snprintf(str, sizeof(str), "%d", (int)i); + yyjson_val *val = yyjson_obj_get(obj, str); + yy_assert(yyjson_is_bool(val)); + yy_assert(yyjson_get_bool(val) == (i != 0)); + } + + yyjson_mut_doc_free(mdoc); + yyjson_doc_free(doc); + free(json); + } } #else