Browse Source

fix(core): Fix default search handling of mysql binary operators

Fixes #1808
Michael Bromley 3 years ago
parent
commit
c133cce036

+ 21 - 19
packages/core/e2e/default-search-plugin.e2e-spec.ts

@@ -1670,36 +1670,38 @@ describe('Default search plugin', () => {
 
         // https://github.com/vendure-ecommerce/vendure/issues/1789
         describe('input escaping', () => {
-            it('correctly escapes "a & b"', async () => {
-                const result = await adminClient.query<SearchProductsShop.Query, SearchProductShopVariables>(
+            function search(term: string) {
+                return adminClient.query<SearchProductsShop.Query, SearchProductShopVariables>(
                     SEARCH_PRODUCTS,
                     {
-                        input: {
-                            take: 10,
-                            term: 'laptop & camera',
-                        },
+                        input: { take: 10, term },
                     },
                     {
-                        languageCode: LanguageCode.de,
+                        languageCode: LanguageCode.en,
                     },
                 );
+            }
+            it('correctly escapes "a & b"', async () => {
+                const result = await search('laptop & camera');
                 expect(result.search.items).toBeDefined();
             });
+
             it('correctly escapes other special chars', async () => {
-                const result = await adminClient.query<SearchProductsShop.Query, SearchProductShopVariables>(
-                    SEARCH_PRODUCTS,
-                    {
-                        input: {
-                            take: 10,
-                            term: 'a : b ? * (c) ! "foo"',
-                        },
-                    },
-                    {
-                        languageCode: LanguageCode.de,
-                    },
-                );
+                const result = await search('a : b ? * (c) ! "foo"');
                 expect(result.search.items).toBeDefined();
             });
+
+            it('correctly escapes mysql binary mode chars', async () => {
+                expect((await search('foo+')).search.items).toBeDefined();
+                expect((await search('foo-')).search.items).toBeDefined();
+                expect((await search('foo<')).search.items).toBeDefined();
+                expect((await search('foo>')).search.items).toBeDefined();
+                expect((await search('foo*')).search.items).toBeDefined();
+                expect((await search('foo~')).search.items).toBeDefined();
+                expect((await search('foo@bar')).search.items).toBeDefined();
+                expect((await search('foo + - *')).search.items).toBeDefined();
+                expect((await search('foo + - bar')).search.items).toBeDefined();
+            });
         });
     });
 });

+ 6 - 1
packages/core/src/plugin/default-search-plugin/search-strategy/mysql-search-strategy.ts

@@ -149,7 +149,12 @@ export class MysqlSearchStrategy implements SearchStrategy {
             input;
 
         if (term && term.length > this.minTermLength) {
-            const safeTerm = term.replace(/"/g, '');
+            const safeTerm = term
+                .replace(/"/g, '')
+                .replace(/@/g, ' ')
+                .trim()
+                .replace(/[+\-*~<>]/g, ' ')
+                .trim();
             const termScoreQuery = this.connection
                 .getRepository(ctx, SearchIndexItem)
                 .createQueryBuilder('si_inner')