Skip to content

Commit

Permalink
adt: zpl_adt_parse_number exit early on false hex value assumption
Browse files Browse the repository at this point in the history
  • Loading branch information
zpl-zak committed Jul 23, 2023
1 parent 6455161 commit b46652f
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
19.3.1 - adt: zpl_adt_parse_number exit early on false hex value assumption
19.3.0 - socket: new socket api cross-platform layer
19.2.0 - file: add macros for standard i/o wrappers (ZPL_STDIO_IN, ...)
19.1.1 - thread: return error values for POSIX calls
Expand Down
6 changes: 6 additions & 0 deletions code/source/adt.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,12 @@ char *zpl_adt_parse_number(zpl_adt_node *node, char* base_str) {
} while (zpl_char_is_digit(*++e));
} else {
if (!zpl_strncmp(e, "0x", 2) || !zpl_strncmp(e, "0X", 2)) { node_props = ZPL_ADT_PROPS_IS_HEX; }

/* bail if ZPL_ADT_PROPS_IS_HEX is unset but we get 'x' on input */
if (zpl_char_to_lower(*e) == 'x' && (node_props != ZPL_ADT_PROPS_IS_HEX)) {
return ++base_str;
}

while (zpl_char_is_hex_digit(*e) || zpl_char_to_lower(*e) == 'x') { buf[ib++] = *e++; }

if (*e == '.') {
Expand Down
34 changes: 17 additions & 17 deletions code/source/parsers/csv.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
zpl_adt_make_branch(root, allocator, NULL, has_header ? false : true);
char *p = text, *b = p, *e = p;
zpl_isize colc = 0, total_colc = 0;

do {
char d = 0;
p = cast(char *)zpl_str_trim(p, false);
Expand All @@ -28,7 +28,7 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
#ifndef ZPL_PARSER_DISABLE_ANALYSIS
row_item.name_style = ZPL_ADT_NAME_STYLE_NO_QUOTES;
#endif

/* handle string literals */
if (*p == '"') {
p = b = e = p+1;
Expand All @@ -51,7 +51,7 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
*e = 0;
p = cast(char *)zpl_str_trim(e+1, true);
d = *p;

/* unescape escaped quotes (so that unescaped text escapes :) */
{
char *ep = b;
Expand Down Expand Up @@ -84,7 +84,7 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
d = 0;
p = e;
}

/* check if number and process if so */
zpl_b32 skip_number = false;
char *num_p = b;
Expand All @@ -94,18 +94,18 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
break;
}
} while (*num_p++);

if (!skip_number) {
zpl_adt_str_to_number(&row_item);
}
}

if (colc >= zpl_array_count(root->nodes)) {
zpl_adt_append_arr(root, NULL);
}

zpl_array_append(root->nodes[colc].nodes, row_item);

if (d == delim) {
colc++;
p++;
Expand All @@ -122,13 +122,13 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
if (d != 0) p++;
}
} while(*p);

if (zpl_array_count(root->nodes) == 0) {
ZPL_CSV_ASSERT("unexpected end of input. stream is empty.");
err = ZPL_CSV_ERROR_UNEXPECTED_END_OF_INPUT;
return err;
}

/* consider first row as a header. */
if (has_header) {
for (zpl_isize i = 0; i < zpl_array_count(root->nodes); i++) {
Expand All @@ -138,7 +138,7 @@ zpl_u8 zpl_csv_parse_delimiter(zpl_csv_object *root, char *text, zpl_allocator a
zpl_array_remove_at(col->nodes, 0);
}
}

return err;
}
void zpl_csv_free(zpl_csv_object *obj) {
Expand All @@ -155,7 +155,7 @@ void zpl__csv_write_record(zpl_file *file, zpl_csv_object *node) {
zpl_adt_print_string(file, node, "\"", "\"");
zpl_fprintf(file, "\"");
} break;

case ZPL_ADT_NAME_STYLE_NO_QUOTES: {
#endif
zpl_fprintf(file, "%s", node->string);
Expand All @@ -164,7 +164,7 @@ void zpl__csv_write_record(zpl_file *file, zpl_csv_object *node) {
}
#endif
} break;

case ZPL_ADT_TYPE_REAL:
case ZPL_ADT_TYPE_INTEGER: {
zpl_adt_print_number(file, node);
Expand All @@ -185,12 +185,12 @@ void zpl_csv_write_delimiter(zpl_file *file, zpl_csv_object *obj, char delimiter
ZPL_ASSERT(obj->nodes);
zpl_isize cols = zpl_array_count(obj->nodes);
if (cols == 0) return;

zpl_isize rows = zpl_array_count(obj->nodes[0].nodes);
if (rows == 0) return;

zpl_b32 has_headers = obj->nodes[0].name != NULL;

if (has_headers) {
for (zpl_isize i = 0; i < cols; i++) {
zpl__csv_write_header(file, &obj->nodes[i]);
Expand All @@ -200,7 +200,7 @@ void zpl_csv_write_delimiter(zpl_file *file, zpl_csv_object *obj, char delimiter
}
zpl_fprintf(file, "\n");
}

for (zpl_isize r = 0; r < rows; r++) {
for (zpl_isize i = 0; i < cols; i++) {
zpl__csv_write_record(file, &obj->nodes[i].nodes[r]);
Expand Down
18 changes: 18 additions & 0 deletions code/tests/cases/csv.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,24 @@ MODULE(csv_parser, {
EQUALS(r.nodes[1].nodes[0].type, ZPL_ADT_TYPE_STRING);
STREQUALS(r.nodes[1].nodes[0].string, "123.45.67.89");
});

IT("parses 'x' field as string", {
zpl_string t = zpl_string_make(mem_alloc, "x\n");
__PARSE(false);

EQUALS(err, 0);
EQUALS(r.nodes[0].nodes[0].type, ZPL_ADT_TYPE_STRING);
STREQUALS(r.nodes[0].nodes[0].string, "x");
});

IT("parses 'n' field as string", {
zpl_string t = zpl_string_make(mem_alloc, "n\n");
__PARSE(false);

EQUALS(err, 0);
EQUALS(r.nodes[0].nodes[0].type, ZPL_ADT_TYPE_STRING);
STREQUALS(r.nodes[0].nodes[0].string, "n");
});
});

#undef __PARSE

0 comments on commit b46652f

Please sign in to comment.