-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Escape sequences in string arguments - unicode and others #4721
Comments
Hey! Thanks for the detailed writeup. Yes, as you noticed, there have been many attempts to match the spec on this 😅 I've created a replication script for this bug: Replicate unicode escape bugs
require "bundler/inline"
gemfile do
gem "graphql", "2.1.7"
end
class MySchema < GraphQL::Schema
class QueryType < GraphQL::Schema::Object
field :get_string, String do
argument :string, String
end
def get_string(string:)
puts "***"
puts "string.length: #{string.length}"
puts "string value: \"#{string}\""
string.each_char.each_with_index do |c, i|
puts "string[#{i}] = \"#{c}\""
end
puts "***"
string
end
end
query(QueryType)
end
query_str = File.read("./example1.graphql")
puts query_str
pp MySchema.execute(query_str).to_h
query_str = File.read("./example2.graphql")
puts query_str
pp MySchema.execute(query_str).to_h # example1.graphql
{
example1: getString(string: "\u0064") # correct: should return "d"
example2: getString(string: "\\u0064") # incorrect: should return "\\u0064"
# example3: getString(string: "\u006") # correct: validation error
example4: getString(string: "\\u006") # correct: should return "\\u006"
} # example2.graphql
query bug2 {
# example1: getString(string: """\a""") # incorrect (fails): should be "\\a"
# example2: getString(string: """\u006""") # incorrect (fails): should be "\\u006"
example3: getString(string: """\n""") # incorrect: should be "\\n"
example4: getString(string: """\u0064""") # incorrect: should be "\\u0064"
} It seems like it boils down to two things:
I've got an open PR to rewrite the lexer (#4718) and I'll dive in on that when I'm done there! |
I've got a fix in the works over at #4824. The most interesting part of the bug was basically that these two graphql-ruby/lib/graphql/language/lexer.rb Lines 302 to 303 in 18f3ded
They had to be merged into a single |
Describe the bug
handling unicode has some bugs and weird behaviors:
Versions
graphql
version: 2.0.19rails
(or other framework): 6.0.4.7other applicable versions (
graphql-batch
, etc): noneGraphQL schema
in both the examples below i used the following simple resolver.
note that the result is the rendered result to the client, so there are escape characters added.
i also printed the string passed to the resolver char by char to make sure i'm not making mistakes:
GraphQL query
Example GraphQL query and response (if query execution is involved)
example for bug 1:
the log:
the result:
example for bug 2
the log:
the result:
Steps to reproduce
Steps to reproduce the behavior
Expected behavior
parsing string arguments:
"\\u0064" => "\u0064"
"""\u0064""" => "\u0064"
Actual behavior
parsing string arguments:
"\\u0064" => "n"
"""\u0064""" => "n"
Click to view exception backtrace
n/aAdditional context
I saw an old version changing the behavior of
\\u
back and forth, stating it was reverted because of failing other parsers test suite:#372
it mentions a test suite in graphql-js in this url (it moved, this is the updated link)
note: in the tests, the string that are written are parsed by the language parser (js). so, for example, the string
'\u{1234}'
is actually passed to the parser asሴ
, while the string\\u{1234}
is passed as the characters\
,u
,{
, etc.the tests there behave as i the expected behavior i described. examples:
"unicode \u1234\u5678\u90AB\uCDEF"
, and it returns the characters:unicode ሴ噸邫췯
this works the same as ruby.
"escaped \n\r\b\t\f"
and returnsescaped
followed by newline, carriage return, etc.this works the same as ruby.
"""unescaped \n\r\b\t\f\u1234"""
and returns the characters:unescaped \n\r\b\t\f\u1234
in ruby the chars are converted to special characters, same as 2 - which is a bug.
in the test i passed the characters:
"unicode \\u{1234}\\u{5678}\\u{90AB}\\u{CDE"
and the result is the characters:unicode \u{1234}\u{5678}\u{90AB}\u{CDE
. the unicode is not parsed, and the escape of the\
before theu
works.in ruby the first 3 unicodes are parsed, and the last one is not. the escape of the
\
before theu
does not work.The text was updated successfully, but these errors were encountered: