Skip to content

Backslashes in collections in @Query-annotated methods are not escaped #2326

Closed
@akoessler

Description

@akoessler

Having a repository with a custom method:

    @Query("{\"ids\": {\"values\": ?0 }}")
    Stream<T> findAllByIdStream(Iterable<String> ids);

and calling it with IDs that contain backslashes:

repository.findAllByIdStream(List.of("Test\\id1", "Test\\id2"));

will be translated to this request:

"POST /elastic-testdata/_search?scroll=60000ms&typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512 HTTP/1.1[\r][\n]"
"X-Elastic-Client-Meta: es=7.17.4p,jv=11,t=7.17.4p,hc=4.1.5[\r][\n]"
"Content-Length: 145[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Host: localhost:9200[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: elasticsearch-java/7.17.4-SNAPSHOT (Java/11.0.16.1)[\r][\n]"
"[\r][\n]"
"{"from":0,"size":500,"query":{"wrapper":{"query":"eyJpZHMiOiB7InZhbHVlcyI6IFsiVGVzdFxpZDEiLCJUZXN0XGlkMiJdIH19"}},"version":true,"explain":false}"

with the query decoded being:

{"ids": {"values": ["Test\id1","Test\id2"] }}

resulting in an elastic error:

"HTTP/1.1 400 Bad Request[\r][\n]"
"X-elastic-product: Elasticsearch[\r][\n]"
"content-type: application/json; charset=UTF-8[\r][\n]"
"content-length: 504[\r][\n]"
"[\r][\n]"
"{"error":{"root_cause":[{"type":"parsing_exception","reason":"[1:21] [ids] failed to parse field [values]","line":1,"col":21}],"type":"parsing_exception","reason":"[1:21] [ids] failed to parse field [values]","line":1,"col":21,"caused_by":{"type":"x_content_parse_exception","reason":"[1:21] [ids] failed to parse field [values]","caused_by":{"type":"json_parse_exception","reason":"Unrecognized character escape 'i' (code 105)\n at [Source: (ByteArrayInputStream); line: 1, column: 28]"}}},"status":400}"
HTTP/1.1 400 Bad Request
X-elastic-product: Elasticsearch
content-type: application/json; charset=UTF-8
content-length: 504

The problem here is the backslash!

Executing that same query in elastic directly:

{"query": 
  {"ids": {"values": ["Test\id1","Test\id2"] }}
}

returns:

{
	"error": {
		"root_cause": [
			{
				"type": "parsing_exception",
				"reason": "[3:21] [ids] failed to parse field [values]",
				"line": 3,
				"col": 21
			}
		],
		"type": "parsing_exception",
		"reason": "[3:21] [ids] failed to parse field [values]",
		"line": 3,
		"col": 21,
		"caused_by": {
			"type": "x_content_parse_exception",
			"reason": "[3:21] [ids] failed to parse field [values]",
			"caused_by": {
				"type": "json_parse_exception",
				"reason": "Unrecognized character escape 'i' (code 105)\n at [Source: (org.elasticsearch.common.io.stream.ByteBufferStreamInput); line: 3, column: 28]"
			}
		}
	},
	"status": 400
}

Using escaped backslashes does work:

{"query": 
  {"ids": {"values": ["Test\\id1","Test\\id2"] }}
}

And would return the results:

{
	"took": 4,
	"timed_out": false,
	"_shards": {
		"total": 1,
		"successful": 1,
		"skipped": 0,
		"failed": 0
	},
	"hits": {
		"total": {
			"value": 1,
			"relation": "eq"
		},
		"max_score": 1,
		"hits": [
			{
				"_index": "elastic-testdata",
				"_type": "_doc",
				"_id": "Test\\id1",
				"_score": 1,
				"_source": {
					"_class": "**********",
					"name": "Name1",
					"id": "Test\\id1"
				}
			}
		]
	}
}

Found with spring-boot 2.7.1 (using spring-boot-starter-data-elasticsearch) and still happening at 2.7.4.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions