From c62a514caffd350381d6bdef4d2b32a611b61ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 12 Aug 2021 18:39:50 +0200 Subject: [PATCH] Use '\' as escape char for wildcard issue10626 review349031002 (grafted from 67429bcbe92e6c9beeea4e65f84d2dc09d08c2b2) --HG-- branch : 6.0 --- src/common.js | 40 ++++++++++++++++++++++++++++++++++------ tests/sao.js | 2 +- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/common.js b/src/common.js index a49513d87c..e0f1a07543 100644 --- a/src/common.js +++ b/src/common.js @@ -1186,8 +1186,7 @@ name = name.slice(0, -9); } if (!(name in this.fields)) { - escaped = value.replace('%%', '__'); - if (escaped.startsWith('%') && escaped.endsWith('%')) { + if (this.is_full_text(value)) { value = value.slice(1, -1); } return this.quote(value); @@ -1198,16 +1197,15 @@ target = clause[3]; } if (operator.contains('ilike')) { - escaped = value.replace('%%', '__'); - if (escaped.startsWith('%') && escaped.endsWith('%')) { + if (this.is_full_text(value)) { value = value.slice(1, -1); - } else if (!escaped.contains('%')) { + } else if (!this.is_like(value)) { if (operator == 'ilike') { operator = '='; } else { operator = '!'; } - value = value.replace('%%', '%'); + value = this.unescape(value); } } var def_operator = this.default_operator(field); @@ -1843,6 +1841,36 @@ return '%' + value + '%'; } }, + is_full_text: function(value, escape) { + escape = escape || '\\'; + var escaped = value; + while (escaped.charAt(0) == '%') { + escaped = escaped.substring(1); + } + while (escaped.charAt(escaped.length - 1) == '%') { + escaped = escaped.substring(0, escaped.length - 1); + } + escaped = escaped + .replace(escape + '%', '') + .replace(escape + '_', ''); + if (escaped.contains('%') || escaped.contains('_')) { + return false; + } + return value.startsWith('%') && value.endsWith('%'); + }, + is_like: function(value, escape) { + escape = escape || '\\'; + var escaped = value + .replace(escape + '%', '') + .replace(escape + '_', ''); + return escaped.contains('%') || escaped.contains('_'); + }, + unescape: function(value, escape) { + escape = escape || '\\'; + return value + .replace(escape + '%', '%') + .replace(escape + '_', '_'); + }, quote: function(value) { if (typeof value != 'string') { return value; diff --git a/tests/sao.js b/tests/sao.js index 193d51b78e..a05fdbf1a4 100644 --- a/tests/sao.js +++ b/tests/sao.js @@ -2133,7 +2133,7 @@ [[['name', 'ilike', '%<%']], 'Name: "" "<"'], [[['name', 'ilike', 'Doe']], 'Name: =Doe'], [[['name', 'ilike', 'Doe%']], 'Name: Doe%'], - [[['name', 'ilike', 'Doe%%']], 'Name: =Doe%'], + [[['name', 'ilike', 'Doe\\%']], 'Name: =Doe%'], [[['name', 'not ilike', '%Doe%']], 'Name: !Doe'], [[['name', 'in', ['John', 'Jane']]], 'Name: John;Jane'], [[['name', 'not in', ['John', 'Jane']]], 'Name: !John;Jane'],