@@ -139,3 +139,36 @@ TEST(PegtlExecutableCase, AnalyzeExecutableGrammar)
139139 ASSERT_EQ (size_t { 0 }, analyze<executable_document>(true ))
140140 << " there shouldn't be any infinite loops in the PEG version of the grammar" ;
141141}
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