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)
|
||