summaryrefslogtreecommitdiff
path: root/regex.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-19 04:36:34 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-19 04:36:34 +0000
commit9be426a0ec6ec98b61a7d99f2d77d5fdf79a3837 (patch)
tree0c70d582217d4ecf4ec7c05f5ad56d78eed47257 /regex.c
parente7392b3f844b7fe2517d8c671102dcc886a96edb (diff)
* eval.c (rb_f_require): searches ".rb" and ".so" at the same
time. previous behavior (search ".rb", then ".so") has a security risk (ruby-bugs#PR140). * regex.c (re_compile_pattern): avoid pushing unnecessary option_set. * eval.c (rb_load): tainted string is OK if wrapped *and* $SAFE >= 4. * eval.c (rb_thread_start_0): should not nail down higher blocks before preserving original context (i.e. should not alter original context). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@1527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/regex.c b/regex.c
index 9033e0ac81..bc63fac651 100644
--- a/regex.c
+++ b/regex.c
@@ -1260,7 +1260,6 @@ re_compile_pattern(pattern, size, bufp)
int had_char_class = 0;
int options = bufp->options;
- int old_options = 0;
bufp->fastmap_accurate = 0;
bufp->must = 0;
@@ -1683,11 +1682,15 @@ re_compile_pattern(pattern, size, bufp)
break;
case '(':
- old_options = options;
+ {
+ int old_options = options;
+ int push_option = 0;
+ int casefold = 0;
+
PATFETCH(c);
if (c == '?') {
int negative = 0;
- int push_option = 0;
+
PATFETCH_RAW(c);
switch (c) {
case 'x': case 'p': case 'm': case 'i': case '-':
@@ -1736,13 +1739,12 @@ re_compile_pattern(pattern, size, bufp)
if (negative) {
if (options&RE_OPTION_IGNORECASE) {
options &= ~RE_OPTION_IGNORECASE;
- BUFPUSH(casefold_off);
}
}
else if (!(options&RE_OPTION_IGNORECASE)) {
options |= RE_OPTION_IGNORECASE;
- BUFPUSH(casefold_on);
}
+ casefold = 1;
break;
default:
@@ -1774,16 +1776,24 @@ re_compile_pattern(pattern, size, bufp)
default:
FREE_AND_RETURN(stackb, "undefined (?...) sequence");
}
+ }
+ else {
+ PATUNFETCH;
+ c = '(';
+ }
+ if (c == '#') {
if (push_option) {
BUFPUSH(option_set);
BUFPUSH(options);
}
+ if (casefold) {
+ if (options & RE_OPTION_IGNORECASE)
+ BUFPUSH(casefold_on);
+ else
+ BUFPUSH(casefold_off);
}
- else {
- PATUNFETCH;
- c = '(';
+ break;
}
- if (c == '#') break;
if (stackp+8 >= stacke) {
DOUBLE_STACK(int);
}
@@ -1826,24 +1836,28 @@ re_compile_pattern(pattern, size, bufp)
default:
break;
}
+ if (push_option) {
+ BUFPUSH(option_set);
+ BUFPUSH(options);
+ }
+ if (casefold) {
+ if (options & RE_OPTION_IGNORECASE)
+ BUFPUSH(casefold_on);
+ else
+ BUFPUSH(casefold_off);
+ }
*stackp++ = c;
*stackp++ = old_options;
fixup_alt_jump = 0;
laststart = 0;
begalt = b;
+ }
break;
case ')':
if (stackp == stackb)
FREE_AND_RETURN(stackb, "unmatched )");
- if (options != stackp[-1]) {
- if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
- BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
- }
- BUFPUSH(option_set);
- BUFPUSH(stackp[-1]);
- }
pending_exact = 0;
if (fixup_alt_jump) {
/* Push a dummy failure point at the end of the
@@ -1856,6 +1870,15 @@ re_compile_pattern(pattern, size, bufp)
to `fixup_alt_jump', in the `handle_alt' case below. */
store_jump(fixup_alt_jump, jump, b);
}
+ if (options != stackp[-1]) {
+ if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
+ BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
+ }
+ if ((options ^ stackp[-1]) != RE_OPTION_IGNORECASE) {
+ BUFPUSH(option_set);
+ BUFPUSH(stackp[-1]);
+ }
+ }
p0 = b;
options = *--stackp;
switch (c = *--stackp) {
@@ -3241,7 +3264,8 @@ re_search(bufp, string, size, startpos, range, regs)
}
if (startpos > size) return -1;
- if (anchor && size > 0 && startpos == size) return -1;
+ if ((anchor || !bufp->can_be_null) && size > 0 && startpos == size)
+ return -1;
val = re_match(bufp, string, size, startpos, regs);
if (val >= 0) return startpos;
if (val == -2) return -2;