From 20d323310053fd443ec3bac68515232d391b98a8 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 30 Oct 2001 08:43:28 +0000 Subject: * string.c (rb_str_chomp_bang): do smart chomp if $/ == '\n'. * io.c (rb_io_puts): don't treat Array specially. * bignum.c (rb_big_cmp): should convert bignum to float. * eval.c (rb_f_eval): can't modify untainted binding. * regex.c (re_compile_pattern): should preverve p0 value. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@1803 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 14 +++++++++ bignum.c | 8 ++++- eval.c | 3 ++ io.c | 33 +++----------------- misc/ruby-mode.el | 18 ++++++----- parse.y | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++----- regex.c | 14 ++++++--- string.c | 24 +++++++++++++++ version.h | 4 +-- 9 files changed, 158 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1c2cb06c..626567fed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Tue Oct 30 14:04:04 2001 Yukihiro Matsumoto + + * string.c (rb_str_chomp_bang): do smart chomp if $/ == '\n'. + + * io.c (rb_io_puts): don't treat Array specially. + + * bignum.c (rb_big_cmp): should convert bignum to float. + + * eval.c (rb_f_eval): can't modify untainted binding. + +Mon Oct 29 16:08:30 2001 Yukihiro Matsumoto + + * regex.c (re_compile_pattern): should preverve p0 value. + Mon Oct 29 14:56:44 2001 Usaku Nakamura * intern.h (rb_protect_inspect): follow the change of array.c. diff --git a/bignum.c b/bignum.c index 2a1601bf5..cbb069920 100644 --- a/bignum.c +++ b/bignum.c @@ -561,7 +561,13 @@ rb_big_cmp(x, y) break; case T_FLOAT: - y = dbl2big(RFLOAT(y)->value); + { + double d = rb_big2dbl(x); + + if (d == RFLOAT(y)->value) return INT2FIX(0); + if (d > RFLOAT(y)->value) return INT2FIX(1); + if (d < RFLOAT(y)->value) return INT2FIX(-1); + } break; default: diff --git a/eval.c b/eval.c index e9cf463d9..e27020926 100644 --- a/eval.c +++ b/eval.c @@ -5052,6 +5052,9 @@ rb_f_eval(argc, argv, self) rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline); if (ruby_safe_level >= 4) { StringValue(src); + if (!NIL_P(scope) && !OBJ_TAINTED(scope)) { + rb_raise(rb_eSecurityError, "Insecure: can't modify trusted binding"); + } } else { SafeStringValue(src); diff --git a/io.c b/io.c index 7dd1f493e..c33b3e781 100644 --- a/io.c +++ b/io.c @@ -2187,25 +2187,6 @@ rb_f_putc(recv, ch) return rb_io_putc(rb_defout, ch); } -static VALUE rb_io_puts _((int, VALUE*, VALUE)); - -static VALUE -io_puts_ary(ary, out) - VALUE ary, out; -{ - VALUE tmp; - int i; - - for (i=0; ilen; i++) { - tmp = RARRAY(ary)->ptr[i]; - if (rb_inspecting_p(tmp)) { - tmp = rb_str_new2("[...]"); - } - rb_io_puts(1, &tmp, out); - } - return Qnil; -} - static VALUE rb_io_puts(argc, argv, out) int argc; @@ -2221,18 +2202,12 @@ rb_io_puts(argc, argv, out) return Qnil; } for (i=0; iptr[RSTRING(line)->len-1] != '\n') { rb_io_write(out, rb_default_rs); diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index a66568552..7f7cebef7 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -671,26 +671,30 @@ An end of a defun is found by moving forward from the beginning of one." '( ;; #{ }, #$hoge, #@foo are not comments ("\\(#\\)[{$@]" 1 (1 . nil)) - ;; the last $' in the string ,'...$' is not variable - ("\\(^\\|[[\\s <+(,]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[\\?\\$]\\('\\)" + ;; the last $' in the string ,'...$' is not variable + ;; the last ?' in the string ,'...?' is not ascii code + ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[\\?\\$]\\('\\)" (2 (7 . nil)) (4 (7 . nil))) - ;; the last $` in the string ,`...$` is not variable - ("\\(^\\|[[\\s <+(,]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[\\?\\$]\\(`\\)" + ;; the last $` in the string ,`...$` is not variable + ;; the last ?` in the string ,`...?` is not ascii code + ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[\\?\\$]\\(`\\)" (2 (7 . nil)) (4 (7 . nil))) - ;; the last $" in the string ,"...$" is not variable - ("\\(^\\|[[\\s <+(,]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[\\?\\$]\\(\"\\)" + ;; the last $" in the string ,"...$" is not variable + ;; the last ?" in the string ,"...?" is not ascii code + ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[\\?\\$]\\(\"\\)" (2 (7 . nil)) (4 (7 . nil))) ;; $' $" $` .... are variables + ;; ?' ?" ?` are ascii codes ("[\\?\\$][#\"'`]" 0 (1 . nil)) ;; regexps ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)" (4 (7 . ?/)) (6 (7 . ?/))) ;; %Q!...! - ("\\(^\\|[[\\s <+(,]\\)%[xrqQ]?\\([^a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\2\\)" + ("\\(^\\|[[\\s <+(,=]\\)%[xrqQ]?\\([^a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\2\\)" (2 (7 . nil)) (4 (7 . nil))) ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil)) diff --git a/parse.y b/parse.y index ac26a0157..917848605 100644 --- a/parse.y +++ b/parse.y @@ -425,6 +425,81 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem $1->nd_value = $3; $$ = $1; } + | variable tOP_ASGN command_call + { + NODE *n = assignable($1, 0); + if ($2 == tOROP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_OR(gettable($1), n); + if (is_instance_id($1)) { + $$->nd_aid = $1; + } + } + else if ($2 == tANDOP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_AND(gettable($1), n); + } + else { + $$ = n; + if ($$) { + $$->nd_value = call_op(gettable($1),$2,1,$3); + } + } + fixpos($$, $3); + } + | primary '[' aref_args ']' tOP_ASGN command_call + { + NODE *tmp, *args = NEW_LIST($6); + + $3 = list_append($3, NEW_NIL()); + list_concat(args, $3); + if ($5 == tOROP) { + $5 = 0; + } + else if ($5 == tANDOP) { + $5 = 1; + } + $$ = NEW_OP_ASGN1($1, $5, args); + fixpos($$, $1); + } + | primary '.' tIDENTIFIER tOP_ASGN command_call + { + if ($4 == tOROP) { + $4 = 0; + } + else if ($4 == tANDOP) { + $4 = 1; + } + $$ = NEW_OP_ASGN2($1, $3, $4, $5); + fixpos($$, $1); + } + | primary '.' tCONSTANT tOP_ASGN command_call + { + if ($4 == tOROP) { + $4 = 0; + } + else if ($4 == tANDOP) { + $4 = 1; + } + $$ = NEW_OP_ASGN2($1, $3, $4, $5); + fixpos($$, $1); + } + | primary tCOLON2 tIDENTIFIER tOP_ASGN command_call + { + if ($4 == tOROP) { + $4 = 0; + } + else if ($4 == tANDOP) { + $4 = 1; + } + $$ = NEW_OP_ASGN2($1, $3, $4, $5); + fixpos($$, $1); + } + | backref tOP_ASGN command_call + { + rb_backref_error($1); + $$ = 0; + } | lhs '=' mrhs_basic { $$ = node_assign($1, NEW_REXPAND($3)); @@ -692,26 +767,27 @@ arg : lhs '=' arg value_expr($3); $$ = node_assign($1, $3); } - | variable tOP_ASGN {$$ = assignable($1, 0);} arg + | variable tOP_ASGN arg { + NODE *n = assignable($1, 0); if ($2 == tOROP) { - $3->nd_value = $4; - $$ = NEW_OP_ASGN_OR(gettable($1), $3); + n->nd_value = $3; + $$ = NEW_OP_ASGN_OR(gettable($1), n); if (is_instance_id($1)) { $$->nd_aid = $1; } } else if ($2 == tANDOP) { - $3->nd_value = $4; - $$ = NEW_OP_ASGN_AND(gettable($1), $3); + n->nd_value = $3; + $$ = NEW_OP_ASGN_AND(gettable($1), n); } else { - $$ = $3; + $$ = n; if ($$) { - $$->nd_value = call_op(gettable($1),$2,1,$4); + $$->nd_value = call_op(gettable($1),$2,1,$3); } } - fixpos($$, $4); + fixpos($$, $3); } | primary '[' aref_args ']' tOP_ASGN arg { diff --git a/regex.c b/regex.c index 694299daf..ad5d88cc4 100644 --- a/regex.c +++ b/regex.c @@ -1540,11 +1540,15 @@ re_compile_pattern(pattern, size, bufp) case 'M': case 'C': case 'c': - p0 = --p; - c = read_special(p, pend, &p0); - if (c > 255) goto invalid_escape; - p = p0; - had_num_literal = 1; + { + char *pp; + + --p; + c = read_special(p, pend, &pp); + if (c > 255) goto invalid_escape; + p = pp; + had_num_literal = 1; + } break; default: diff --git a/string.c b/string.c index a4612221c..c57ebb5a5 100644 --- a/string.c +++ b/string.c @@ -2661,15 +2661,37 @@ rb_str_chomp_bang(argc, argv, str) long len = RSTRING(str)->len; if (rb_scan_args(argc, argv, "01", &rs) == 0) { + if (len == 0) return Qnil; rs = rb_rs; + if (rs == rb_default_rs) { + smart_chomp: + rb_str_modify(str); + if (RSTRING(str)->ptr[len-1] == '\n') { + RSTRING(str)->len--; + if (RSTRING(str)->len > 0 && + RSTRING(str)->ptr[RSTRING(str)->len-1] == '\r') { + RSTRING(str)->len--; + } + return str; + } + else if (RSTRING(str)->ptr[len-1] == '\r') { + RSTRING(str)->len--; + return str; + } + return Qnil; + } } if (NIL_P(rs)) return Qnil; + if (len == 0) return Qnil; StringValue(rs); + rb_str_modify(str); rslen = RSTRING(rs)->len; if (rslen == 0) { while (len>0 && p[len-1] == '\n') { len--; + if (len>0 && p[len-1] == '\r') + len--; } if (len < RSTRING(str)->len) { rb_str_modify(str); @@ -2681,6 +2703,8 @@ rb_str_chomp_bang(argc, argv, str) } if (rslen > len) return Qnil; newline = RSTRING(rs)->ptr[rslen-1]; + if (rslen == 1 && newline == '\n') + goto smart_chomp; if (p[len-1] == newline && (rslen <= 1 || diff --git a/version.h b/version.h index ec9deda4e..93a7ff597 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.1" -#define RUBY_RELEASE_DATE "2001-10-29" +#define RUBY_RELEASE_DATE "2001-10-30" #define RUBY_VERSION_CODE 171 -#define RUBY_RELEASE_CODE 20011029 +#define RUBY_RELEASE_CODE 20011030 -- cgit