Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Apr 16, 2023

Conversation

joshbuddy
Copy link
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
Copy link

vercel bot commented Mar 20, 2023

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
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
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
Member

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

@lyimmi
Copy link
Contributor

lyimmi commented Apr 11, 2023

@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

Copy link
Member

@tmclane tmclane left a comment

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
Member

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
Member

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
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
Member

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
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
Member

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

@joshbuddy
Copy link
Contributor Author

@leaanthony done

Copy link
Member

@leaanthony leaanthony left a comment

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.

None yet

4 participants