diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-09-25 23:10:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-09-25 23:10:38 -0700 |
commit | 77406d76ba836230a907cb3a2cdb9a5641b1fba8 (patch) | |
tree | 42acfa1b543e886a5bd3b90c3dd2deb9364a82d9 /regex.c | |
parent | a58577fba180a08ebc0fcf43be8a99996359966f (diff) | |
download | txr-77406d76ba836230a907cb3a2cdb9a5641b1fba8.tar.gz txr-77406d76ba836230a907cb3a2cdb9a5641b1fba8.tar.bz2 txr-77406d76ba836230a907cb3a2cdb9a5641b1fba8.zip |
Flurry of regex bugfixes.
* regex.c (match_regex): Bail if pos is too positive,
beyond length of string.
(match_regex_right): Include the pos == end case in the
iteration, so we can match an empty suffix of the string. The
inner loop guard takes care of not feeding any characters from
the string into the regex machine in this case; we just feed
the terminating zero to get the final state.
(match_regst): Normalize a negative pos, otherwise the sub_str
calculation will be junk, since match_regex returns a
normalized position. After normalizing, check that if the
position is still negative, the match must fail.
(match_regst_right_old, match_regst_right): Use zero rather
than t as the range end in sub_str. That way if len is
zero and neg(len) produces zero, an empty string will
be sliced out. For negative values, the zero serves
as one position beyond the last char, just like t.
(do_match_full_offs, regex_match_full, regex_range_full,
regex_range_left): Fail match if normalized starting
pos is negative.
(regex_range_right): Fix completely bogus calculation of the
returne range in the case when the end position defaults to
the string length.
Diffstat (limited to 'regex.c')
-rw-r--r-- | regex.c | 38 |
1 files changed, 27 insertions, 11 deletions
@@ -2476,6 +2476,8 @@ val match_regex(val str, val reg, val pos) pos = plus(pos, length_str(str)); if (lt(pos, zero)) return nil; + } else if (length_str_lt(str, pos)) { + return nil; } regex_machine_init(®m, reg); @@ -2552,7 +2554,7 @@ val match_regex_right(val str, val regex, val end) return nil; } - while (lt(pos, end)) { + while (le(pos, end)) { regex_machine_t regm; val i ; regm_result_t last_res = REGM_INCOMPLETE; @@ -2641,8 +2643,11 @@ val search_regst(val haystack, val needle_regex, val start_num, val from_end) val match_regst(val str, val regex, val pos_in) { - val pos = default_arg(pos_in, zero); - val new_pos = match_regex(str, regex, pos); + val pos = if3(null_or_missing_p(pos_in), + zero, + if3(minusp(pos_in), + plus(pos_in, length_str(str)), pos_in)); + val new_pos = if3(minusp(pos), nil, match_regex(str, regex, pos)); return if2(new_pos, sub_str(str, pos, new_pos)); } @@ -2650,7 +2655,7 @@ static val match_regst_right_old(val str, val regex, val end) { val len = match_regex_right_old(str, regex, end); return if2(len, if3(null_or_missing_p(end), - sub_str(str, neg(len), t), + sub_str(str, neg(len), zero), sub_str(str, minus(end, len), end))); } @@ -2658,7 +2663,7 @@ val match_regst_right(val str, val regex, val end) { val len = match_regex_right(str, regex, end); return if2(len, if3(null_or_missing_p(end), - sub_str(str, neg(len), t), + sub_str(str, neg(len), zero), sub_str(str, minus(end, len), end))); } static val do_match_full(val regex, val str) @@ -2671,8 +2676,10 @@ static val do_match_full_offs(val env, val str) cons_bind (regex, pos_in, env); val len = length_str(str); val pos = if3(minusp(pos_in), plus(pos_in, len), pos_in); - return if2(eql(match_regex(str, regex, pos), len), - sub_str(str, pos, t)); + return if3(minusp(pos), + nil, + if2(eql(match_regex(str, regex, pos), len), + sub_str(str, pos, t))); } val regex_match_full_fun(val regex, val pos) @@ -2727,7 +2734,10 @@ val regex_match_full(val regex, val arg1, val arg2) val str = arg2; val len = length_str(str); val pos = if3(minusp(arg1), plus(len, arg1), arg1); - return if2(eql(match_regex(str, regex, pos), len), sub_str(str, pos, t)); + return if3(minusp(pos), + nil, + if2(eql(match_regex(str, regex, pos), len), + sub_str(str, pos, t))); } } @@ -2755,7 +2765,8 @@ val regex_range_full(val regex, val arg1, val arg2) val str = arg2; val len = length_str(str); val pos = if3(minusp(arg1), plus(len, arg1), arg1); - return if2(eql(match_regex(str, regex, pos), len), rcons(pos, len)); + return if3(minusp(pos), nil, + if2(eql(match_regex(str, regex, pos), len), rcons(pos, len))); } } @@ -2766,7 +2777,7 @@ val regex_range_left(val regex, val arg1, val arg2) return if2(len, rcons(zero, len)); } else { val pos = if3(lt(arg1, zero), plus(arg1, length_str(arg2)), arg1); - val new_pos = match_regex(arg2, regex, pos); + val new_pos = if3(minusp(pos), nil, match_regex(arg2, regex, pos)); return if2(new_pos, rcons(pos, new_pos)); } } @@ -2775,7 +2786,12 @@ val regex_range_right(val regex, val arg1, val arg2) { if (null_or_missing_p(arg2)) { val len = match_regex_right(arg1, regex, arg2); - return if2(len, rcons(zero, len)); + if (len) { + val slen = length_str(arg1); + return rcons(minus(slen, len), slen); + } else { + return nil; + } } else { val end = if3(lt(arg1, zero), plus(arg1, length_str(arg2)), arg1); val len = match_regex_right(arg2, regex, end); |