summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-06 13:11:44 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-06 13:11:44 +0000
commitbd10ce165c1a352d8a225face91d94e855b72e35 (patch)
treee4031bcb5d6816d1af2a8a15ba267f185490cd19 /string.c
parentfaa26f55704f8fcbca507e19c529f8fc45acc5d2 (diff)
string.c: fix false coderange
* string.c (rb_enc_str_scrub): enc can differ from the actual encoding of the string, the cached coderange is useless then. [ruby-core:82674] [Bug #13874] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r--string.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/string.c b/string.c
index 734184085c..0ed9489ae3 100644
--- a/string.c
+++ b/string.c
@@ -9553,6 +9553,8 @@ str_compat_and_valid(VALUE str, rb_encoding *enc)
return str;
}
+static VALUE enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl, int cr);
+
/**
* @param str the string to be scrubbed
* @param repl the replacement character
@@ -9561,13 +9563,25 @@ str_compat_and_valid(VALUE str, rb_encoding *enc)
VALUE
rb_str_scrub(VALUE str, VALUE repl)
{
- return rb_enc_str_scrub(STR_ENC_GET(str), str, repl);
+ rb_encoding *enc = STR_ENC_GET(str);
+ return enc_str_scrub(enc, str, repl, ENC_CODERANGE(str));
}
VALUE
rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl)
{
- int cr = ENC_CODERANGE(str);
+ int cr = ENC_CODERANGE_UNKNOWN;
+ if (enc == STR_ENC_GET(str)) {
+ /* cached coderange makes sense only when enc equals the
+ * actual encoding of str */
+ cr = ENC_CODERANGE(str);
+ }
+ return enc_str_scrub(enc, str, repl, cr);
+}
+
+static VALUE
+enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl, int cr)
+{
int encidx;
VALUE buf = Qnil;
const char *rep;