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

Fixes #10176 Updating struct.to_json to escape the key string. #10577

Closed
wants to merge 7 commits into from

Conversation

dwhu
Copy link
Contributor

@dwhu dwhu commented Jan 14, 2020

Please let me know where to place an appopriate test. No existing test
class appeared appropriate as far as I could tell.

@aiuto
Copy link
Contributor

aiuto commented Jan 14, 2020

@alandonovan You've touched this code most in the last year. Can you take a look.

@@ -513,6 +513,7 @@ java_library(
"//third_party:guava",
"//third_party:jsr305",
"//third_party/protobuf:protobuf_java",
"//third_party:apache_commons_lang"
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a new dependency, and it's totally unnecessary. There is already code in StructImpl.java to escape Java strings into JSON notation (see L319); please re-use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

@@ -299,7 +300,7 @@ private void printJson(Object value, StringBuilder sb, Location loc, String cont
throw new EvalException(loc, errorMessage);
}
sb.append("\"");
sb.append(entry.getKey());
sb.append(StringEscapeUtils.escapeJava(String.valueOf(entry.getKey())));
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't use String.valueOf(x) here; it's equivalent to x.toString() except when x is null, which can't happen because this statement is dominated by the check on L291 (and even if it could, I would prefer to see a crash in that case than to silently emit incorrect JSON).

Use: (String) entry.getKey()

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you also apply escaping to the field names on L280? Field names should be valid identifiers, but this is not guaranteed, and we don't want to emit corrupt JSON in that case.

At that point, there are three places that emit quote escape(s) quote; could you refactor jsonEscapeString to accept a StringBuilder and emit the quotes too? Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

.replace("\r", "\\r")
.replace("\t", "\\t");
.replace("\t", "\\t"));
if (appendColon) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The appendColon logic has no business being in here, as it can be composed separately an no extra cost, resulting in a simpler function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

private String jsonEscapeString(String string) {
return escapeDoubleQuotesAndBackslashesAndNewlines(string)
private void jsonEscapeString(StringBuilder stringBuilder, String string, boolean appendColon) {
stringBuilder.append("\"");
Copy link
Contributor

Choose a reason for hiding this comment

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

If you like, use append('"') to avoid the internal loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I completely understand your suggestion. Was my change what you had in mind?

@@ -333,10 +327,16 @@ private void printJson(Object value, StringBuilder sb, Location loc, String cont
}
}

private String jsonEscapeString(String string) {
return escapeDoubleQuotesAndBackslashesAndNewlines(string)
private void jsonEscapeString(StringBuilder stringBuilder, String string, boolean appendColon) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's call this function appendJSONStringLiteral, the StringBuilder 'out', and the String s.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

@dwhu dwhu changed the title GH-10176 Updating struct.to_json to escape the key string. Fixes #10176 Updating struct.to_json to escape the key string. Jan 15, 2020
@aiuto
Copy link
Contributor

aiuto commented Feb 14, 2020

Can someone please resolve the merge conflicts so we can merge this.
@alandonovan @dwhu

Please let me know where to place an appopriate test. No existing test
class appeared appropriate as far as I could tell.
- Adding another usage of jsonEscapeString
- Removing dependency on StringEscapeUtils
- Updating method and paremeter naming of jsonEscapeString method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants