Skip to content

Commit

Permalink
simple-stmt: prevent dangling pointers by limiting nested stmts
Browse files Browse the repository at this point in the history
  • Loading branch information
mptre committed Apr 12, 2024
1 parent fb5716d commit 2c16237
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 9 deletions.
4 changes: 2 additions & 2 deletions parser-stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ parser_stmt_block(struct parser *pr, struct parser_stmt_block_arg *arg)

if ((arg->flags & PARSER_STMT_BLOCK_EXPR_GNU) == 0 &&
is_simple_enabled(pr->pr_si, SIMPLE_STMT)) {
dc = simple_stmt_braces_enter(pr->pr_simple.stmt, lbrace,
dc = simple_stmt_braces_enter(pr->pr_simple.stmt, dc, lbrace,
rbrace, pr->pr_nindent * style(pr->pr_st, IndentWidth));
}

Expand Down Expand Up @@ -841,7 +841,7 @@ parser_simple_stmt_no_braces_enter(struct parser *pr, struct doc *dc,
if (!is_simple_enabled(pr->pr_si, SIMPLE_STMT) ||
!lexer_peek(lx, &lbrace))
return dc;
return simple_stmt_no_braces_enter(pr->pr_simple.stmt, lbrace,
return simple_stmt_no_braces_enter(pr->pr_simple.stmt, dc, lbrace,
(pr->pr_nindent + 1) * style(pr->pr_st, IndentWidth), cookie);
}

Expand Down
21 changes: 16 additions & 5 deletions simple-stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "options.h"
#include "token.h"

#define SIMPLE_STMT_MAX 32

struct stmt {
struct doc *st_root;
struct doc *st_indent;
Expand Down Expand Up @@ -59,7 +61,8 @@ simple_stmt_enter(struct lexer *lx, const struct style *st,
struct simple_stmt *ss;

ss = arena_calloc(eternal_scope, 1, sizeof(*ss));
if (VECTOR_INIT(ss->ss_stmts))
if (VECTOR_INIT(ss->ss_stmts) ||
VECTOR_RESERVE(ss->ss_stmts, SIMPLE_STMT_MAX))
err(1, NULL);
ss->ss_arena.scratch = scratch;
ss->ss_arena.doc_scope = doc_scope;
Expand Down Expand Up @@ -128,8 +131,8 @@ simple_stmt_free(struct simple_stmt *ss)
}

struct doc *
simple_stmt_braces_enter(struct simple_stmt *ss, struct token *lbrace,
struct token *rbrace, unsigned int indent)
simple_stmt_braces_enter(struct simple_stmt *ss, struct doc *dc,
struct token *lbrace, struct token *rbrace, unsigned int indent)
{
struct stmt *st;
unsigned int flags = STMT_BRACES;
Expand All @@ -138,6 +141,8 @@ simple_stmt_braces_enter(struct simple_stmt *ss, struct token *lbrace,
if (!is_brace_moveable(ss, lbrace) || !is_brace_moveable(ss, rbrace))
flags |= STMT_IGNORE;
st = simple_stmt_alloc(ss, indent, flags);
if (st == NULL)
return dc;
token_ref(lbrace);
st->st_lbrace = lbrace;
token_ref(rbrace);
Expand All @@ -146,15 +151,17 @@ simple_stmt_braces_enter(struct simple_stmt *ss, struct token *lbrace,
}

struct doc *
simple_stmt_no_braces_enter(struct simple_stmt *ss, struct token *lbrace,
unsigned int indent, void **cookie)
simple_stmt_no_braces_enter(struct simple_stmt *ss, struct doc *dc,
struct token *lbrace, unsigned int indent, void **cookie)
{
struct stmt *st;
unsigned int flags = 0;

if (!is_brace_moveable(ss, lbrace))
flags |= STMT_IGNORE;
st = simple_stmt_alloc(ss, indent, flags);
if (st == NULL)
return dc;
token_ref(lbrace);
st->st_lbrace = lbrace;
*cookie = st;
Expand All @@ -179,6 +186,10 @@ simple_stmt_alloc(struct simple_stmt *ss, unsigned int indent,
{
struct stmt *st;

/* Prevent reallocations causing dangling pointers. */
if (VECTOR_LENGTH(ss->ss_stmts) >= SIMPLE_STMT_MAX)
return NULL;

st = VECTOR_CALLOC(ss->ss_stmts);
if (st == NULL)
err(1, NULL);
Expand Down
5 changes: 3 additions & 2 deletions simple-stmt.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
struct arena;
struct arena_scope;
struct doc;
struct lexer;
struct options;
struct style;
Expand All @@ -11,8 +12,8 @@ struct simple_stmt *simple_stmt_enter(struct lexer *,
void simple_stmt_leave(struct simple_stmt *);
void simple_stmt_free(struct simple_stmt *);
struct doc *simple_stmt_braces_enter(struct simple_stmt *,
struct token *, struct token *, unsigned int);
struct doc *, struct token *, struct token *, unsigned int);
struct doc *simple_stmt_no_braces_enter(struct simple_stmt *,
struct token *, unsigned int, void **);
struct doc *, struct token *, unsigned int, void **);
void simple_stmt_no_braces_leave(struct simple_stmt *,
struct token *, void *);
1 change: 1 addition & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ TESTS+= error-072.c
TESTS+= error-073.c
TESTS+= error-074.c
TESTS+= error-075.c
TESTS+= error-076.c
TESTS+= error-style-IncludeGuards-001.h
TESTS+= error-style-IncludeGuards-002.h

Expand Down
6 changes: 6 additions & 0 deletions tests/error-076.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* AFL
*/

t
n(){if(())f/**/x=&{{{{{{{{{{{{{{{{{}}}}}}}}}}¿}}}}}}}}0;

0 comments on commit 2c16237

Please sign in to comment.