webpmux: fix heap overflow w/-get/-set

If extra arguments after -get/-set matched one of the recognized
keywords ('icc', 'xmp', etc.), the parser would overwrite the
`config->args[]` allocation, as only one argument was expected.

The additional arguments are now treated as input files. This has the
side effect of allowing input files to be named the same as one of the
keywords.

Bug: webp:427503509
Change-Id: Ic48c94b75349109638e938781024be0a783ff267
This commit is contained in:
James Zern 2025-06-26 11:50:43 -07:00
parent 418340d85b
commit 85e098e58d

View File

@ -680,7 +680,6 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
} else if (!strcmp(argv[i], "-strip")) {
if (ACTION_IS_NIL) {
config->action_type = ACTION_STRIP;
config->arg_count = 0;
} else {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
}
@ -760,10 +759,15 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
ERROR_GOTO2("ERROR: Unknown option: '%s'.\n", argv[i], ErrParse);
}
} else { // One of the feature types or input.
// After consuming the arguments to -get/-set/-strip, treat any remaining
// arguments as input. This allows files that are named the same as the
// keywords used with these options.
int is_input = feature_arg_index == config->arg_count;
if (ACTION_IS_NIL) {
ERROR_GOTO1("ERROR: Action must be specified before other arguments.\n",
ErrParse);
}
if (!is_input) {
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
!strcmp(argv[i], "xmp")) {
if (FEATURETYPE_IS_NIL) {
@ -778,6 +782,11 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
++feature_arg_index;
i += 2;
} else {
// Note: 'arg->params' is not used in this case. 'arg_count' is
// used as a flag to indicate the -get/-strip feature has already
// been consumed, allowing input types to be named the same as the
// feature type.
config->arg_count = 0;
++i;
}
} else if (!strcmp(argv[i], "frame") &&
@ -801,7 +810,12 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
arg->params = argv[i + 1];
++feature_arg_index;
i += 2;
} else { // Assume input file.
} else {
is_input = 1;
}
}
if (is_input) {
if (config->input == NULL) {
config->input = wargv[i];
} else {