Go creates raw control characters in JSON output due to emoji

I'm having problems with something in Go, and I'm not sure where to look. I am retrieving a UTF-8 string from a MySQL database and trying to return it in a JSON response to the client.

Different clients react differently, but iOS NSJSONSerializationreturns a Unescaped control character error . This violates the entire application. I can decrypt JSON without problems in Chrome using JSON.parse().

On the server side, the same generator function, written in a different language, except Go, works fine. Help?


EDIT: Here is the JSON causing the problem:

{ "test":"☮️" }

... if I omit this emoji, it works. If he is there, he does not work. The problem seems to be due to the presence of two different encodings for certain emoji. It seems that they fire Go, but both of them are valid.

To demonstrate the difference in coding, some of the emoji are displayed in the database explorer, and some are not:

screenshot

... , , 100% . ( ) . , , ( -) , , , . , / ... .

. .

+4
1

Go .

fmt.Println([]byte("☮️"))
//[226 152 174 239 184 143]
//Yup, 1 character - 6 bytes.

NSJSONSerialization can not . , NSJSONSerialization Emoji. - NSData * utf32Data = [uniText dataUsingEncoding:NSUTF32LittleEndianStringEncoding];.

- "☮️" simbol " iOS", go?

UPD

, , - . UTF16?

// it look the same, but completely different "characters"
//first one is yours, and second one is U+262E
const nihongo = "☮️☮"
for index, runeValue := range nihongo {
        fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
}
bad := []byte("☮️")
good := []byte("☮")
fmt.Printf("%v %s \n", bad, bad)
fmt.Printf("%v %s \n", good, good)

:

U+262E '☮' starts at byte position 0
U+FE0F '️' starts at byte position 3
U+262E '☮' starts at byte position 6
[226 152 174 239 184 143] ☮️ 
[226 152 174] ☮ 

UDP2

! ctrl + c/ctrl + v . ! 2 .

unprintable := []byte{239, 184, 143}
fmt.Printf("valid? %v", utf8.Valid(unprintable))
fmt.Println("full rune?", utf8.FullRune(unprintable))
r, size := utf8.DecodeRune(unprintable)
fmt.Println(r, size, string(r))
fmt.Printf("valid rune? #v", utf8.ValidRune(r))

:

valid? true
full rune? true
65039 3 ️
valid rune? true

, db , "" , NSJSONSerialization . iOS =)

+2

All Articles