Article View: gnu.utils.bug
Article #676regex bug?
From: David Boulware
Date: Wed, 19 Aug 1992 19:42
Date: Wed, 19 Aug 1992 19:42
187 lines
6871 bytes
6871 bytes
Line 2393ff of regex.c from the textutils-1.1 distribution follow.
The variable 'enough_memory' is a pointer to a boolean quantity; however after
the first couple of uses, 'enough_memory' is used where '*enough_memory' appears
to be correct. These places are marked by /*HERE*/ notations.
If this observation is in error, please let me know.
static boolean
verify_and_adjust_endlines (op_list, group_forward_match_status,
bufp, enough_memory)
op_list_type op_list;
/* `duplicate' case needs this: which groups matched something;
set when went fowards through the pattern. */
bits_list_type group_forward_match_status;
struct re_pattern_buffer *bufp;
boolean *enough_memory;
{
int this_op_offset; /* Has to be type int because decrementing it. */
/* See comments for analogous variables used for '^' in regex_compile. */
bits_list_type level_match_status;
unsigned current_level = 0;
bits_list_type group_match_status;
bits_list_type group_active_status;
char *bend = bufp->buffer + bufp->used;
char *previous_p = NULL;
if (!(init_bits_list (&level_match_status)
&& init_bits_list (&group_match_status)
&& init_bits_list (&group_active_status)))
{
*enough_memory = false;
return true;
}
else
*enough_memory = true;
for (this_op_offset = op_list.avail - 1; this_op_offset >= 0;
this_op_offset--)
{
char *p = bufp->buffer + op_list.offsets[this_op_offset];
if (!enough_memory) /*HERE*/
break;
switch ((enum regexpcode) *p)
{
case endline:
case endline_in_repeat:
case endline_before_newline:
case repeated_endline_before_newline:
/* If the '$' must be at the pattern's end or else is
in a trailing position. */
if ((bufp->syntax & RE_ANCHORS_ONLY_AT_ENDS)
? p + 1 == bend
: ((bufp->syntax & RE_TIGHT_ALT)
? p + 3 == bend /* Would have two following no_ops. */
: (*p == endline_before_newline
|| *p == repeated_endline_before_newline
|| no_levels_match_anything (level_match_status))))
{
if ((enum regexpcode) *p == endline_in_repeat
|| (enum regexpcode) *p == repeated_endline_before_newline)
if (bufp->syntax & RE_REPEATED_ANCHORS_AWAY)
*p = no_op;
else
*p = endline;
/* If this is a trailing '$' in an empty alternative. */
if ((bufp->syntax & RE_NO_EMPTY_ALTS)
/* If there's an alternation op right before this `$'. */
&& ((this_op_offset > 0
&& *(bufp->buffer
+ op_list.offsets[this_op_offset - 1])
== jump_past_next_alt)
/* Or this `$' is the only thing in the first
alternative of more than one of them. */
|| ((this_op_offset == 0 /* It's first. */
/* Or it's right after an open-group op. */
|| (this_op_offset > 0
&& *(bufp->buffer
+ op_list.offsets[this_op_offset - 1])
== start_memory))
/* And it's right before an alternation op. */
&& previous_p != NULL
&& *previous_p == jump_past_next_alt)))
return false;
}
else if (bufp->syntax & RE_CONTEXT_INVALID_ANCHORS)
return false;
else if (!(bufp->syntax & RE_CONTEXT_INDEP_ANCHORS))
{
p[0] = (char)exactn;
p[1] = (char)1;
p[2] = '$';
}
break;
/* Yes, start and stop_memory are switched because we're going
backwards through the pattern! */
case stop_memory:
increase_level (¤t_level);
if (!make_group_active (&group_active_status, p[1]))
enough_memory = false; /*HERE*/
break;
case start_memory:
if (get_level_match_status (level_match_status, current_level))
if (!set_next_lower_level (&level_match_status, current_level))
enough_memory = false; /*HERE*/
else
{
decrease_level (¤t_level);
make_group_inactive (&group_active_status, p[1]);
}
break;
/* Hit an alternative. */
case jump_past_next_alt:
if (lower_levels_match_nothing (level_match_status, current_level))
clear_this_and_higher_levels (&level_match_status,current_level);
break;
/* These below mean was followed by a repetition operator. */
case no_op:
case maybe_pop_jump:
case no_pop_jump_n:
if (bufp->syntax & RE_REPEATED_ANCHORS_AWAY)
break;
case charset:
case charset_not:
case wordchar:
case notwordchar:
case exactn:
case anychar:
if (!set_this_level (&level_match_status, current_level)
|| !set_match_status_of_active_groups (group_active_status,
&group_match_status))
enough_memory = false;; /*HERE*/
break;
case duplicate:
/* Only set level_match_status if this back reference
refers to a nonempty group. */
if (get_group_match_status (group_forward_match_status, p[1]))
if (!set_this_level (&level_match_status, current_level))
enough_memory = false; /*HERE*/
break;
default:
printf ("Found an unknown operator %u in compiled pattern.\n", *p);
}
previous_p = p;
}
return true;
}
--
David G. Boulware
dgb@phys.washington.edu
Physics Dept, FM-15
University of Washington
Seattle, WA 98195
(206)-543-8591
Technical Details
Message-ID:
<9208192042.AA04531@galileo.phys.washington.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!galileo.phys.washington.edu!dgbShow Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!galileo.phys.washington.edu!dgb From: dgb@galileo.phys.washington.edu (David Boulware) Subject: regex bug? Message-ID: <9208192042.AA04531@galileo.phys.washington.edu> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Wed, 19 Aug 1992 19:42:14 GMT Approved: bug-gnu-utils@prep.ai.mit.edu Lines: 188