Ruby String编码改变了版本

时间:2015-12-28 07:27:23

标签: ruby utf-8 character-encoding utf

我正在使用目前在ruby 1.9.3上运行的遗留项目,并正在调查将其在未来几个月内移至2.3.0

我们有这行代码,这会在不同的ruby版本上返回不同的结果。我想知道这是一个修复过的ruby bug,还是一个新bug,或者是一个记录在案的行为变化。对相关错误票据的引用会有所帮助。

content =  "Is your pl\xFFace available?".force_encoding("UTF-8")
content.encode("UTF-8", invalid: :replace) # some other details removed to give smallest code sample

红宝石1.9.3,2.0

的结果
"Is your pl\xFFace available?"

ruby​​ 2.1,2.2,2.3的结果

"Is your pl�ace available?"

基本上" \ xFF"被认为是无效的替换,但如果invalid: :replace省略,它不会引起错误。我猜这可能是因为它是无操作,因为源/目标编码是相同的。

1 个答案:

答案 0 :(得分:0)

如果您查看2.02.1文档之间的文档差异,您会看到以下文字在2.1中消失:

  

请注意,从编码enc到相同编码enc的转换是无操作,即返回接收器时没有任何更改,并且即使存在无效字节也不会引发异常。

所以当2.0和更低版本的源代码和目标编码相同且2.1+所做的情况下,2.0和更低版本没有修改字符串时,这种行为似乎是预期的变化。

我不能100%确定您的代码尝试做什么,但如果它尝试从无效的UTF-8字节序列中清除字符串,则可以使用valid_encoding?和从Ruby 2.1开始scrub

irb(main):055:0* content = "Is your pl\xFFace available?"
=> "Is your pl\xFFace available?"
irb(main):056:0> content.valid_encoding?
=> false
irb(main):057:0> new = content.scrub
=> "Is your pl�ace available?"
irb(main):059:0> new.valid_encoding?
=> true

修改

如果查看2.0源代码,如果senc(源代码)与denc(目标编码)相同,您将看到str_transcode0函数exits immediately

    if (senc && senc == denc) {
        return NIL_P(arg2) ? -1 : dencidx;
    }

2.1 it scrubs the data中,当编码相同且您明确要求替换无效序列时:

    if (senc && senc == denc) {
        ...
        if ((ecflags & ECONV_INVALID_MASK) && explicitly_invalid_replace) {
            dest = rb_str_scrub(str, rep);
        }
        ...
    }