Commit: 7b2a7bda201ec0b716f53108d9c2abff434c95bc
Parent: 50dbb69776976cf9b043a9c1187c0e0e5971b850
Author: Randy Palamar
Date: Mon, 17 Feb 2025 11:54:32 -0700
remove duplicate integer conversion code
Diffstat:
6 files changed, 54 insertions(+), 76 deletions(-)
diff --git a/build.sh b/build.sh
@@ -66,7 +66,7 @@ fuzz_llvm)
fuzz_results)
${cc} ${testcflags} -DFUZZ_RESULTS -O0 tests/test-fuzz.c -o tests/test-fuzz-results
set -e
- for file in fuzz_out/default/crashes/id*; do
+ for file in tests/fuzz_out/default/crashes/id*; do
echo ${file}
./tests/test-fuzz-results "${file}"
done
diff --git a/platform_linux_x11.c b/platform_linux_x11.c
@@ -373,7 +373,6 @@ main(i32 argc, char *argv[], char *envp[])
char *argv0 = *argv++;
argc--;
- struct conversion_result cres;
for (i32 i = 0; i < argc; i++) {
char *arg = argv[i];
if (!arg || !arg[0])
@@ -382,15 +381,22 @@ main(i32 argc, char *argv[], char *envp[])
break;
arg++;
switch (arg[0]) {
- case 'g':
+ case 'g': {
if (!argv[i + 1])
usage(argv0, &linux_ctx.error_stream);
- cres = i32_from_cstr(argv[i + 1], 'x');
+ s8 g_arg = c_str_to_s8(argv[i + 1]);
+ struct conversion_result cres = s8_parse_i32_until(g_arg, 'x');
if (cres.status == CR_SUCCESS)
cells.w = cres.i;
- cres = i32_from_cstr(cres.unparsed.c_str, 0);
- if (cres.status == CR_SUCCESS)
- cells.h = cres.i;
+
+ if (cres.unparsed.len > 0 && cres.unparsed.data[0] == 'x') {
+ s8 remainder = {.len = cres.unparsed.len - 1,
+ .data = cres.unparsed.data + 1};
+ cres = s8_parse_i32(remainder);
+ if (cres.status == CR_SUCCESS)
+ cells.h = cres.i;
+ }
+
if (cells.w <= 0 || cells.h <= 0) {
stream_push_s8(&linux_ctx.error_stream, s8("ignoring malformed geometry: "));
stream_push_s8(&linux_ctx.error_stream, c_str_to_s8(argv[i + 1]));
@@ -398,7 +404,7 @@ main(i32 argc, char *argv[], char *envp[])
}
argv++;
argc--;
- break;
+ } break;
case 'v':
stream_push_s8s(&linux_ctx.error_stream, 2,
(s8 []){c_str_to_s8(argv0), s8(" " VERSION "\n")});
diff --git a/terminal.c b/terminal.c
@@ -369,6 +369,8 @@ cursor_step_raw(Term *t, i32 step, i32 rows, i32 cols)
{
rows *= step;
cols *= step;
+ rows = MIN(rows, I32_MAX - t->cursor.pos.y);
+ cols = MIN(cols, I32_MAX - t->cursor.pos.x);
cursor_move_to(t, t->cursor.pos.y + rows, t->cursor.pos.x + cols);
}
@@ -907,27 +909,24 @@ parse_csi(s8 *r, CSI *csi)
get_ascii(r);
}
- i32 accum = 0;
+ struct conversion_result arg = {0};
while (r->len) {
- u32 cp = get_ascii(r);
- if (ISCONTROL(cp)) {
- continue;
- } else if (BETWEEN(cp, '0', '9')) {
- i32 digit = cp - '0';
- if (accum <= (I32_MAX - digit) / 10) {
- accum = 10 * accum + digit;
- } else {
- /* TODO(rnp): report error/out of range? */
- }
- continue;
- }
- csi->argv[csi->argc++] = accum;
- accum = 0;
+ s8_parse_i32_accum(&arg, *r);
+ *r = arg.unparsed;
+ if (r->len) {
+ u32 cp = get_ascii(r);
+
+ if (ISCONTROL(cp))
+ continue;
+
+ csi->argv[csi->argc++] = arg.i;
+ zero_struct(&arg);
- if (cp != ';' || csi->argc == ESC_ARG_SIZ) {
- if (cp == ';') csi->mode = get_ascii(r);
- else csi->mode = cp;
- goto end;
+ if (cp != ';' || csi->argc == ESC_ARG_SIZ) {
+ if (cp == ';') csi->mode = get_ascii(r);
+ else csi->mode = cp;
+ goto end;
+ }
}
}
/* NOTE: if we fell out of the loop then we ran out of characters */
@@ -1034,7 +1033,7 @@ parse_osc(s8 *raw, OSC *osc)
struct conversion_result cmd = s8_parse_i32_until(*raw, ';');
if (cmd.status != CR_FAILURE) {
osc->cmd = cmd.i;
- osc->arg = cmd.unparsed.s8;
+ osc->arg = cmd.unparsed;
osc->raw.len = osc->arg.data - raw->data;
*raw = consume(*raw, osc->raw.len);
} else {
diff --git a/util.c b/util.c
@@ -309,13 +309,13 @@ s8_chop_at(s8 raw, u8 delim)
return result;
}
-static struct conversion_result
-s8_parse_i32(s8 raw)
+static void
+s8_parse_i32_accum(struct conversion_result *result, s8 raw)
{
- struct conversion_result result = {.status = CR_SUCCESS};
- i32 scale = 1;
+ result->status = CR_SUCCESS;
- size i = 0;
+ size i = 0;
+ i32 scale = 1;
if (raw.len && raw.data[0] == '-') {
scale = -1;
i = 1;
@@ -324,11 +324,11 @@ s8_parse_i32(s8 raw)
for (; i < raw.len; i++) {
i32 digit = (i32)raw.data[i] - '0';
if (BETWEEN(digit, 0, 9)) {
- if (result.i > (I32_MAX - digit) / 10) {
- result.status = CR_OUT_OF_RANGE;
- result.i = I32_MAX;
+ if (result->i > (I32_MAX - digit) / 10) {
+ result->status = CR_OUT_OF_RANGE;
+ result->i = I32_MAX;
} else {
- result.i = 10 * result.i + digit;
+ result->i = 10 * result->i + digit;
}
} else {
break;
@@ -336,11 +336,17 @@ s8_parse_i32(s8 raw)
}
if (i == 0 || (i == 1 && raw.data[0] == '-'))
- result.status = CR_FAILURE;
+ result->status = CR_FAILURE;
- result.unparsed.s8 = (s8){.len = raw.len - i, .data = raw.data + i};
- result.i *= scale;
+ result->unparsed = (s8){.len = raw.len - i, .data = raw.data + i};
+ result->i *= scale;
+}
+static struct conversion_result
+s8_parse_i32(s8 raw)
+{
+ struct conversion_result result = {0};
+ s8_parse_i32_accum(&result, raw);
return result;
}
@@ -349,43 +355,10 @@ s8_parse_i32_until(s8 raw, u8 delim)
{
s8 chopped = s8_chop_at(raw, delim);
struct conversion_result result = s8_parse_i32(chopped);
- result.unparsed.s8 = (s8){.data = raw.data + chopped.len, .len = raw.len - chopped.len};
+ result.unparsed = (s8){.data = raw.data + chopped.len, .len = raw.len - chopped.len};
return result;
}
-static struct conversion_result
-i32_from_cstr(char *s, char delim)
-{
- struct conversion_result ret = {.status = CR_FAILURE};
- i32 scale = 1;
-
- if (!s || !s[0])
- return ret;
-
- if (s[0] == '-') {
- s++;
- scale = -1;
- }
-
- for (; *s && *s != delim; s++) {
- i32 digit = s[0] - '0';
- if (!BETWEEN(digit, 0, 9))
- return ret;
-
- if (ret.i > (I32_MAX - digit) / 10) {
- ret.status = CR_OUT_OF_RANGE;
- return ret;
- }
- ret.i = 10 * ret.i + digit;
- }
-
- ret.i *= scale;
- ret.status = CR_SUCCESS;
- ret.unparsed.c_str = (*s == delim) ? s + 1 : s;
-
- return ret;
-}
-
static Stream
arena_stream(Arena a)
{
diff --git a/util.h b/util.h
@@ -279,7 +279,7 @@ typedef __attribute__((aligned(64))) struct {
typedef enum { CR_FAILURE, CR_SUCCESS, CR_OUT_OF_RANGE } conversion_status;
struct conversion_result {
conversion_status status;
- union { char *c_str; s8 s8; } unparsed;
+ s8 unparsed;
union { i32 i; f32 f; Colour colour;};
};
diff --git a/vtgl.c b/vtgl.c
@@ -1080,7 +1080,7 @@ DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize)
.x = cs.x * requested_cells.x + 2 * g_term_margin.x,
.y = cs.y * requested_cells.y + 2 * g_term_margin.y,
};
- if (requested_cells.x < 0 || requested_cells.y)
+ if (requested_cells.x < 0 || requested_cells.y < 0)
requested_size = (iv2){.x = -1, .y = -1};
t->size = (iv2){.x = 1, .y = 1};