diff --git a/CHANGELOG.md b/CHANGELOG.md index 26d2879..f484af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Change log ### vNEXT +- Fix escaping of literal .graphql files [Simon Lydell](https://github.com/lydell/) in [#88](https://github.com/apollographql/eslint-plugin-graphql/pull/88) - Fix ESLint config validation [Simon Lydell](https://github.com/lydell/) in [#86](https://github.com/apollographql/eslint-plugin-graphql/pull/86) ### v1.3.0 diff --git a/src/index.js b/src/index.js index c42eb1f..b56d60c 100644 --- a/src/index.js +++ b/src/index.js @@ -463,8 +463,16 @@ function strWithLen(len) { const gqlProcessor = { preprocess: function(text) { - const escaped = text.replace(/`/g, '\\`'); - + // Wrap the text in backticks and prepend the internal tag. First the text + // must be escaped, because of the three sequences that have special + // meaning in JavaScript template literals, and could change the meaning of + // the text or cause syntax errors. + // https://tc39.github.io/ecma262/#prod-TemplateCharacter + // + // - "`" would end the template literal. + // - "\" would start an escape sequence. + // - "${" would start an interpolation. + const escaped = text.replace(/[`\\]|\$\{/g, '\\$&'); return [`${internalTag}\`${escaped}\``]; }, postprocess: function(messages) { diff --git a/test/makeProcessors.js b/test/makeProcessors.js index 7364094..ebc1dbe 100644 --- a/test/makeProcessors.js +++ b/test/makeProcessors.js @@ -42,9 +42,9 @@ describe('processors', () => { assert(includes(extensions, '.graphql')); }); - it('should escape backticks and prepend internalTag', () => { - const query = 'query { someValueWith` }'; - const expected = 'ESLintPluginGraphQLFile`query { someValueWith\\` }`'; + it('should wrap with backticks, escape properly and prepend internalTag', () => { + const query = 'query { search(q: "` \\n ${}") { title } }'; + const expected = 'ESLintPluginGraphQLFile`query { search(q: "\\` \\\\n \\${}") { title } }`'; const preprocess = processors['.gql'].preprocess; const result = preprocess(query);