mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
fe17d66363
Make `Integer#chr("UTF-8")` reject UTF-16 surrogate code points
(U+D800..U+DFFF), and make `String#ord` reject ill-formed UTF-8 byte
sequences (overlong encodings, surrogates encoded as UTF-8, and code
points above U+10FFFF), matching CRuby and RFC 3629.
The `utf8code()` helper now decodes the code point first and then
validates the range per byte length:
len=2: cp >= 0x80 (rejects overlong)
len=3: cp >= 0x800 and not D800..DFFF
len=4: 0x10000 <= cp <= 0x10FFFF
close #2708
Co-authored-by: Claude <noreply@anthropic.com>
33 lines
1.2 KiB
Ruby
33 lines
1.2 KiB
Ruby
assert('Integer#chr') do
|
|
assert_equal("A", 65.chr)
|
|
assert_equal("B", 0x42.chr)
|
|
assert_equal("\xab", 171.chr)
|
|
assert_raise(RangeError) { -1.chr }
|
|
assert_raise(RangeError) { 256.chr }
|
|
|
|
assert_equal("A", 65.chr("ASCII-8BIT"))
|
|
assert_equal("B", 0x42.chr("BINARY"))
|
|
assert_equal("\xab", 171.chr("ascii-8bit"))
|
|
assert_raise(RangeError) { -1.chr("binary") }
|
|
assert_raise(RangeError) { 256.chr("Ascii-8bit") }
|
|
assert_raise(ArgumentError) { 65.chr("ASCII") }
|
|
assert_raise(ArgumentError) { 65.chr("ASCII-8BIT", 2) }
|
|
assert_raise(TypeError) { 65.chr(:BINARY) }
|
|
|
|
if __ENCODING__ == "ASCII-8BIT"
|
|
assert_raise(ArgumentError) { 65.chr("UTF-8") }
|
|
else
|
|
assert_equal("A", 65.chr("UTF-8"))
|
|
assert_equal("B", 0x42.chr("UTF-8"))
|
|
assert_equal("«", 171.chr("utf-8"))
|
|
assert_equal("あ", 12354.chr("Utf-8"))
|
|
assert_raise(RangeError) { -1.chr("utf-8") }
|
|
assert_raise(RangeError) { 0x110000.chr("UTF-8") }
|
|
# UTF-16 surrogates are not valid Unicode scalar values (RFC 3629, #2708)
|
|
assert_raise(RangeError) { 0xD800.chr("UTF-8") }
|
|
assert_raise(RangeError) { 0xDFFF.chr("UTF-8") }
|
|
assert_equal "\u{D7FF}", 0xD7FF.chr("UTF-8")
|
|
assert_equal "\u{E000}", 0xE000.chr("UTF-8")
|
|
end
|
|
end
|