Skip to content

Commit

Permalink
fix: map keys should not be boolean or double
Browse files Browse the repository at this point in the history
  • Loading branch information
a-spiker committed Jan 30, 2025
1 parent 62de2f9 commit cc50e8a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
27 changes: 24 additions & 3 deletions src/main/object_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ LOCAL_HELPER void _destroy_consumer_states(struct consumer_state_s* state);
LOCAL_HELPER int _parse_bin_types(as_vector* bin_specs, uint32_t* n_bins,
const char* const obj_spec_str);
LOCAL_HELPER int _parse_const_val(const char* const obj_spec_str,
const char** stream, struct bin_spec_s* bin_spec, char delim);
const char** stream, struct bin_spec_s* bin_spec, char delim, uint8_t type, uint8_t map_state);
LOCAL_HELPER void bin_spec_free(struct bin_spec_s* bin_spec);
LOCAL_HELPER as_val* _gen_random_bool(as_random* random);
LOCAL_HELPER as_val* _gen_random_int(uint8_t range, as_random* random);
Expand Down Expand Up @@ -1234,7 +1234,7 @@ _parse_bin_types(as_vector* bin_specs, uint32_t* n_bins,
default: {
const char* prev_str = str;
// try parsing as a constant value
if (_parse_const_val(obj_spec_str, &str, bin_spec, state->delimiter) != 0) {
if (_parse_const_val(obj_spec_str, &str, bin_spec, state->delimiter, state->type, state->state) != 0) {
_destroy_consumer_states(state);
return -1;
}
Expand Down Expand Up @@ -1382,19 +1382,27 @@ _parse_bin_types(as_vector* bin_specs, uint32_t* n_bins,

LOCAL_HELPER int
_parse_const_val(const char* const obj_spec_str,
const char** str_ptr, struct bin_spec_s* bin_spec, char delim)
const char** str_ptr, struct bin_spec_s* bin_spec, char delim, uint8_t type, uint8_t map_state)
{
const char* str = *str_ptr;
switch (*str) {
case 'T':
if (!isalpha(str[1])) {
if (type == CONSUMER_TYPE_MAP && map_state == MAP_KEY) { // Reject bool as map key
_print_parse_error("Map key cannot be boolean", obj_spec_str, str);
return -1;
}
bin_spec->type = BIN_SPEC_TYPE_BOOL | BIN_SPEC_TYPE_CONST;
bin_spec->const_bool.val = as_true;
*str_ptr = str + 1;
return 0;
}
case 't':
if (strncasecmp(str, "true", 4) == 0 && !isalpha(str[4])) {
if (type == CONSUMER_TYPE_MAP && map_state == MAP_KEY) { // Reject bool as map key
_print_parse_error("Map key cannot be boolean", obj_spec_str, str);
return -1;
}
bin_spec->type = BIN_SPEC_TYPE_BOOL | BIN_SPEC_TYPE_CONST;
bin_spec->const_bool.val = as_true;
*str_ptr = str + 4;
Expand All @@ -1404,13 +1412,21 @@ _parse_const_val(const char* const obj_spec_str,

case 'F':
if (!isalpha(str[1])) {
if (type == CONSUMER_TYPE_MAP && map_state == MAP_KEY) { // Reject bool as map key
_print_parse_error("Map key cannot be boolean", obj_spec_str, str);
return -1;
}
bin_spec->type = BIN_SPEC_TYPE_BOOL | BIN_SPEC_TYPE_CONST;
bin_spec->const_bool.val = as_false;
*str_ptr = str + 1;
return 0;
}
case 'f':
if (strncasecmp(str, "false", 5) == 0 && !isalpha(str[5])) {
if (type == CONSUMER_TYPE_MAP && map_state == MAP_KEY) { // Reject bool as map key
_print_parse_error("Map key cannot be boolean", obj_spec_str, str);
return -1;
}
bin_spec->type = BIN_SPEC_TYPE_BOOL | BIN_SPEC_TYPE_CONST;
bin_spec->const_bool.val = as_false;
*str_ptr = str + 5;
Expand Down Expand Up @@ -1450,6 +1466,11 @@ _parse_const_val(const char* const obj_spec_str,
return -1;
}

if (type == CONSUMER_TYPE_MAP && map_state == MAP_KEY) { // Reject double as map key
_print_parse_error("Map key cannot be double", obj_spec_str, str);
return -1;
}

bin_spec->type = BIN_SPEC_TYPE_DOUBLE | BIN_SPEC_TYPE_CONST;
as_double_init(&bin_spec->const_double.val, val);

Expand Down
8 changes: 4 additions & 4 deletions src/test/unit/obj_spec_parse_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,10 @@ DEFINE_FAILING_TCASE(test_const_D_f, "f", "a single 'f' is not a valid float");
DEFINE_FAILING_TCASE(test_const_D_0f, "0f", "floats must always contain a '.'");
DEFINE_FAILING_TCASE(test_const_D_1f, "1f", "floats must always contain a '.'");

DEFINE_TCASE(test_const_map_key_bool, "{true:S5}");
DEFINE_FAILING_TCASE(test_const_map_key_bool, "{true:S5}", "maps cannot have boolean keys");
DEFINE_TCASE(test_const_map_key_int, "{10:S5}");
DEFINE_TCASE(test_const_map_key_str, "{\"test_key\":S5}");
DEFINE_TCASE(test_const_map_key_double, "{3.14f:S5}");
DEFINE_FAILING_TCASE(test_const_map_key_double, "{3.14f:S5}", "maps cannot have double keys");
DEFINE_FAILING_TCASE(test_const_map_keys, "{5*10:S5}", "constant map keys "
"cannot have multipliers");
DEFINE_FAILING_TCASE(test_const_map_key_bool_rep, "{true:S5,I:I,true:B10}",
Expand Down Expand Up @@ -784,10 +784,10 @@ obj_spec_suite(void)
tcase_add_ftest(tc_constants, test_const_D_0f);
tcase_add_ftest(tc_constants, test_const_D_1f);

tcase_add_ptest(tc_constants, test_const_map_key_bool);
tcase_add_ftest(tc_constants, test_const_map_key_bool);
tcase_add_ptest(tc_constants, test_const_map_key_int);
tcase_add_ptest(tc_constants, test_const_map_key_str);
tcase_add_ptest(tc_constants, test_const_map_key_double);
tcase_add_ftest(tc_constants, test_const_map_key_double);
tcase_add_ftest(tc_constants, test_const_map_keys);
tcase_add_ftest(tc_constants, test_const_map_key_bool_rep);
tcase_add_ftest(tc_constants, test_const_map_key_int_rep);
Expand Down

0 comments on commit cc50e8a

Please sign in to comment.