diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index 4658eba77..2f27e08c5 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -93,6 +93,11 @@ namespace misc_utils return lut[(uint8_t)c] & 1; } + inline bool isalpha(char c) + { + return lut[(uint8_t)c] & 4; + } + std::string transform_to_escape_sequence(const std::string& src); /* diff --git a/contrib/epee/include/storages/portable_storage_from_json.h b/contrib/epee/include/storages/portable_storage_from_json.h index 60acfccb8..8acb5b432 100644 --- a/contrib/epee/include/storages/portable_storage_from_json.h +++ b/contrib/epee/include/storages/portable_storage_from_json.h @@ -146,7 +146,7 @@ namespace epee stg.set_value(name, double(nval), current_section); } state = match_state_wonder_after_value; - }else if(isalpha(*it) ) + }else if(epee::misc_utils::parse::isalpha(*it) ) {// could be null, true or false boost::string_ref word; misc_utils::parse::match_word2(it, buf_end, word); @@ -245,7 +245,7 @@ namespace epee { array_md = array_mode_undifined; state = match_state_wonder_after_value; - }else if(isalpha(*it) ) + }else if(epee::misc_utils::parse::isalpha(*it) ) {// array of booleans boost::string_ref word; misc_utils::parse::match_word2(it, buf_end, word); @@ -333,7 +333,7 @@ namespace epee }else CHECK_ISSPACE(); break; case array_mode_booleans: - if(isalpha(*it) ) + if(epee::misc_utils::parse::isalpha(*it) ) {// array of booleans boost::string_ref word; misc_utils::parse::match_word2(it, buf_end, word); diff --git a/tests/unit_tests/epee_serialization.cpp b/tests/unit_tests/epee_serialization.cpp index 2cafc0e80..ec3999617 100644 --- a/tests/unit_tests/epee_serialization.cpp +++ b/tests/unit_tests/epee_serialization.cpp @@ -98,6 +98,35 @@ struct ObjWithOptChild KV_SERIALIZE_OPT(test_value, true); END_KV_SERIALIZE_MAP() }; + +struct ObjWithBool +{ + bool b; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(b) + END_KV_SERIALIZE_MAP() +}; +} + +TEST(epee_json, keyword_values) +{ + // true/false/null parse as keyword values + ObjWithBool o{}; + + o.b = false; + EXPECT_TRUE(epee::serialization::load_t_from_json(o, std::string("{\"b\": true}"))); + EXPECT_TRUE(o.b); + + o.b = true; + EXPECT_TRUE(epee::serialization::load_t_from_json(o, std::string("{\"b\": false}"))); + EXPECT_FALSE(o.b); + + EXPECT_TRUE(epee::serialization::load_t_from_json(o, std::string("{\"b\": null}"))); + + // A value beginning with a non-ASCII byte (most significant bit == 1) is not + // a keyword and must be rejected. + EXPECT_FALSE(epee::serialization::load_t_from_json(o, std::string("{\"b\": \xc3\x28}"))); } TEST(epee_binary, serialize_deserialize)