diff options
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 48 |
1 files changed, 37 insertions, 11 deletions
@@ -1913,8 +1913,13 @@ rb_str_sub_bang(argc, argv, str) regs = RMATCH(match)->regs; if (iter) { + char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len; + rb_match_busy(match); repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + if (RSTRING(str)->ptr != p || RSTRING(str)->len != len) { + rb_raise(rb_eRuntimeError, "string modified"); + } rb_backref_set(match); } else { @@ -3095,7 +3100,7 @@ tr_setup_table(str, table, init) buf[c & 0xff] = !cflag; } for (i=0; i<256; i++) { - table[i] = table[i]&&buf[i]; + table[i] = table[i] && buf[i]; } } @@ -3554,6 +3559,17 @@ rb_f_split(argc, argv) } +static inline void +str_mod_check(s, p, len) + VALUE s; + char *p; + long len; +{ + if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) { + rb_raise(rb_eRuntimeError, "string modified"); + } +} + /* * call-seq: * str.each(separator=$/) {|substr| block } => str @@ -3628,8 +3644,7 @@ rb_str_each_line(argc, argv, str) line = rb_str_new5(str, s, p - s); OBJ_INFECT(line, str); rb_yield(line); - if (RSTRING(str)->ptr != ptr || RSTRING(str)->len != len) - rb_raise(rb_eArgError, "string modified"); + str_mod_check(str, ptr, len); s = p; } } @@ -3799,11 +3814,13 @@ rb_str_chomp_bang(argc, argv, str) { VALUE rs; int newline; - char *p = RSTRING(str)->ptr; - long len = RSTRING(str)->len, rslen; + char *p; + long len, rslen; if (rb_scan_args(argc, argv, "01", &rs) == 0) { + len = RSTRING(str)->len; if (len == 0) return Qnil; + p = RSTRING(str)->ptr; rs = rb_rs; if (rs == rb_default_rs) { smart_chomp: @@ -3827,9 +3844,10 @@ rb_str_chomp_bang(argc, argv, str) } } if (NIL_P(rs)) return Qnil; - if (len == 0) return Qnil; - StringValue(rs); + len = RSTRING(str)->len; + if (len == 0) return Qnil; + p = RSTRING(str)->ptr; rslen = RSTRING(rs)->len; if (rslen == 0) { while (len>0 && p[len-1] == '\n') { @@ -4277,7 +4295,7 @@ rb_str_crypt(str, salt) { extern char *crypt(); VALUE result; - char *s; + char *s, *cr; StringValue(salt); if (RSTRING(salt)->len < 2) @@ -4285,7 +4303,10 @@ rb_str_crypt(str, salt) if (RSTRING(str)->ptr) s = RSTRING(str)->ptr; else s = ""; - result = rb_str_new2(crypt(s, RSTRING(salt)->ptr)); + cr = crypt(s, RSTRING(salt)->ptr); + s = ALLOCA_N(char, strlen(cr)); + strcpy(s, cr); + result = rb_str_new2(s); OBJ_INFECT(result, str); OBJ_INFECT(result, salt); return result; @@ -4348,14 +4369,17 @@ rb_str_sum(argc, argv, str) { VALUE vbits; int bits; - char *p, *pend; + char *ptr, *p, *pend; + long len; if (rb_scan_args(argc, argv, "01", &vbits) == 0) { bits = 16; } else bits = NUM2INT(vbits); - p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; + ptr = p = RSTRING(str)->ptr; + len = RSTRING(str)->len; + pend = p + len; if (bits > sizeof(long)*CHAR_BIT) { VALUE res = INT2FIX(0); VALUE mod; @@ -4364,6 +4388,7 @@ rb_str_sum(argc, argv, str) mod = rb_funcall(mod, '-', 1, INT2FIX(1)); while (p < pend) { + str_mod_check(str, ptr, len); res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p)); p++; } @@ -4378,6 +4403,7 @@ rb_str_sum(argc, argv, str) mod = -1; } while (p < pend) { + str_mod_check(str, ptr, len); res += (unsigned int)*p; p++; } |