Skip to content

Commit

Permalink
regcomp.c: Guard against corrupting inversion list SV
Browse files Browse the repository at this point in the history
I don't know of any cases where this happens, but in working on the next
commit I triggered a problem with shrinking an inversion list so much
that the required 0 UV at the beginning was freed.
  • Loading branch information
khwilliamson committed Feb 24, 2016
1 parent ea99f9a commit f0c0c5a
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 5 deletions.
2 changes: 1 addition & 1 deletion embed.fnc
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ EiMRn |bool |invlist_is_iterating|NN SV* const invlist
EiMRn |IV* |get_invlist_previous_index_addr|NN SV* invlist
EiMn |void |invlist_set_previous_index|NN SV* const invlist|const IV index
EiMRn |IV |invlist_previous_index|NN SV* const invlist
EiMn |void |invlist_trim |NN SV* const invlist
EiMn |void |invlist_trim |NN SV* invlist
#endif
EiMR |SV* |invlist_clone |NN SV* const invlist
EiMRn |STRLEN*|get_invlist_iter_addr |NN SV* invlist
Expand Down
2 changes: 1 addition & 1 deletion proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -3667,7 +3667,7 @@ PERL_STATIC_INLINE IV S_invlist_previous_index(SV* const invlist)
PERL_STATIC_INLINE void S_invlist_set_previous_index(SV* const invlist, const IV index);
#define PERL_ARGS_ASSERT_INVLIST_SET_PREVIOUS_INDEX \
assert(invlist)
PERL_STATIC_INLINE void S_invlist_trim(SV* const invlist);
PERL_STATIC_INLINE void S_invlist_trim(SV* invlist);
#define PERL_ARGS_ASSERT_INVLIST_TRIM \
assert(invlist)
# endif
Expand Down
9 changes: 6 additions & 3 deletions regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8382,15 +8382,18 @@ S_invlist_set_previous_index(SV* const invlist, const IV index)
}

PERL_STATIC_INLINE void
S_invlist_trim(SV* const invlist)
S_invlist_trim(SV* invlist)
{
PERL_ARGS_ASSERT_INVLIST_TRIM;

assert(SvTYPE(invlist) == SVt_INVLIST);

/* Change the length of the inversion list to how many entries it currently
* has */
SvPV_shrink_to_cur((SV *) invlist);
* has. But don't shorten it so that it would free up the required
* initial 0 UV (and a trailing NUL byte) */
if (SvCUR(invlist) > TO_INTERNAL_SIZE(1) + 1) {
SvPV_shrink_to_cur(invlist);
}
}

#endif /* ifndef PERL_IN_XSUB_RE */
Expand Down

0 comments on commit f0c0c5a

Please sign in to comment.