Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion enterprise/e2e/html/hurl/mcp-2025-11-25-resources.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jsonpath "$.result.resources[20].uri" == "{{base}}/self/v1/schemas/api/schemas/s
jsonpath "$.result.resources[20].name" == "rpc"
jsonpath "$.result.resources[20].description" == "Search for schemas in the catalog by query term"
jsonpath "$.result.resources[20].mimeType" == "application/schema+json"
jsonpath "$.result.resources[20].size" == 1120
jsonpath "$.result.resources[20].size" == 1166
jsonpath "$.result.resources[21].uri" == "{{base}}/self/v1/schemas/api/schemas/stats/response"
jsonpath "$.result.resources[21].name" == "response"
jsonpath "$.result.resources[21].description" == "The response format for the schema statistics API endpoint"
Expand Down
108 changes: 108 additions & 0 deletions enterprise/e2e/html/hurl/mcp-2025-11-25-search_schemas.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -964,3 +964,111 @@ POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
HTTP 200
[Asserts]
jsonpath "$.valid" == true

# An empty query is rejected.
POST {{base}}/self/v1/mcp
MCP-Protocol-Version: 2025-11-25
Content-Type: application/json
```
{
"jsonrpc": "2.0",
"id": 1140,
"method": "tools/call",
"params": {
"name": "search_schemas",
"arguments": { "q": "" }
}
}
```
HTTP 200
Content-Type: application/json
Access-Control-Allow-Origin: {{base}}
Link: </self/v1/schemas/mcp/response>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.jsonrpc" == "2.0"
jsonpath "$.id" == 1140
jsonpath "$.error.code" == -32602
jsonpath "$.error.message" == "Invalid params"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
[Asserts]
jsonpath "$.valid" == true

# A whitespace-only query is rejected.
POST {{base}}/self/v1/mcp
MCP-Protocol-Version: 2025-11-25
Content-Type: application/json
```
{
"jsonrpc": "2.0",
"id": 1141,
"method": "tools/call",
"params": {
"name": "search_schemas",
"arguments": { "q": " " }
}
}
```
HTTP 200
Content-Type: application/json
Access-Control-Allow-Origin: {{base}}
Link: </self/v1/schemas/mcp/response>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.jsonrpc" == "2.0"
jsonpath "$.id" == 1141
jsonpath "$.error.code" == -32602
jsonpath "$.error.message" == "Invalid params"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
[Asserts]
jsonpath "$.valid" == true

# Tabs, newlines, and other whitespace characters are also rejected.
POST {{base}}/self/v1/mcp
MCP-Protocol-Version: 2025-11-25
Content-Type: application/json
```
{
"jsonrpc": "2.0",
"id": 1142,
"method": "tools/call",
"params": {
"name": "search_schemas",
"arguments": { "q": "\t\n\r " }
}
}
```
HTTP 200
Content-Type: application/json
Access-Control-Allow-Origin: {{base}}
Link: </self/v1/schemas/mcp/response>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.jsonrpc" == "2.0"
jsonpath "$.id" == 1142
jsonpath "$.error.code" == -32602
jsonpath "$.error.message" == "Invalid params"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
[Asserts]
jsonpath "$.valid" == true
2 changes: 1 addition & 1 deletion enterprise/e2e/path/hurl/mcp-2025-11-25-resources.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jsonpath "$.result.resources[20].uri" == "{{base}}/v1/catalog/self/v1/schemas/ap
jsonpath "$.result.resources[20].name" == "rpc"
jsonpath "$.result.resources[20].description" == "Search for schemas in the catalog by query term"
jsonpath "$.result.resources[20].mimeType" == "application/schema+json"
jsonpath "$.result.resources[20].size" == 1131
jsonpath "$.result.resources[20].size" == 1177
jsonpath "$.result.resources[21].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/stats/response"
jsonpath "$.result.resources[21].name" == "response"
jsonpath "$.result.resources[21].description" == "The response format for the schema statistics API endpoint"
Expand Down
36 changes: 36 additions & 0 deletions enterprise/e2e/path/hurl/mcp-2025-11-25-search_schemas.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,39 @@ POST {{base}}/v1/catalog/self/v1/api/schemas/evaluate{{schema_path}}
HTTP 200
[Asserts]
jsonpath "$.valid" == true

# A whitespace-only query is rejected.
POST {{base}}/v1/catalog/self/v1/mcp
MCP-Protocol-Version: 2025-11-25
Content-Type: application/json
```
{
"jsonrpc": "2.0",
"id": 1203,
"method": "tools/call",
"params": {
"name": "search_schemas",
"arguments": { "q": " " }
}
}
```
HTTP 200
Content-Type: application/json
Access-Control-Allow-Origin: {{base}}
Link: </v1/catalog/self/v1/schemas/mcp/response>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "</v1/catalog([^>]+)>"
[Asserts]
jsonpath "$.jsonrpc" == "2.0"
jsonpath "$.id" == 1203
jsonpath "$.error.code" == -32602
jsonpath "$.error.message" == "Invalid params"

POST {{base}}/v1/catalog/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
[Asserts]
jsonpath "$.valid" == true
9 changes: 9 additions & 0 deletions src/actions/action_schema_search_v1.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ class ActionSchemaSearch_v1 : public sourcemeta::one::RouterAction {
return;
}

if (query.find_first_not_of(" \t\n\r\f\v") == std::string_view::npos) {
sourcemeta::one::json_error(
request, response, sourcemeta::one::STATUS_BAD_REQUEST,
"invalid-search-query",
"The search query must contain at least one non-whitespace character",
this->error_schema_);
return;
}

constexpr std::size_t MAXIMUM_QUERY_LENGTH{256};
if (query.size() > MAXIMUM_QUERY_LENGTH) {
sourcemeta::one::json_error(
Expand Down
4 changes: 3 additions & 1 deletion src/self/v1/schemas/api/schemas/search/rpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"q": {
"description": "Case-insensitive substring to search for",
"type": "string",
"maxLength": 256
"pattern": "\\S",
"maxLength": 256,
"minLength": 1
Copy link
Copy Markdown

@augmentcode augmentcode Bot May 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minLength: 1 blocks the empty string, but it still allows whitespace-only queries (e.g. " ") which are often effectively empty after trimming; if the intent is to forbid "empty" queries in that broader sense, schema validation alone may not fully enforce it.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

},
"limit": {
"description": "Maximum number of results to return",
Expand Down
44 changes: 44 additions & 0 deletions test/e2e/headless/hurl/schemas-search.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,50 @@ Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

GET {{base}}/self/v1/api/schemas/search?q=%20%20%20
HTTP 400
Content-Type: application/problem+json
Access-Control-Allow-Origin: *
Link: </self/v1/schemas/api/error>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.status" == 400
jsonpath "$.title" == "sourcemeta:one/invalid-search-query"
jsonpath "$.detail" == "The search query must contain at least one non-whitespace character"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

GET {{base}}/self/v1/api/schemas/search?q=%09%0A%0D
HTTP 400
Content-Type: application/problem+json
Access-Control-Allow-Origin: *
Link: </self/v1/schemas/api/error>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.status" == 400
jsonpath "$.title" == "sourcemeta:one/invalid-search-query"
jsonpath "$.detail" == "The search query must contain at least one non-whitespace character"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

POST {{base}}/self/v1/api/schemas/search?q=foo
HTTP 405
Content-Type: application/problem+json
Expand Down
44 changes: 44 additions & 0 deletions test/e2e/html/hurl/schemas-search.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,50 @@ Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

GET {{base}}/self/v1/api/schemas/search?q=%20%20%20
HTTP 400
Content-Type: application/problem+json
Access-Control-Allow-Origin: *
Link: </self/v1/schemas/api/error>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.status" == 400
jsonpath "$.title" == "sourcemeta:one/invalid-search-query"
jsonpath "$.detail" == "The search query must contain at least one non-whitespace character"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

GET {{base}}/self/v1/api/schemas/search?q=%09%0A%0D
HTTP 400
Content-Type: application/problem+json
Access-Control-Allow-Origin: *
Link: </self/v1/schemas/api/error>; rel="describedby"
[Captures]
last_response: body
schema_path: header "Link" regex "<([^>]+)>"
[Asserts]
jsonpath "$.status" == 400
jsonpath "$.title" == "sourcemeta:one/invalid-search-query"
jsonpath "$.detail" == "The search query must contain at least one non-whitespace character"

POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}}
```
{{last_response}}
```
HTTP 200
Link: </self/v1/schemas/api/schemas/evaluate/response>; rel="describedby"
[Asserts]
jsonpath "$.valid" == true

POST {{base}}/self/v1/api/schemas/search?q=foo
HTTP 405
Content-Type: application/problem+json
Expand Down
9 changes: 9 additions & 0 deletions test/e2e/path/hurl/search.all.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,12 @@ Content-Type: application/problem+json
Access-Control-Allow-Origin: *
[Asserts]
jsonpath "$.status" == 400

GET {{base}}/v1/catalog/self/v1/api/schemas/search?q=%20%20%20
HTTP 400
Content-Type: application/problem+json
Access-Control-Allow-Origin: *
[Asserts]
jsonpath "$.status" == 400
jsonpath "$.title" == "sourcemeta:one/invalid-search-query"
jsonpath "$.detail" == "The search query must contain at least one non-whitespace character"
Loading