summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/string.c b/string.c
index a2287b8f28..8782e41bc2 100644
--- a/string.c
+++ b/string.c
@@ -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++;
}