mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-21 14:59:34 +00:00
In the functions create_initial_state() and calc_eclosure_iter(), memory is allocated for the elems member of a re_node_set structure but that memory isn't freed on error. Before returning an error, a call to re_node_set_free() should be made to prevent the resource leak. This issue has been fixed in the latest version of gnulib and I've backported this change to maintain consistency. This issue was found by a Coverity scan of GRUB2 under the following CIDs: 473869, 473888. Fixes: CID 473869 Fixes: CID 473888 Signed-off-by: Alec Brown <alec.r.brown@oracle.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
111 lines
3.4 KiB
Diff
111 lines
3.4 KiB
Diff
--- a/lib/regcomp.c
|
|
+++ b/lib/regcomp.c
|
|
@@ -1001,21 +1001,25 @@ create_initial_state (re_dfa_t *dfa)
|
|
Idx dest_idx = dfa->edests[node_idx].elems[0];
|
|
if (!re_node_set_contains (&init_nodes, dest_idx))
|
|
{
|
|
- reg_errcode_t merge_err
|
|
+ err
|
|
= re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
|
|
- if (merge_err != REG_NOERROR)
|
|
- return merge_err;
|
|
+ if (err != REG_NOERROR)
|
|
+ break;
|
|
i = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* It must be the first time to invoke acquire_state. */
|
|
- dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
|
|
- /* We don't check ERR here, since the initial state must not be NULL. */
|
|
+ dfa->init_state
|
|
+ = (err == REG_NOERROR
|
|
+ ? re_acquire_state_context (&err, dfa, &init_nodes, 0)
|
|
+ : NULL);
|
|
if (__glibc_unlikely (dfa->init_state == NULL))
|
|
- return err;
|
|
- if (dfa->init_state->has_constraint)
|
|
+ {
|
|
+ /* Don't check ERR here, as the initial state must not be null. */
|
|
+ }
|
|
+ else if (dfa->init_state->has_constraint)
|
|
{
|
|
dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
|
|
CONTEXT_WORD);
|
|
@@ -1025,17 +1029,13 @@ create_initial_state (re_dfa_t *dfa)
|
|
&init_nodes,
|
|
CONTEXT_NEWLINE
|
|
| CONTEXT_BEGBUF);
|
|
- if (__glibc_unlikely (dfa->init_state_word == NULL
|
|
- || dfa->init_state_nl == NULL
|
|
- || dfa->init_state_begbuf == NULL))
|
|
- return err;
|
|
}
|
|
else
|
|
dfa->init_state_word = dfa->init_state_nl
|
|
= dfa->init_state_begbuf = dfa->init_state;
|
|
|
|
re_node_set_free (&init_nodes);
|
|
- return REG_NOERROR;
|
|
+ return err;
|
|
}
|
|
|
|
/* If it is possible to do searching in single byte encoding instead of UTF-8
|
|
@@ -1677,12 +1677,11 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
|
|
{
|
|
err = duplicate_node_closure (dfa, node, node, node,
|
|
dfa->nodes[node].constraint);
|
|
- if (__glibc_unlikely (err != REG_NOERROR))
|
|
- return err;
|
|
}
|
|
|
|
/* Expand each epsilon destination nodes. */
|
|
- if (IS_EPSILON_NODE(dfa->nodes[node].type))
|
|
+ if (__glibc_likely (err == REG_NOERROR)
|
|
+ && IS_EPSILON_NODE (dfa->nodes[node].type))
|
|
for (i = 0; i < dfa->edests[node].nelem; ++i)
|
|
{
|
|
re_node_set eclosure_elem;
|
|
@@ -1700,14 +1699,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
|
|
{
|
|
err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
|
|
if (__glibc_unlikely (err != REG_NOERROR))
|
|
- return err;
|
|
+ break;
|
|
}
|
|
else
|
|
eclosure_elem = dfa->eclosures[edest];
|
|
/* Merge the epsilon closure of 'edest'. */
|
|
err = re_node_set_merge (&eclosure, &eclosure_elem);
|
|
if (__glibc_unlikely (err != REG_NOERROR))
|
|
- return err;
|
|
+ break;
|
|
/* If the epsilon closure of 'edest' is incomplete,
|
|
the epsilon closure of this node is also incomplete. */
|
|
if (dfa->eclosures[edest].nelem == 0)
|
|
@@ -1717,12 +1716,18 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
|
|
}
|
|
}
|
|
|
|
- if (incomplete && !root)
|
|
- dfa->eclosures[node].nelem = 0;
|
|
+ if (err != REG_NOERROR)
|
|
+ re_node_set_free (&eclosure);
|
|
else
|
|
- dfa->eclosures[node] = eclosure;
|
|
- *new_set = eclosure;
|
|
- return REG_NOERROR;
|
|
+ {
|
|
+ if (incomplete && !root)
|
|
+ dfa->eclosures[node].nelem = 0;
|
|
+ else
|
|
+ dfa->eclosures[node] = eclosure;
|
|
+ *new_set = eclosure;
|
|
+ }
|
|
+
|
|
+ return err;
|
|
}
|
|
|
|
/* Functions for token which are used in the parser. */
|