Clean up output command

Plugs memory leaks during failure of the output command and in other
circumstances and fixes `bg` option.

Fixes #1381
This commit is contained in:
Calvin Lee 2017-10-05 20:43:47 -06:00
parent 839064d278
commit 419a1087ac
2 changed files with 51 additions and 25 deletions

View file

@ -46,7 +46,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
output->enabled = 0; output->enabled = 0;
} else if (strcasecmp(command, "resolution") == 0 || strcasecmp(command, "res") == 0) { } else if (strcasecmp(command, "resolution") == 0 || strcasecmp(command, "res") == 0) {
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing resolution argument."); error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument.");
goto fail;
} }
char *res = argv[i]; char *res = argv[i];
char *x = strchr(res, 'x'); char *x = strchr(res, 'x');
@ -61,7 +62,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
// Format is 1234 4321 // Format is 1234 4321
width = atoi(res); width = atoi(res);
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing resolution argument (height)."); error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument (height).");
goto fail;
} }
res = argv[i]; res = argv[i];
height = atoi(res); height = atoi(res);
@ -70,7 +72,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
output->height = height; output->height = height;
} else if (strcasecmp(command, "position") == 0 || strcasecmp(command, "pos") == 0) { } else if (strcasecmp(command, "position") == 0 || strcasecmp(command, "pos") == 0) {
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing position argument."); error = cmd_results_new(CMD_INVALID, "output", "Missing position argument.");
goto fail;
} }
char *res = argv[i]; char *res = argv[i];
char *c = strchr(res, ','); char *c = strchr(res, ',');
@ -85,7 +88,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
// Format is 1234 4321 // Format is 1234 4321
x = atoi(res); x = atoi(res);
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing position argument (y)."); error = cmd_results_new(CMD_INVALID, "output", "Missing position argument (y).");
goto fail;
} }
res = argv[i]; res = argv[i];
y = atoi(res); y = atoi(res);
@ -94,25 +98,49 @@ struct cmd_results *cmd_output(int argc, char **argv) {
output->y = y; output->y = y;
} else if (strcasecmp(command, "scale") == 0) { } else if (strcasecmp(command, "scale") == 0) {
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing scale parameter."); error = cmd_results_new(CMD_INVALID, "output", "Missing scale parameter.");
goto fail;
} }
output->scale = atoi(argv[i]); output->scale = atoi(argv[i]);
} else if (strcasecmp(command, "background") == 0 || strcasecmp(command, "bg") == 0) { } else if (strcasecmp(command, "background") == 0 || strcasecmp(command, "bg") == 0) {
wordexp_t p; wordexp_t p;
if (++i >= argc) { if (++i >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing background file or color specification."); error = cmd_results_new(CMD_INVALID, "output", "Missing background file or color specification.");
goto fail;
} }
if (i + 1 >= argc) { if (i + 1 >= argc) {
return cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode or `solid_color`."); error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode or `solid_color`.");
goto fail;
} }
if (strcasecmp(argv[argc - 1], "solid_color") == 0) { if (strcasecmp(argv[i + 1], "solid_color") == 0) {
output->background = strdup(argv[argc - 2]); output->background = strdup(argv[argc - 2]);
output->background_option = strdup("solid_color"); output->background_option = strdup("solid_color");
} else { } else {
char *src = join_args(argv + i, argc - i - 1); // argv[i+j]=bg_option
char *mode = argv[argc - 1]; bool valid = false;
char *mode;
size_t j;
for (j = 0; j < (size_t) (argc - i); ++j) {
mode = argv[i + j];
for (size_t k = 0; k < sizeof(bg_options) / sizeof(char *); ++k) {
if (strcasecmp(mode, bg_options[k]) == 0) {
valid = true;
break;
}
}
if (valid) {
break;
}
}
if (!valid) {
error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode.");
goto fail;
}
char *src = join_args(argv + i, j);
if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) { if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
return cmd_results_new(CMD_INVALID, "output", "Invalid syntax (%s)", src); error = cmd_results_new(CMD_INVALID, "output", "Invalid syntax (%s)", src);
goto fail;
} }
free(src); free(src);
src = p.we_wordv[0]; src = p.we_wordv[0];
@ -132,27 +160,19 @@ struct cmd_results *cmd_output(int argc, char **argv) {
} }
} }
if (!src || access(src, F_OK) == -1) { if (!src || access(src, F_OK) == -1) {
return cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src); error = cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src);
} wordfree(&p);
for (char *m = mode; *m; ++m) *m = tolower(*m); goto fail;
// Check mode
bool valid = false;
size_t j;
for (j = 0; j < sizeof(bg_options) / sizeof(char *); ++j) {
if (strcasecmp(mode, bg_options[j]) == 0) {
valid = true;
break;
}
}
if (!valid) {
return cmd_results_new(CMD_INVALID, "output", "Invalid background scaling mode.");
} }
output->background = strdup(src); output->background = strdup(src);
output->background_option = strdup(mode); output->background_option = strdup(mode);
if (src != p.we_wordv[0]) { if (src != p.we_wordv[0]) {
free(src); free(src);
} }
wordfree(&p); wordfree(&p);
i += j;
} }
} }
} }
@ -192,4 +212,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
fail:
free_output_config(output);
return error;
} }

View file

@ -128,6 +128,8 @@ void free_output_config(struct output_config *oc) {
return; return;
} }
free(oc->name); free(oc->name);
free(oc->background);
free(oc->background_option);
free(oc); free(oc);
} }