diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2023-04-07 19:08:39 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2023-04-07 19:14:01 +0300 |
commit | 279e44361a82b6c1b79e7094186ae23da2909858 (patch) | |
tree | 54464fefec0e662211d2652cdce9cd56b67a50a7 | |
parent | c54d42aed3e104c120540498d3f8c7f39203a515 (diff) | |
download | orc-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.c | 197 |
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++){ |