summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--bignum.c8
-rw-r--r--eval.c3
-rw-r--r--io.c33
-rw-r--r--misc/ruby-mode.el18
-rw-r--r--parse.y92
-rw-r--r--regex.c14
-rw-r--r--string.c24
-rw-r--r--version.h4
9 files changed, 158 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index c1c2cb06cd..626567fed9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Tue Oct 30 14:04:04 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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 <matz@ruby-lang.org>
+
+ * regex.c (re_compile_pattern): should preverve p0 value.
+
Mon Oct 29 14:56:44 2001 Usaku Nakamura <usa@ruby-lang.org>
* intern.h (rb_protect_inspect): follow the change of array.c.
diff --git a/bignum.c b/bignum.c
index 2a1601bf5b..cbb0699209 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 e9cf463d9f..e270209268 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 7dd1f493e0..c33b3e7818 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; i<RARRAY(ary)->len; 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; i<argc; i++) {
- switch (TYPE(argv[i])) {
- case T_NIL:
+ if (NIL_P(argv[i])) {
line = rb_str_new2("nil");
- break;
- case T_ARRAY:
- rb_protect_inspect(io_puts_ary, argv[i], out);
- continue;
- default:
- line = argv[i];
- break;
}
- line = rb_obj_as_string(line);
+ else {
+ line = rb_obj_as_string(argv[i]);
+ }
rb_io_write(out, line);
if (RSTRING(line)->ptr[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 a665685523..7f7cebef75 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 ac26a01577..917848605b 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) {
- $<node>3->nd_value = $4;
- $$ = NEW_OP_ASGN_OR(gettable($1), $<node>3);
+ n->nd_value = $3;
+ $$ = NEW_OP_ASGN_OR(gettable($1), n);
if (is_instance_id($1)) {
$$->nd_aid = $1;
}
}
else if ($2 == tANDOP) {
- $<node>3->nd_value = $4;
- $$ = NEW_OP_ASGN_AND(gettable($1), $<node>3);
+ n->nd_value = $3;
+ $$ = NEW_OP_ASGN_AND(gettable($1), n);
}
else {
- $$ = $<node>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 694299daf9..ad5d88cc4f 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 a4612221c5..c57ebb5a5b 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 ec9deda4e3..93a7ff5975 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