close
Skip to content

Use json.Marshal instead of strconv.Quote to correctly support unicode#2509

Merged
leaanthony merged 3 commits into
wailsapp:masterfrom
joshbuddy:bugfix/unicode-encoding
Apr 16, 2023
Merged

Use json.Marshal instead of strconv.Quote to correctly support unicode#2509
leaanthony merged 3 commits into
wailsapp:masterfrom
joshbuddy:bugfix/unicode-encoding

Conversation

@joshbuddy

Copy link
Copy Markdown
Contributor

I came across a bug where unicode values such as 🫣 would not get correctly escaped. This is due to using strconv.Quote which would encode this value as "\U0001fae3" which is not a valid js string. This would, in turn, get turned into "U0001fae3" in the frontend.

To correctly represent these values we need to use the new js format for multi-rune characters "\u{0001fae3}"[1], but I thought, instead of figuring out the correct quoting strategy, why not just use json.Marshal here instead. Certainly open to finding a different approach if you don't think this is a good idea.

Also decided to panic on error here as this error should never come up, and I saw similar panics in the code encountering things like this.

[1] https://exploringjs.com/es6/ch_unicode.html#sec_escape-sequences

@vercel

vercel Bot commented Mar 20, 2023

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
wails-v3-docs ❌ Failed (Inspect) Mar 20, 2023 at 10:04PM (UTC)

@leaanthony

Copy link
Copy Markdown
Member

Thanks for opening this and raising the issue. What testing have you done on this so far and on what platforms? Thanks!

@joshbuddy

Copy link
Copy Markdown
Contributor Author

@leaanthony I was only able to test this on Mac, but after making this change all the weird unicode issues I was having went away.

@leaanthony

Copy link
Copy Markdown
Member

@tmclane / @lyimmi - Is this something that can be easily tested on Linux? 🙏

@lyimmi

lyimmi commented Apr 11, 2023

Copy link
Copy Markdown
Contributor

@tmclane / @lyimmi - Is this something that can be easily tested on Linux? pray

I checked the basic behavior, go side responds with a unicode smiley, the frontend prints it as an escaped string. If I apply @joshbuddy's changes the unicode is parsed properly on the frontend.

I'm currently on Ubuntu 22.04 LTS

master:
Screenshot from 2023-04-11 14-26-34

PR applied:
Screenshot from 2023-04-11 14-28-06

@tmclane tmclane left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll test it in a bit. Looks like @lyimmi already did though.

f.ExecJS(`window.wails.Callback(` + strconv.Quote(message) + `);`)
escaped, err := json.Marshal(message)
if err != nil {
panic(err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make it not panic here? That would look like a crash for a user and be really hard to locate.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise for the other ones.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would you do though? If your callbacks fail then you have a pretty catastrophic error. I'm trying to think of an alternative

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good question! Let me think about it.. In the meantime I don't think we should block merging this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, a panic is appropriate here because json.Marshal should never return an error in response to marshaling a string, so if it did that, I would consider that to be unspecified behavior.

On a separate note, I notice that json.Marshall will do a certain amount of html escaping on a string. I can't think how it would be a problem, but worth noticing. See: https://pkg.go.dev/encoding/json#Marshal

String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune. So that the JSON will be safe to embed inside HTML <script> tags, the string is encoded using HTMLEscape, which replaces "<", ">", "&", U+2028, and U+2029 are escaped to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". This replacement can be disabled when using an Encoder, by calling SetEscapeHTML(false).

@leaanthony

Copy link
Copy Markdown
Member

@joshbuddy - could you please add an entry to the changelog in website/src/pages/changelog.mdx 👍

@joshbuddy
joshbuddy force-pushed the bugfix/unicode-encoding branch from 0707c1b to 144e0f3 Compare April 12, 2023 14:41
@joshbuddy

Copy link
Copy Markdown
Contributor Author

@leaanthony done

@leaanthony leaanthony left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants