@@ -139,3 +139,36 @@ TEST(PegtlExecutableCase, AnalyzeExecutableGrammar)
139
139
ASSERT_EQ (size_t { 0 }, analyze<executable_document>(true ))
140
140
<< " there shouldn't be any infinite loops in the PEG version of the grammar" ;
141
141
}
142
+
143
+ TEST (PegtlExecutableCase, InvalidStringEscapeSequence)
144
+ {
145
+ bool parsedQuery = false ;
146
+ bool caughtException = false ;
147
+
148
+ try
149
+ {
150
+ memory_input<> input (R"gql( query { foo @something(arg: "\.") })gql" ,
151
+ " InvalidStringEscapeSequence" );
152
+ parsedQuery = parse<executable_document>(input);
153
+ }
154
+ catch (const peg::parse_error& e)
155
+ {
156
+ ASSERT_NE (nullptr , e.what ());
157
+
158
+ using namespace std ::literals;
159
+
160
+ const std::string_view error { e.what () };
161
+ constexpr auto c_start = " InvalidStringEscapeSequence:1:31: parse error matching " sv;
162
+ constexpr auto c_end = " graphql::peg::string_escape_sequence_content" sv;
163
+
164
+ ASSERT_TRUE (error.size () > c_start.size ()) << " error message is too short" ;
165
+ ASSERT_TRUE (error.size () > c_end.size ()) << " error message is too short" ;
166
+ EXPECT_TRUE (error.substr (0 , c_start.size ()) == c_start) << e.what ();
167
+ EXPECT_TRUE (error.substr (error.size () - c_end.size ()) == c_end) << e.what ();
168
+
169
+ caughtException = true ;
170
+ }
171
+
172
+ EXPECT_TRUE (caughtException) << " should catch a parse exception" ;
173
+ EXPECT_FALSE (parsedQuery) << " should not successfully parse the query" ;
174
+ }
0 commit comments