Skip to content

fix(drivers): handle null and trailing peer data when decoding - #197

Merged
zsltg merged 2 commits into
mainfrom
fix/peer-decode
Oct 27, 2026
Merged

zsltg merged 2 commits into
mainfrom
fix/peer-decode

Conversation

@zsltg

@zsltg zsltg commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

What and why

Two defects in how drivers decode documents that a database server returns. A security audit found both.

  1. Elasticsearch and OpenSearch: a search hit or an mget doc with "_source": null made decodeSource write the _id into a nil map. That panicked. The CLI has no recover, and under iq mcp the whole server process ended. A null _source now gives {"_id": id}, the same as an absent _source.
  2. Couchbase: decodeValue read the first JSON value and ignored the bytes after it. A body like {"a":1}garbage became {"a":1}, so a copy kept a prefix and lost the rest. A body with data after the first value now counts as not JSON and returns as the raw string, which is the documented behavior for a non-JSON body. Trailing whitespace is still allowed.

I checked the sibling decoders:

  • CouchDB decodeDoc can return a nil map for a null document, but no caller writes into it. Its input is one value that kivik already parsed, so it cannot carry trailing bytes.
  • MongoDB decodes BSON through the driver.
  • Redis decodeJSON reads one value from a RedisJSON reply that the server produces. That shape is out of scope here.

Checks

  • make check
  • make cover: left to CI
  • make security: left to CI
  • End-to-end tests: left to CI
  • scripts/mutation-gate.sh: left to CI
  • Tests added: TestDecodeSource/null source still yields the id, TestScanSurvivesANullSource, TestGetSurvivesANullSource, TestDecodeValueTrailingData. With the fix reverted, TestDecodeSource panics and TestDecodeValueTrailingData fails.
  • scripts/capabilities.sh: not needed, go.mod and go.sum did not change
  • Docs: no user-facing behavior is documented for these cases

Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Couchbase values containing trailing or concatenated JSON data are now kept as strings instead of being partially decoded. Valid JSON with trailing whitespace continues to decode normally.
    • Elasticsearch results with a null source are now handled without errors and return a document containing its ID, including in scans and multi-get results.

Elasticsearch search hits and mget docs can carry "_source": null.
The decoder left a nil map and then wrote the _id into it. That
write panicked and ended the process, including the iq mcp server.
A null _source now gives {"_id": id}, the same as no _source.

Couchbase decodeValue read only the first JSON value and ignored
the bytes after it. A body like {"a":1}garbage became {"a":1}, and
a copy lost the rest. Now any body with data after the first value
counts as not JSON and returns as the raw string. Trailing
whitespace is still allowed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Zsolt Gaspar <17578237+zsltg@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between f7f59b8 and 6b30488.

Files selected for processing: 5
  • drivers/couchbase/normalize.go
  • drivers/couchbase/normalize_test.go
  • drivers/elasticsearch/normalize.go
  • drivers/elasticsearch/normalize_test.go
  • drivers/elasticsearch/scan_test.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The Couchbase decoder now rejects trailing JSON data. The Elasticsearch normalizer now handles null _source values by returning documents containing _id. Tests cover both changes.

Changes: Couchbase JSON decoding

Layer / File(s) Summary
Reject trailing JSON data
drivers/couchbase/normalize.go, drivers/couchbase/normalize_test.go
decodeValue returns the full input as a string when data follows the first JSON value. Tests cover malformed and concatenated input, valid objects, and trailing whitespace.

Elasticsearch null source handling

Layer / File(s) Summary
Normalize null _source documents
drivers/elasticsearch/normalize.go, drivers/elasticsearch/normalize_test.go, drivers/elasticsearch/scan_test.go
decodeSource replaces a nil map with an empty map before normalization and _id injection. Tests cover direct decoding, scan results across pages, and mget results.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: codescene-access

Merge Risk: Minimal · previous review 6b304

The decoding changes preserve valid data, avoid truncated Couchbase values, and safely normalize null Elasticsearch sources. No merge-blocking risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title is concise, specific, and accurately summarizes both decoder fixes: handling null values and trailing data.
Description check Passed The description explains the two defects, the intended behavior, scope decisions, and added regression tests. It also reports completed checks and identifies checks left to CI. The required sections a…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the two defects, the intended behavior, scope decisions, and added regression tests. It also reports completed checks and identifies checks left to CI. The required sections are present and sufficiently complete.

Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 6 functions across 5 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zsltg

zsltg commented Oct 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review


Generated by Claude Code

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@zsltg
zsltg marked this pull request as ready for review October 27, 2026 14:37
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.43%. Comparing base (1ef7b63) to head (1081c02).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #197   +/-   ##
=======================================
  Coverage   96.43%   96.43%           
=======================================
  Files         145      145           
  Lines       14559    14563    +4     
=======================================
+ Hits        14040    14044    +4     
  Misses        518      518           
  Partials        1        1           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zsltg
zsltg merged commit 9fd4913 into main Oct 27, 2026
106 of 115 checks passed
@zsltg
zsltg deleted the fix/peer-decode branch October 27, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant