Page MenuHomePhabricator

D21106.diff
No OneTemporary

D21106.diff

diff --git a/src/applications/search/compiler/PhutilSearchQueryCompiler.php b/src/applications/search/compiler/PhutilSearchQueryCompiler.php
--- a/src/applications/search/compiler/PhutilSearchQueryCompiler.php
+++ b/src/applications/search/compiler/PhutilSearchQueryCompiler.php
@@ -243,34 +243,26 @@
'Query contains unmatched double quotes.'));
}
- if ($mode == 'operator') {
- throw new PhutilSearchQueryCompilerSyntaxException(
- pht(
- 'Query contains operator ("%s") with no search term.',
- implode('', $current_operator)));
- }
+ // If the input query has trailing space, like "a b ", we may exit the
+ // parser without a final token.
+ if ($current_function !== null || $current_operator || $current_token) {
+ $token = array(
+ 'operator' => $current_operator,
+ 'quoted' => false,
+ 'value' => $current_token,
+ );
- $token = array(
- 'operator' => $current_operator,
- 'quoted' => false,
- 'value' => $current_token,
- );
+ if ($enable_functions) {
+ $token['function'] = $current_function;
+ }
- if ($enable_functions) {
- $token['function'] = $current_function;
+ $tokens[] = $token;
}
- $tokens[] = $token;
-
$results = array();
foreach ($tokens as $token) {
$value = implode('', $token['value']);
$operator_string = implode('', $token['operator']);
-
- if (!strlen($value)) {
- continue;
- }
-
$is_quoted = $token['quoted'];
switch ($operator_string) {
@@ -304,6 +296,24 @@
$operator_string));
}
+ if (!strlen($value)) {
+ $require_value = $is_quoted;
+
+ switch ($operator) {
+ default:
+ $require_value = true;
+ break;
+ }
+
+ if ($require_value) {
+ throw new PhutilSearchQueryCompilerSyntaxException(
+ pht(
+ 'Query contains a token ("%s") with no search term. Query '.
+ 'tokens specify text to search for.',
+ $this->getDisplayToken($token)));
+ }
+ }
+
$result = array(
'operator' => $operator,
'quoted' => $is_quoted,
@@ -371,4 +381,23 @@
return $open_quote.$value.$close_quote;
}
+ private function getDisplayToken(array $token) {
+ if (isset($token['function'])) {
+ $function = $token['function'].':';
+ } else {
+ $function = '';
+ }
+
+ $operator_string = implode('', $token['operator']);
+
+ $value = implode('', $token['value']);
+
+ $is_quoted = $token['quoted'];
+ if ($is_quoted) {
+ $value = $this->quoteToken($value);
+ }
+
+ return sprintf('%s%s%s', $function, $operator_string, $value);
+ }
+
}
diff --git a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
--- a/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
+++ b/src/applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php
@@ -36,6 +36,13 @@
'"cat' => false,
'A"' => false,
'A"B"' => '+"A" +"B"',
+
+ // Trailing whitespace should be discarded.
+ 'a b ' => '+"a" +"b"',
+
+ // Functions must have search text.
+ '""' => false,
+ '-' => false,
);
$this->assertCompileQueries($tests);
@@ -56,7 +63,6 @@
'cat -dog' => '+[cat] -[dog]',
);
$this->assertCompileQueries($quote_tests, '+ -><()~*:[]&|');
-
}
public function testCompileQueriesWithStemming() {
@@ -133,6 +139,9 @@
'"'.$mao.'"' => array(
array(null, $op_and, $mao),
),
+ 'title:' => false,
+ 'title:+' => false,
+ 'title:+""' => false,
);
$this->assertCompileFunctionQueries($function_tests);
@@ -199,15 +208,19 @@
$compiler = id(new PhutilSearchQueryCompiler())
->setEnableFunctions(true);
- $tokens = $compiler->newTokens($input);
+ try {
+ $tokens = $compiler->newTokens($input);
- $result = array();
- foreach ($tokens as $token) {
- $result[] = array(
- $token->getFunction(),
- $token->getOperator(),
- $token->getValue(),
- );
+ $result = array();
+ foreach ($tokens as $token) {
+ $result[] = array(
+ $token->getFunction(),
+ $token->getOperator(),
+ $token->getValue(),
+ );
+ }
+ } catch (PhutilSearchQueryCompilerSyntaxException $ex) {
+ $result = false;
}
$this->assertEqual(

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 5:50 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6285202
Default Alt Text
D21106.diff (4 KB)

Event Timeline