harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 2ffc3196f199e93c00b1bde9f937d7efb587146e
parent 9048ce748f804c96ea61d27b2139edd8d4548428
Author: Kiƫd Llaentenn <kiedtl@tilde.team>
Date:   Tue, 13 Apr 2021 21:03:25 +0000

Fix stack overflow in is_zeroes()

When a large buffer is declared as a global variable, e.g.:

	def IMAGE_SIZE: size = 242000;
	let memory: [IMAGE_SIZE]i32 = [0...];

...is_zeroes() overflows its stack when the stack is smaller than the
buffer's size. Converting is_zeroes() to an iterative function instead
of a recursive one fixes this issue.

Diffstat:
Msrc/emit.c | 47+++++++++++++++++++++++------------------------
1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/src/emit.c b/src/emit.c @@ -254,36 +254,35 @@ emit_data_string(const char *str, size_t sz, FILE *out) static bool is_zeroes(struct qbe_data_item *data) { - switch (data->type) { - case QD_ZEROED: - break; - case QD_VALUE: - switch (data->value.kind) { - case QV_CONST: - if (data->value.lval != 0) { + for (struct qbe_data_item *cur = data; cur; cur = cur->next) { + switch (cur->type) { + case QD_ZEROED: + break; + case QD_VALUE: + switch (cur->value.kind) { + case QV_CONST: + if (cur->value.lval != 0) { + return false; + } + break; + case QV_GLOBAL: + case QV_LABEL: + case QV_TEMPORARY: return false; } break; - case QV_GLOBAL: - case QV_LABEL: - case QV_TEMPORARY: - return false; - } - break; - case QD_STRING: - for (size_t i = 0; i < data->sz; ++i) { - if (data->str[i] != 0) { - return false; + case QD_STRING: + for (size_t i = 0; i < cur->sz; ++i) { + if (cur->str[i] != 0) { + return false; + } } + break; + case QD_SYMOFFS: + return false; } - break; - case QD_SYMOFFS: - return false; - } - if (!data->next) { - return true; } - return is_zeroes(data->next); + return true; } static void