yihui504 opened a new issue, #6087:
URL: https://github.com/apache/couchdb/issues/6087

   ### Version
   
   3.5.1
   
   ### Describe the problem you're encountering
   
   
   `GET /testdb/_changes?limit=abc` returns HTTP **500** with an unhandled 
Erlang `badarg`:
   
   ```json
   {"error":"unknown_error","reason":"badarg","ref":3761585293}
   ```
   
   The same invalid input on `_all_docs` returns a clean HTTP **400**:
   
   ```json
   {"error":"query_parse_error","reason":"Invalid value for integer: \"abc\""}
   ```
   
   So `_changes` leaks an unhandled server exception (plus a stack-hash `ref`) 
for what `_all_docs` handles as a normal client error. `limit=1.5` (float) 
produces the same 500 `badarg`.
   
   
   ### Expected Behaviour
   
   
   Return HTTP 400 `query_parse_error` for non-numeric `limit`, consistent with 
`_all_docs`.
   
   
   ### Steps to Reproduce
   
   
   ```bash
   docker run -d -p 5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=admin 
--name couchdb-t couchdb:3.5
   curl -s -X POST http://admin:admin@localhost:5984/_cluster_setup -H 
"Content-Type: application/json" \
     -d 
'{"action":"enable_single_node","bind_address":"0.0.0.0","port":5984,"singlenode":true}'
   curl -s -X PUT http://admin:admin@localhost:5984/testdb
   curl -s -X POST http://admin:admin@localhost:5984/testdb/_bulk_docs -H 
"Content-Type: application/json" \
     -d '{"docs":[{"_id":"d1","v":1}]}'
   
   # _changes: 500 (bug)
   curl -i "http://admin:admin@localhost:5984/testdb/_changes?limit=abc";
   # HTTP/1.1 500 Internal Server Error
   # {"error":"unknown_error","reason":"badarg","ref":...}
   
   curl -i "http://admin:admin@localhost:5984/testdb/_changes?limit=1.5";
   # HTTP/1.1 500 Internal Server Error (same badarg)
   
   # _all_docs: 400 (expected)
   curl -i "http://admin:admin@localhost:5984/testdb/_all_docs?limit=abc";
   # HTTP/1.1 400 Bad Request
   # {"error":"query_parse_error","reason":"Invalid value for integer: \"abc\""}
   ```
   
   
   ### Your Environment
   
   
   - CouchDB 3.4.3 and 3.5.1/3.5.2 (official Docker images `couchdb:3.4` and 
`couchdb:3.5`)
   - Single-node setup (`_cluster_setup enable_single_node`)
   - OS: Windows 11 host, Docker Desktop
   
   
   ### Additional Context
   
   ## Root cause (source)
   
   `src/chttpd/src/chttpd_db.erl`, `parse_changes_query/1` 
([3.5.0](https://github.com/apache/couchdb/blob/3.5.0/src/chttpd/src/chttpd_db.erl),
 line 2098):
   
   ```erlang
   {"limit", _} ->
       Args#changes_args{limit = list_to_integer(Value)};   %% bare call, NO 
try/catch
   ```
   
   The very next parameter, `timeout` (line 2104), wraps the same call:
   
   ```erlang
   {"timeout", _} ->
       try list_to_integer(Value) of ...                     %% has try/catch
   ```
   
   So `limit` is the only integer parameter in `parse_changes_query` parsed 
without a `try` guard, which is why `list_to_integer("abc")` raises uncaught 
`badarg` → HTTP 500. The fix is to wrap `limit` in the same `try` block used 
for `timeout`.
   
   `list_to_integer/1` is an Erlang BIF; its `"abc" -> badarg` behaviour is 
OTP-version-independent. `diff` of `parse_changes_query` between the 3.4.3 and 
3.5.0 tags exits 0 (byte-identical).
   
   ## Related prior fix
   
   [COUCHDB-2375](https://issues.apache.org/jira/browse/COUCHDB-2375) — same 
class of "invalid query parameter → HTTP 500 instead of 400" bug, for the `rev` 
parameter on PUT. Resolved as **Fixed**. This is the same pattern on 
`_changes?limit=`.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to