mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 15:27:59 +00:00
lib: fix static analysis issues, use regfree()
* Fix potential NULL dereference * Fix use of uninitialized value * Fix leaking memory by not freeing regex_t * Fix extra \n when using empty regex filter * Clean up still-reachable hook memory * Handle nonexistent pager Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
62bece4449
commit
5d806ec6e0
@ -1198,16 +1198,22 @@ static int handle_pipe_action(struct vty *vty, const char *cmd_in,
|
|||||||
if (strmatch(token, "include")) {
|
if (strmatch(token, "include")) {
|
||||||
/* the remaining text should be a regexp */
|
/* the remaining text should be a regexp */
|
||||||
char *regexp = working;
|
char *regexp = working;
|
||||||
|
|
||||||
|
if (!regexp) {
|
||||||
|
vty_out(vty, "%% Need a regexp to filter with\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
bool succ = vty_set_include(vty, regexp);
|
bool succ = vty_set_include(vty, regexp);
|
||||||
|
|
||||||
if (!succ) {
|
if (!succ) {
|
||||||
vty_out(vty, "%% Bad regexp '%s'", regexp);
|
vty_out(vty, "%% Bad regexp '%s'\n", regexp);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*cmd_out = XSTRDUP(MTYPE_TMP, cmd_in);
|
*cmd_out = XSTRDUP(MTYPE_TMP, cmd_in);
|
||||||
*(strstr(*cmd_out, "|")) = '\0';
|
*(strstr(*cmd_out, "|")) = '\0';
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, "%% Unknown action '%s'", token);
|
vty_out(vty, "%% Unknown action '%s'\n", token);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2892,6 +2898,9 @@ void cmd_terminate()
|
|||||||
{
|
{
|
||||||
struct cmd_node *cmd_node;
|
struct cmd_node *cmd_node;
|
||||||
|
|
||||||
|
hook_unregister(cmd_execute, handle_pipe_action);
|
||||||
|
hook_unregister(cmd_execute_done, handle_pipe_action_done);
|
||||||
|
|
||||||
if (cmdvec) {
|
if (cmdvec) {
|
||||||
for (unsigned int i = 0; i < vector_active(cmdvec); i++)
|
for (unsigned int i = 0; i < vector_active(cmdvec); i++)
|
||||||
if ((cmd_node = vector_slot(cmdvec, i)) != NULL) {
|
if ((cmd_node = vector_slot(cmdvec, i)) != NULL) {
|
||||||
|
@ -58,6 +58,9 @@ vector frrstr_split_vec(const char *string, const char *delimiter)
|
|||||||
char **result;
|
char **result;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
frrstr_split(string, delimiter, &result, &argc);
|
frrstr_split(string, delimiter, &result, &argc);
|
||||||
|
|
||||||
vector v = array_to_vector((void **)result, argc);
|
vector v = array_to_vector((void **)result, argc);
|
||||||
@ -89,7 +92,7 @@ char *frrstr_join(const char **parts, int argc, const char *join)
|
|||||||
|
|
||||||
memcpy(p, parts[i], arglen);
|
memcpy(p, parts[i], arglen);
|
||||||
p += arglen;
|
p += arglen;
|
||||||
if (i + 1 != argc) {
|
if (i + 1 != argc && join) {
|
||||||
memcpy(p, join, joinlen);
|
memcpy(p, join, joinlen);
|
||||||
p += joinlen;
|
p += joinlen;
|
||||||
}
|
}
|
||||||
|
24
lib/vty.c
24
lib/vty.c
@ -119,8 +119,8 @@ bool vty_set_include(struct vty *vty, const char *regexp)
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
|
|
||||||
if (!regexp) {
|
if (!regexp && vty->filter) {
|
||||||
memset(&vty->include, 0x00, sizeof(vty->include));
|
regfree(&vty->include);
|
||||||
vty->filter = false;
|
vty->filter = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -188,8 +188,26 @@ int vty_out(struct vty *vty, const char *format, ...)
|
|||||||
vector lines = frrstr_split_vec(buf, "\n");
|
vector lines = frrstr_split_vec(buf, "\n");
|
||||||
|
|
||||||
frrstr_filter_vec(lines, &vty->include);
|
frrstr_filter_vec(lines, &vty->include);
|
||||||
if (buf[strlen(buf) - 1] == '\n' && vector_active(lines) > 0)
|
|
||||||
|
/*
|
||||||
|
* Consider the string "foo\n". If the regex is an empty string
|
||||||
|
* and the line ended with a newline, then the vector will look
|
||||||
|
* like:
|
||||||
|
*
|
||||||
|
* [0]: 'foo'
|
||||||
|
* [1]: ''
|
||||||
|
*
|
||||||
|
* If the regex isn't empty, the vector will look like:
|
||||||
|
*
|
||||||
|
* [0]: 'foo'
|
||||||
|
*
|
||||||
|
* In this case we'd like to preserve the newline, so we add
|
||||||
|
* the empty string [1] as in the first example.
|
||||||
|
*/
|
||||||
|
if (buf[strlen(buf) - 1] == '\n' && vector_active(lines) > 0
|
||||||
|
&& strlen(vector_slot(lines, vector_active(lines) - 1)))
|
||||||
vector_set(lines, XSTRDUP(MTYPE_TMP, ""));
|
vector_set(lines, XSTRDUP(MTYPE_TMP, ""));
|
||||||
|
|
||||||
filtered = frrstr_join_vec(lines, "\n");
|
filtered = frrstr_join_vec(lines, "\n");
|
||||||
frrstr_strvec_free(lines);
|
frrstr_strvec_free(lines);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,6 +70,9 @@ static FILE *vty_open_pager(struct vty *vty)
|
|||||||
if (vty->is_paged)
|
if (vty->is_paged)
|
||||||
return vty->of;
|
return vty->of;
|
||||||
|
|
||||||
|
if (!vtysh_pager_name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
vty->of_saved = vty->of;
|
vty->of_saved = vty->of;
|
||||||
vty->of = popen(vtysh_pager_name, "w");
|
vty->of = popen(vtysh_pager_name, "w");
|
||||||
if (vty->of == NULL) {
|
if (vty->of == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user