summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2023-04-07 19:08:39 +0300
committerSebastian Dröge <sebastian@centricular.com>2023-04-07 19:14:01 +0300
commit279e44361a82b6c1b79e7094186ae23da2909858 (patch)
tree54464fefec0e662211d2652cdce9cd56b67a50a7
parentc54d42aed3e104c120540498d3f8c7f39203a515 (diff)
downloadorc-279e44361a82b6c1b79e7094186ae23da2909858.tar.gz
orcparse: Check for correct number of function header directive arguments
This was otherwise accessing random pointers. Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/94>
-rw-r--r--orc/orcparse.c197
1 files changed, 132 insertions, 65 deletions
diff --git a/orc/orcparse.c b/orc/orcparse.c
index f46b0be..84615dc 100644
--- a/orc/orcparse.c
+++ b/orc/orcparse.c
@@ -126,19 +126,24 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
if (token[0][0] == '.') {
if (strcmp (token[0], ".function") == 0) {
- if (parser->program) {
- orc_parse_sanity_check (parser, parser->program);
- }
- parser->program = orc_program_new ();
- orc_program_set_name (parser->program, token[1]);
- if (parser->n_programs == parser->n_programs_alloc) {
- parser->n_programs_alloc += 32;
- parser->programs = realloc (parser->programs,
- sizeof(OrcProgram *)*parser->n_programs_alloc);
+ if (n_tokens < 2) {
+ orc_parse_log (parser, "error: line %d: .function without function name\n",
+ parser->line_number);
+ } else {
+ if (parser->program) {
+ orc_parse_sanity_check (parser, parser->program);
+ }
+ parser->program = orc_program_new ();
+ orc_program_set_name (parser->program, token[1]);
+ if (parser->n_programs == parser->n_programs_alloc) {
+ parser->n_programs_alloc += 32;
+ parser->programs = realloc (parser->programs,
+ sizeof(OrcProgram *)*parser->n_programs_alloc);
+ }
+ parser->programs[parser->n_programs] = parser->program;
+ parser->n_programs++;
+ parser->creg_index = 1;
}
- parser->programs[parser->n_programs] = parser->program;
- parser->n_programs++;
- parser->creg_index = 1;
} else if (strcmp (token[0], ".backup") == 0) {
if (n_tokens < 2) {
orc_parse_log (parser, "error: line %d: .backup without function name\n",
@@ -202,78 +207,128 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
}
}
} else if (strcmp (token[0], ".m") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_set_constant_m (parser->program, size);
+ if (n_tokens < 2) {
+ orc_parse_log (parser, "error: line %d: .m without value\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_set_constant_m (parser->program, size);
+ }
} else if (strcmp (token[0], ".source") == 0) {
- int size = strtol (token[1], NULL, 0);
- int var;
- int i;
- var = orc_program_add_source (parser->program, size, token[2]);
- for(i=3;i<n_tokens;i++){
- if (strcmp (token[i], "align") == 0) {
- if (i == n_tokens - 1) {
- orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
- parser->line_number);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .source without size or identifier\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ int var;
+ int i;
+ var = orc_program_add_source (parser->program, size, token[2]);
+ for(i=3;i<n_tokens;i++){
+ if (strcmp (token[i], "align") == 0) {
+ if (i == n_tokens - 1) {
+ orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
+ parser->line_number);
+ } else {
+ int alignment = strtol (token[i+1], NULL, 0);
+ orc_program_set_var_alignment (parser->program, var, alignment);
+ i++;
+ }
+ } else if (i == n_tokens - 1) {
+ orc_program_set_type_name (parser->program, var, token[i]);
} else {
- int alignment = strtol (token[i+1], NULL, 0);
- orc_program_set_var_alignment (parser->program, var, alignment);
- i++;
+ orc_parse_log (parser, "error: line %d: unknown .dest token '%s'\n",
+ parser->line_number, token[i]);
}
- } else if (i == n_tokens - 1) {
- orc_program_set_type_name (parser->program, var, token[i]);
- } else {
- orc_parse_log (parser, "error: line %d: unknown .dest token '%s'\n",
- parser->line_number, token[i]);
}
}
} else if (strcmp (token[0], ".dest") == 0) {
- int size = strtol (token[1], NULL, 0);
- int var;
- int i;
- var = orc_program_add_destination (parser->program, size, token[2]);
- for(i=3;i<n_tokens;i++){
- if (strcmp (token[i], "align") == 0) {
- if (i == n_tokens - 1) {
- orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
- parser->line_number);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .dest without size or identifier\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ int var;
+ int i;
+ var = orc_program_add_destination (parser->program, size, token[2]);
+ for(i=3;i<n_tokens;i++){
+ if (strcmp (token[i], "align") == 0) {
+ if (i == n_tokens - 1) {
+ orc_parse_log (parser, "error: line %d: .source align requires alignment value\n",
+ parser->line_number);
+ } else {
+ int alignment = strtol (token[i+1], NULL, 0);
+ orc_program_set_var_alignment (parser->program, var, alignment);
+ i++;
+ }
+ } else if (i == n_tokens - 1) {
+ orc_program_set_type_name (parser->program, var, token[i]);
} else {
- int alignment = strtol (token[i+1], NULL, 0);
- orc_program_set_var_alignment (parser->program, var, alignment);
- i++;
+ orc_parse_log (parser, "error: line %d: unknown .source token '%s'\n",
+ parser->line_number, token[i]);
}
- } else if (i == n_tokens - 1) {
- orc_program_set_type_name (parser->program, var, token[i]);
- } else {
- orc_parse_log (parser, "error: line %d: unknown .source token '%s'\n",
- parser->line_number, token[i]);
}
}
} else if (strcmp (token[0], ".accumulator") == 0) {
- int size = strtol (token[1], NULL, 0);
- int var;
- var = orc_program_add_accumulator (parser->program, size, token[2]);
- if (n_tokens > 3) {
- orc_program_set_type_name (parser->program, var, token[3]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .accumulator without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ int var;
+ var = orc_program_add_accumulator (parser->program, size, token[2]);
+ if (n_tokens > 3) {
+ orc_program_set_type_name (parser->program, var, token[3]);
+ }
}
} else if (strcmp (token[0], ".temp") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_add_temporary (parser->program, size, token[2]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .temp without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_add_temporary (parser->program, size, token[2]);
+ }
} else if (strcmp (token[0], ".param") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_add_parameter (parser->program, size, token[2]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .param without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_add_parameter (parser->program, size, token[2]);
+ }
} else if (strcmp (token[0], ".longparam") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_add_parameter_int64 (parser->program, size, token[2]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .longparam without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_add_parameter_int64 (parser->program, size, token[2]);
+ }
} else if (strcmp (token[0], ".const") == 0) {
- int size = strtol (token[1], NULL, 0);
+ if (n_tokens < 4) {
+ orc_parse_log (parser, "error: line %d: .const without size, name or value\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
- orc_program_add_constant_str (parser->program, size, token[3], token[2]);
+ orc_program_add_constant_str (parser->program, size, token[3], token[2]);
+ }
} else if (strcmp (token[0], ".floatparam") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_add_parameter_float (parser->program, size, token[2]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .floatparam without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_add_parameter_float (parser->program, size, token[2]);
+ }
} else if (strcmp (token[0], ".doubleparam") == 0) {
- int size = strtol (token[1], NULL, 0);
- orc_program_add_parameter_double (parser->program, size, token[2]);
+ if (n_tokens < 3) {
+ orc_parse_log (parser, "error: line %d: .doubleparam without size or name\n",
+ parser->line_number);
+ } else {
+ int size = strtol (token[1], NULL, 0);
+ orc_program_add_parameter_double (parser->program, size, token[2]);
+ }
} else {
orc_parse_log (parser, "error: line %d: unknown directive: %s\n",
parser->line_number, token[0]);
@@ -286,9 +341,20 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
if (strcmp (token[0], "x4") == 0) {
flags |= ORC_INSTRUCTION_FLAG_X4;
offset = 1;
+
+ if (n_tokens < 1 + offset) {
+ orc_parse_log (parser, "error: line %d: no opcode argument for x4 flag\n",
+ parser->line_number);
+ continue;
+ }
} else if (strcmp (token[0], "x2") == 0) {
flags |= ORC_INSTRUCTION_FLAG_X2;
offset = 1;
+ if (n_tokens < 1 + offset) {
+ orc_parse_log (parser, "error: line %d: no opcode argument for x2 flag\n",
+ parser->line_number);
+ continue;
+ }
}
o = get_opcode (parser, token[offset]);
@@ -302,6 +368,7 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
orc_parse_log (parser, "error: line %d: too %s arguments for %s (expected %d)\n",
parser->line_number, (n_tokens < 1+offset+n_args) ? "few" : "many",
token[offset], n_args);
+ continue;
}
for(i=offset+1,j=0;i<n_tokens;i++,j++){