Mercurial Hosting > luan
diff src/goodjava/queryparser/SaneQueryParser.java @ 1422:e48290f3d9fb
better quoting
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 17 Nov 2019 16:28:51 -0700 |
parents | 27efb1fcbcb5 |
children |
line wrap: on
line diff
--- a/src/goodjava/queryparser/SaneQueryParser.java Sat Oct 26 22:28:46 2019 -0600 +++ b/src/goodjava/queryparser/SaneQueryParser.java Sun Nov 17 16:28:51 2019 -0700 @@ -19,10 +19,15 @@ return new SaneQueryParser(fieldParser,query).parseQuery(); } - private static Pattern specialChar = Pattern.compile("[ \\t\\r\\n\":\\[\\]{}^+\\-(),?*\\\\]"); - - public static String literal(String s) { - return specialChar.matcher(s).replaceAll("\\\\$0"); + public static String quote(String s) { + s = s.replace("\\","\\\\"); + s = s.replace("\b","\\b"); + s = s.replace("\f","\\f"); + s = s.replace("\n","\\n"); + s = s.replace("\r","\\r"); + s = s.replace("\t","\\t"); + s = s.replace("\"","\\\""); + return "\""+s+"\""; } public static Sort parseSort(FieldParser fieldParser,String sort) throws ParseException { @@ -167,20 +172,9 @@ private String SimpleTerm(String exclude) throws ParseException { parser.begin(); - String match; - if( parser.match('"') ) { - int start = parser.currentIndex() - 1; - while( !parser.match('"') ) { - if( parser.endOfInput() ) - throw exception("unclosed quotes"); - parser.anyChar(); - checkEscape(); - } - match = parser.textFrom(start); - Spaces(); - } else { + String match = Quoted(); + if( match==null ) match = Unquoted(exclude); - } if( match.length() == 0 ) throw exception("invalid input"); return parser.success(match); @@ -204,6 +198,67 @@ return parser.success(match); } + private String Quoted() throws ParseException { + parser.begin(); + if( !parser.match('"') ) + return parser.failure(null); + StringBuilder sb = new StringBuilder(); + while( parser.anyChar() ) { + char c = parser.lastChar(); + switch(c) { + case '"': + return parser.success(sb.toString()); + case '\\': + if( parser.anyChar() ) { + c = parser.lastChar(); + switch(c) { + case '"': + case '\\': + sb.append(c); + continue; + case 'b': + sb.append('\b'); + continue; + case 'f': + sb.append('\f'); + continue; + case 'n': + sb.append('\n'); + continue; + case 'r': + sb.append('\r'); + continue; + case 't': + sb.append('\t'); + continue; + case 'u': + int n = 0; + for( int i=0; i<4; i++ ) { + int d; + if( parser.inCharRange('0','9') ) { + d = parser.lastChar() - '0'; + } else if( parser.inCharRange('a','f') ) { + d = parser.lastChar() - 'a' + 10; + } else if( parser.inCharRange('A','F') ) { + d = parser.lastChar() - 'A' + 10; + } else { + throw exception("invalid hex digit"); + } + n = 16*n + d; + } + sb.append((char)n); + continue; + } + } + throw exception("invalid escape char"); + default: + sb.append(c); + } + } + parser.failure(); + throw exception("unclosed string"); + } + private String Unquoted(String exclude) throws ParseException { int start = parser.begin(); while( parser.noneOf(exclude) ) {