aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2024-12-03 04:22:34 +0000
committerAryadev Chavali <aryadev@aryadevchavali.com>2024-12-03 04:22:42 +0000
commit16da0e0f2cb981f4bb5b11027cead062ab593b93 (patch)
treef41552bc56450e522171607ab5df5e98350ee2ee
parent6ad3e61a2b5c0629012d6db2c3bb56e55a3a567b (diff)
downloadobf-16da0e0f2cb981f4bb5b11027cead062ab593b93.tar.gz
obf-16da0e0f2cb981f4bb5b11027cead062ab593b93.tar.bz2
obf-16da0e0f2cb981f4bb5b11027cead062ab593b93.zip
Add better error correcting code for bad loops in parser
-rw-r--r--parser.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/parser.c b/parser.c
index c7765ad..ee9b46b 100644
--- a/parser.c
+++ b/parser.c
@@ -55,7 +55,7 @@ char *ast_to_str(node_t *ast, size_t size)
struct PResult parse_buffer(buffer_t *buffer)
{
node_t *nodes = NULL;
- size_t usable = 0, loops = 0;
+ size_t usable = 0, loops = 0, loop_ends = 0;
// First pass: Compute |nodes|
for (size_t i = 0; i < buffer->size; ++i)
@@ -64,7 +64,44 @@ struct PResult parse_buffer(buffer_t *buffer)
++usable;
if (buffer->data[i] == '[')
++loops;
+ else if (buffer->data[i] == ']')
+ ++loop_ends;
}
+ if (loops != loop_ends)
+ {
+ // Look for the point of failure
+ i64 stack = 0;
+ for (size_t i = 0, col = 0, row = 0; i < buffer->size; ++i)
+ {
+ if (buffer->data[i] == '\n')
+ {
+ col = 0;
+ ++row;
+ continue;
+ }
+ else if (buffer->data[i] != ']' && buffer->data[i] != '[')
+ {
+ ++col;
+ continue;
+ }
+ else if (buffer->data[i] == ']')
+ {
+ --stack;
+ }
+ else if (buffer->data[i] == '[')
+ {
+ ++stack;
+ }
+ ++col;
+
+ if (stack < 0)
+ {
+ print_error(buffer->name, row, col,
+ "ERROR: Unbalanced square brackets!");
+ goto error;
+ }
+ }
+ }
nodes = calloc(usable, sizeof(*nodes));
if (!nodes)
{
@@ -133,12 +170,6 @@ struct PResult parse_buffer(buffer_t *buffer)
stack[stackptr++] = node;
else if (node->type == LOUT)
{
- if (stackptr == 0)
- {
- print_error(buffer->name, node->row, node->col,
- "ERROR: Unbalanced square brackets!");
- goto error;
- }
// Access last IN loop
--stackptr;
node->loop_ref = stack[stackptr] - nodes;