From 9b8937d4ce5882667518de2fd5c0931ccb2a6f18 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Thu, 21 Mar 2019 00:36:17 +0300 Subject: [PATCH] fixes #22 (#23) --- .../BinaryTest.graphql | Bin 0 -> 60194 bytes .../GraphQLParser.Benchmarks.csproj | 14 +++++- .../LexerBenchmark.cs | 16 +++++++ src/GraphQLParser/AST/GraphQLListValue.cs | 2 +- .../Exceptions/GraphQLSyntaxErrorException.cs | 42 ++++++++++++++++-- src/GraphQLParser/LexerContext.cs | 2 +- src/GraphQLParser/ParserContext.cs | 1 - 7 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/GraphQLParser.Benchmarks/BinaryTest.graphql diff --git a/src/GraphQLParser.Benchmarks/BinaryTest.graphql b/src/GraphQLParser.Benchmarks/BinaryTest.graphql new file mode 100644 index 0000000000000000000000000000000000000000..ca03f5abaa4e3a4d08715dc428d38039899be006 GIT binary patch literal 60194 zcmeI*y-LGS6ae6gU0nRx1W_tZzC|cbIygEAg0>b4l@2a~h`S*8U_OYGxCjnvj6OGbPM%of<1J#6$}U^^U! zm2gs(DFFh33&bCR7a)BC1PJ6H5XbRX4q=2KK!5-N0t5&UAV8p80?l%zBO3w)2oNAZ zfB*pk1PBnA5{TcYh72SEcb7M<&hX`F(Cc3hj^m%xey@1nMi0{LjLxYwElFDko5O0UZR&zC!W~T|ftc&{wdM`RgE1$z@d( zf$#)$5D0J0WK4hn0RjXF5FkK+009C72oR`=KwOhLl}UgA0RjXF5FkK+z;Xi3<))iW zpzZ?6tA4w`&-cyboxg{5w@`mtf$y{ra6bV81PBlyK%g`NC#A_`(L_EMooF5b0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlykb}VM;-9f>R^P@>91^(dnhs@dEC2xl1eO#ib|22#lG&P0fB*pk1PBlyK!89> KfzI&i=;9Ae`&p|1 literal 0 HcmV?d00001 diff --git a/src/GraphQLParser.Benchmarks/GraphQLParser.Benchmarks.csproj b/src/GraphQLParser.Benchmarks/GraphQLParser.Benchmarks.csproj index f9e2b055..5eacd042 100644 --- a/src/GraphQLParser.Benchmarks/GraphQLParser.Benchmarks.csproj +++ b/src/GraphQLParser.Benchmarks/GraphQLParser.Benchmarks.csproj @@ -8,16 +8,26 @@ true + + + + + + + PreserveNewest + + + - + - + diff --git a/src/GraphQLParser.Benchmarks/LexerBenchmark.cs b/src/GraphQLParser.Benchmarks/LexerBenchmark.cs index dbcef69f..d0d6b8de 100644 --- a/src/GraphQLParser.Benchmarks/LexerBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/LexerBenchmark.cs @@ -1,4 +1,6 @@ using BenchmarkDotNet.Attributes; +using GraphQLParser.Exceptions; +using System.IO; namespace GraphQLParser.Benchmarks { @@ -7,6 +9,7 @@ namespace GraphQLParser.Benchmarks #endif public class LexerBenchmark { + private static readonly string Binary = File.ReadAllText("BinaryTest.graphql"); private const string KitchenSink = @" query queryName($foo: ComplexType, $site: Site = MOBILE) { whoever123is: node(id: [123, 456]) { @@ -70,5 +73,18 @@ public void LexKitchenSink() resetPosition = token.End; } } + + [Benchmark] + public void ParseBinaryFile() + { + try + { + var parser = new Parser(new Lexer()); + parser.Parse(new Source(Binary)); + } + catch (GraphQLSyntaxErrorException) + { + } + } } } diff --git a/src/GraphQLParser/AST/GraphQLListValue.cs b/src/GraphQLParser/AST/GraphQLListValue.cs index 41c708d6..04919661 100644 --- a/src/GraphQLParser/AST/GraphQLListValue.cs +++ b/src/GraphQLParser/AST/GraphQLListValue.cs @@ -4,7 +4,7 @@ public class GraphQLListValue : GraphQLValue { - private ASTNodeKind kindField; + private readonly ASTNodeKind kindField; public GraphQLListValue(ASTNodeKind kind) { diff --git a/src/GraphQLParser/Exceptions/GraphQLSyntaxErrorException.cs b/src/GraphQLParser/Exceptions/GraphQLSyntaxErrorException.cs index a6dad2b7..f47ff149 100644 --- a/src/GraphQLParser/Exceptions/GraphQLSyntaxErrorException.cs +++ b/src/GraphQLParser/Exceptions/GraphQLSyntaxErrorException.cs @@ -2,6 +2,7 @@ { using System; using System.Linq; + using System.Text; public class GraphQLSyntaxErrorException : Exception { @@ -49,13 +50,48 @@ private static string LeftPad(int length, string str) private static string ReplaceWithUnicodeRepresentation(string str) { + if (!HasReplacementCharacter(str)) + return str; + + var buffer = new StringBuilder(str.Length); + foreach (var code in str) { - if (code < 0x0020 && code != 0x0009 && code != 0x000A && code != 0x000D) - str = str.Replace(string.Empty + code, "\\u" + ((int)code).ToString("D4")); + if (IsReplacementCharacter(code)) + { + buffer.Append(GetUnicodeRepresentation(code)); + } + else + { + buffer.Append(code); + } } - return str; + return buffer.ToString(); + } + + private static bool HasReplacementCharacter(string str) + { + foreach (var code in str) + { + if (IsReplacementCharacter(code)) + return true; + } + + return false; + } + + private static bool IsReplacementCharacter(char code) => code < 0x0020 && code != 0x0009 && code != 0x000A && code != 0x000D; + + private static string GetUnicodeRepresentation(char code) + { + switch (code) + { + case '\0': + return "\\u0000"; + default: + return "\\u" + ((int)code).ToString("D4"); + } } } } \ No newline at end of file diff --git a/src/GraphQLParser/LexerContext.cs b/src/GraphQLParser/LexerContext.cs index 3dc2f5c5..75e7a17f 100644 --- a/src/GraphQLParser/LexerContext.cs +++ b/src/GraphQLParser/LexerContext.cs @@ -6,7 +6,7 @@ public class LexerContext : IDisposable { private int currentIndex; - private ISource source; + private readonly ISource source; public LexerContext(ISource source, int index) { diff --git a/src/GraphQLParser/ParserContext.cs b/src/GraphQLParser/ParserContext.cs index 3e4e60e2..01e32030 100644 --- a/src/GraphQLParser/ParserContext.cs +++ b/src/GraphQLParser/ParserContext.cs @@ -689,7 +689,6 @@ private GraphQLValue ParseNameValue(bool isConstant) $"Unexpected {this.currentToken}", this.source, this.currentToken.Start); } - private GraphQLValue ParseObject(bool isConstant) { var comment = GetComment();