mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-18 03:24:00 +00:00
reflect: fix (u)int -> string conversions for invalid code points
This commit is contained in:
committed by
Damian Gryski
parent
e111b489ec
commit
364ac2dcb2
@@ -1690,20 +1690,27 @@ func makeComplex(flags valueFlags, f complex128, t *RawType) Value {
|
|||||||
func stringFromUnicode(x rune) string
|
func stringFromUnicode(x rune) string
|
||||||
|
|
||||||
func cvtIntString(v Value, t *RawType) Value {
|
func cvtIntString(v Value, t *RawType) Value {
|
||||||
b := stringFromUnicode(rune(v.Int()))
|
s := "\uFFFD"
|
||||||
|
if x := v.Int(); int64(rune(x)) == x {
|
||||||
|
s = string(rune(x))
|
||||||
|
}
|
||||||
return Value{
|
return Value{
|
||||||
typecode: t,
|
typecode: t,
|
||||||
value: unsafe.Pointer(&b),
|
value: unsafe.Pointer(&s),
|
||||||
flags: v.flags,
|
flags: v.flags | valueFlagRO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cvtUintString(v Value, t *RawType) Value {
|
func cvtUintString(v Value, t *RawType) Value {
|
||||||
b := stringFromUnicode(rune(v.Uint()))
|
s := "\uFFFD"
|
||||||
|
if x := v.Uint(); uint64(rune(x)) == x {
|
||||||
|
s = string(rune(x))
|
||||||
|
}
|
||||||
|
|
||||||
return Value{
|
return Value{
|
||||||
typecode: t,
|
typecode: t,
|
||||||
value: unsafe.Pointer(&b),
|
value: unsafe.Pointer(&s),
|
||||||
flags: v.flags,
|
flags: v.flags | valueFlagRO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,6 +189,86 @@ func TestTinyConvert(t *testing.T) {
|
|||||||
{V(complex64(2i)), V(complex128(2i))},
|
{V(complex64(2i)), V(complex128(2i))},
|
||||||
{V(complex128(3i)), V(complex64(3i))},
|
{V(complex128(3i)), V(complex64(3i))},
|
||||||
{V(complex128(4i)), V(complex128(4i))},
|
{V(complex128(4i)), V(complex128(4i))},
|
||||||
|
|
||||||
|
// string
|
||||||
|
{V(string("hello")), V(string("hello"))},
|
||||||
|
{V(string("bytes1")), V([]byte("bytes1"))},
|
||||||
|
{V([]byte("bytes2")), V(string("bytes2"))},
|
||||||
|
{V([]byte("bytes3")), V([]byte("bytes3"))},
|
||||||
|
{V(string("runes♝")), V([]rune("runes♝"))},
|
||||||
|
{V([]rune("runes♕")), V(string("runes♕"))},
|
||||||
|
{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
|
||||||
|
{V(int('a')), V(string("a"))},
|
||||||
|
{V(int8('a')), V(string("a"))},
|
||||||
|
{V(int16('a')), V(string("a"))},
|
||||||
|
{V(int32('a')), V(string("a"))},
|
||||||
|
{V(int64('a')), V(string("a"))},
|
||||||
|
{V(uint('a')), V(string("a"))},
|
||||||
|
{V(uint8('a')), V(string("a"))},
|
||||||
|
{V(uint16('a')), V(string("a"))},
|
||||||
|
{V(uint32('a')), V(string("a"))},
|
||||||
|
{V(uint64('a')), V(string("a"))},
|
||||||
|
{V(uintptr('a')), V(string("a"))},
|
||||||
|
{V(int(-1)), V(string("\uFFFD"))},
|
||||||
|
{V(int8(-2)), V(string("\uFFFD"))},
|
||||||
|
{V(int16(-3)), V(string("\uFFFD"))},
|
||||||
|
{V(int32(-4)), V(string("\uFFFD"))},
|
||||||
|
{V(int64(-5)), V(string("\uFFFD"))},
|
||||||
|
{V(int64(-1 << 32)), V(string("\uFFFD"))},
|
||||||
|
{V(int64(1 << 32)), V(string("\uFFFD"))},
|
||||||
|
{V(uint(0x110001)), V(string("\uFFFD"))},
|
||||||
|
{V(uint32(0x110002)), V(string("\uFFFD"))},
|
||||||
|
{V(uint64(0x110003)), V(string("\uFFFD"))},
|
||||||
|
{V(uint64(1 << 32)), V(string("\uFFFD"))},
|
||||||
|
{V(uintptr(0x110004)), V(string("\uFFFD"))},
|
||||||
|
|
||||||
|
// named string
|
||||||
|
{V(MyString("hello")), V(string("hello"))},
|
||||||
|
{V(string("hello")), V(MyString("hello"))},
|
||||||
|
{V(string("hello")), V(string("hello"))},
|
||||||
|
{V(MyString("hello")), V(MyString("hello"))},
|
||||||
|
{V(MyString("bytes1")), V([]byte("bytes1"))},
|
||||||
|
{V([]byte("bytes2")), V(MyString("bytes2"))},
|
||||||
|
{V([]byte("bytes3")), V([]byte("bytes3"))},
|
||||||
|
{V(MyString("runes♝")), V([]rune("runes♝"))},
|
||||||
|
{V([]rune("runes♕")), V(MyString("runes♕"))},
|
||||||
|
{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
|
||||||
|
{V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
|
||||||
|
{V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
|
||||||
|
{V(int('a')), V(MyString("a"))},
|
||||||
|
{V(int8('a')), V(MyString("a"))},
|
||||||
|
{V(int16('a')), V(MyString("a"))},
|
||||||
|
{V(int32('a')), V(MyString("a"))},
|
||||||
|
{V(int64('a')), V(MyString("a"))},
|
||||||
|
{V(uint('a')), V(MyString("a"))},
|
||||||
|
{V(uint8('a')), V(MyString("a"))},
|
||||||
|
{V(uint16('a')), V(MyString("a"))},
|
||||||
|
{V(uint32('a')), V(MyString("a"))},
|
||||||
|
{V(uint64('a')), V(MyString("a"))},
|
||||||
|
{V(uintptr('a')), V(MyString("a"))},
|
||||||
|
{V(int(-1)), V(MyString("\uFFFD"))},
|
||||||
|
{V(int8(-2)), V(MyString("\uFFFD"))},
|
||||||
|
{V(int16(-3)), V(MyString("\uFFFD"))},
|
||||||
|
{V(int32(-4)), V(MyString("\uFFFD"))},
|
||||||
|
{V(int64(-5)), V(MyString("\uFFFD"))},
|
||||||
|
{V(uint(0x110001)), V(MyString("\uFFFD"))},
|
||||||
|
{V(uint32(0x110002)), V(MyString("\uFFFD"))},
|
||||||
|
{V(uint64(0x110003)), V(MyString("\uFFFD"))},
|
||||||
|
{V(uintptr(0x110004)), V(MyString("\uFFFD"))},
|
||||||
|
|
||||||
|
// named []byte
|
||||||
|
{V(string("bytes1")), V(MyBytes("bytes1"))},
|
||||||
|
{V(MyBytes("bytes2")), V(string("bytes2"))},
|
||||||
|
{V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
|
||||||
|
{V(MyString("bytes1")), V(MyBytes("bytes1"))},
|
||||||
|
{V(MyBytes("bytes2")), V(MyString("bytes2"))},
|
||||||
|
|
||||||
|
// named []rune
|
||||||
|
{V(string("runes♝")), V(MyRunes("runes♝"))},
|
||||||
|
{V(MyRunes("runes♕")), V(string("runes♕"))},
|
||||||
|
{V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
|
||||||
|
{V(MyString("runes♝")), V(MyRunes("runes♝"))},
|
||||||
|
{V(MyRunes("runes♕")), V(MyString("runes♕"))},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
@@ -153,7 +153,9 @@ func stringNext(s string, it *stringIterator) (bool, int, rune) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert a Unicode code point into an array of bytes and its length.
|
// Convert a Unicode code point into an array of bytes and its length.
|
||||||
func encodeUTF8(x rune) ([4]byte, uintptr) {
|
func encodeUTF8(r rune) ([4]byte, uintptr) {
|
||||||
|
x := uint32(r)
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/6240055/manually-converting-unicode-codepoints-into-utf-8-and-utf-16
|
// https://stackoverflow.com/questions/6240055/manually-converting-unicode-codepoints-into-utf-8-and-utf-16
|
||||||
// Note: this code can probably be optimized (in size and speed).
|
// Note: this code can probably be optimized (in size and speed).
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
Reference in New Issue
Block a user