Bug #15941 ยป scrub-modify-check.patch
| string.c | ||
|---|---|---|
| 
     { 
   | 
||
| 
         int encidx; 
   | 
||
| 
         VALUE buf = Qnil; 
   | 
||
| 
         const char *rep; 
   | 
||
| 
         const char *rep, *p, *e, *p1, *sp; 
   | 
||
| 
         long replen = -1; 
   | 
||
| 
         int tainted = 0; 
   | 
||
| 
         long slen; 
   | 
||
| 
         if (rb_block_given_p()) { 
   | 
||
| 
     	if (!NIL_P(repl)) 
   | 
||
| ... | ... | |
| 
     	rep = replace; replen = (int)sizeof(replace); \ 
   | 
||
| 
         } while (0) 
   | 
||
| 
         slen = RSTRING_LEN(str); 
   | 
||
| 
         p = RSTRING_PTR(str); 
   | 
||
| 
         e = RSTRING_END(str); 
   | 
||
| 
         p1 = p; 
   | 
||
| 
         sp = p; 
   | 
||
| 
         if (rb_enc_asciicompat(enc)) { 
   | 
||
| 
     	const char *p = RSTRING_PTR(str); 
   | 
||
| 
     	const char *e = RSTRING_END(str); 
   | 
||
| 
     	const char *p1 = p; 
   | 
||
| 
     	int rep7bit_p; 
   | 
||
| 
     	if (!replen) { 
   | 
||
| 
     	    rep = NULL; 
   | 
||
| ... | ... | |
| 
     		} 
   | 
||
| 
     		else { 
   | 
||
| 
     		    repl = rb_yield(rb_enc_str_new(p, clen, enc)); 
   | 
||
| 
                         str_mod_check(str, sp, slen); 
   | 
||
| 
     		    repl = str_compat_and_valid(repl, enc); 
   | 
||
| 
     		    tainted |= OBJ_TAINTED_RAW(repl); 
   | 
||
| 
     		    rb_str_buf_cat(buf, RSTRING_PTR(repl), RSTRING_LEN(repl)); 
   | 
||
| ... | ... | |
| 
     	    } 
   | 
||
| 
     	    else { 
   | 
||
| 
     		repl = rb_yield(rb_enc_str_new(p, e-p, enc)); 
   | 
||
| 
                     str_mod_check(str, sp, slen); 
   | 
||
| 
     		repl = str_compat_and_valid(repl, enc); 
   | 
||
| 
     		tainted |= OBJ_TAINTED_RAW(repl); 
   | 
||
| 
     		rb_str_buf_cat(buf, RSTRING_PTR(repl), RSTRING_LEN(repl)); 
   | 
||
| ... | ... | |
| 
         } 
   | 
||
| 
         else { 
   | 
||
| 
     	/* ASCII incompatible */ 
   | 
||
| 
     	const char *p = RSTRING_PTR(str); 
   | 
||
| 
     	const char *e = RSTRING_END(str); 
   | 
||
| 
     	const char *p1 = p; 
   | 
||
| 
     	long mbminlen = rb_enc_mbminlen(enc); 
   | 
||
| 
     	if (!replen) { 
   | 
||
| 
     	    rep = NULL; 
   | 
||
| ... | ... | |
| 
     		} 
   | 
||
| 
     		else { 
   | 
||
| 
     		    repl = rb_yield(rb_enc_str_new(p, clen, enc)); 
   | 
||
| 
                         str_mod_check(str, sp, slen); 
   | 
||
| 
     		    repl = str_compat_and_valid(repl, enc); 
   | 
||
| 
     		    tainted |= OBJ_TAINTED_RAW(repl); 
   | 
||
| 
     		    rb_str_buf_cat(buf, RSTRING_PTR(repl), RSTRING_LEN(repl)); 
   | 
||
| ... | ... | |
| 
     	    } 
   | 
||
| 
     	    else { 
   | 
||
| 
     		repl = rb_yield(rb_enc_str_new(p, e-p, enc)); 
   | 
||
| 
                     str_mod_check(str, sp, slen); 
   | 
||
| 
     		repl = str_compat_and_valid(repl, enc); 
   | 
||
| 
     		tainted |= OBJ_TAINTED_RAW(repl); 
   | 
||
| 
     		rb_str_buf_cat(buf, RSTRING_PTR(repl), RSTRING_LEN(repl)); 
   | 
||
| test/ruby/test_m17n.rb | ||
|---|---|---|
| 
         assert_predicate(str.dup.taint.scrub, :tainted?) 
   | 
||
| 
       end 
   | 
||
| 
       def test_scrub_modification_inside_block 
   | 
||
| 
         str = ("abc\u3042".b << "\xE3\x80".b).force_encoding('UTF-8') 
   | 
||
| 
         assert_raise(RuntimeError) {str.scrub{|_| str << "1234567890"; "?" }} 
   | 
||
| 
         str = "\x00\xD8\x42\x30".force_encoding(Encoding::UTF_16LE) 
   | 
||
| 
         assert_raise(RuntimeError) do 
   | 
||
| 
           str.scrub do |_| 
   | 
||
| 
             str << "1\x002\x00".force_encoding('UTF-16LE') 
   | 
||
| 
             "?\x00".force_encoding('UTF-16LE') 
   | 
||
| 
           end 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_scrub_replace_default 
   | 
||
| 
         assert_equal("\uFFFD\uFFFD\uFFFD", u("\x80\x80\x80").scrub) 
   | 
||
| 
         assert_equal("\uFFFDA", u("\xF4\x80\x80A").scrub) 
   | 
||