8000 Fix CLI cell lists dropping cells near the end of the input by unknownhackerworld · Pull Request #1276 · uber/h3 · GitHub
[go: up one dir, main page]

Skip to content
8000

Fix CLI cell lists dropping cells near the end of the input - #1276

Open
unknownhackerworld wants to merge 1 commit into
uber:masterfrom
unknownhackerworld:fix/cli-cells-near-end
Open

unknownhackerworld wants to merge 1 commit into
uber:masterfrom
unknownhackerworld:fix/cli-cells-near-end

Conversation

@unknownhackerworld
Copy link
Copy Markdown

Summary

The compactCells, uncompactCells and cellsToMultiPolygon CLI subcommands silently drop cells in two cases:

  1. A --cells list is read with %1500c into a 1501 byte buffer, but the help text says it takes "Up to 100 cells". 100 cells separated by , take 1598 characters, so everything after character 1500 is cut off with no error.
  2. readCellsFromFile only scans up to BUFFER_SIZE_LESS_CELL (1485) in every chunk, including the last one. A cell that starts in the last 15 bytes of the input is never read. This affects the -c string (which has no following chunk) and the final chunk of a file or stdin at EOF when that chunk fills the buffer.

Root cause

src/apps/filters/h3.c:

  • compactCells, uncompactCells and cellsToMultiPolygon declare char cellStrs[BUFFER_SIZE_WITH_NULL] with .scanFormat = "%1500c". The size was shared with the file read buffer, but a -c list of 100 cells needs 100 * 15 + 99 * 2 = 1698 characters.
  • In readCellsFromFile, the inner loop is while (bufferOffset < BUFFER_SIZE_LESS_CELL). Holding back the last 15 bytes is right when more of the file follows, since a cell split across reads gets carried over and reassembled. But when fp == NULL, the loop runs once and stops. And at EOF, the do { ... } while (bytesRead > 0) loop exits after the carried-over tail was moved to the front of the buffer, so the tail is never scanned.

Two branches in the function could not run: the cell == 0 && bufferOffset == BUFFER_SIZE reset (the loop condition stops at 1485), and the fp == NULL branch around fread (the fp == NULL case never reaches it). This PR removes both.

Fix

  • Add CELL_LIST_ARG_SIZE_WITH_NULL (1701) and use it with %1700c for the -c buffers in the three subcommands. 1700 leaves room for 100 cells with , separators.
  • In readCellsFromFile, track whether the current chunk is the last one:
    • When fp == NULL, the buffer is a NUL-terminated string. It is scanned to strlen(buffer) and the loop ends.
    • When reading a file, chunks that more data follows are still scanned to 1485. When fread returns 0, the carried-over tail is scanned one last time up to tailLen.
  • Update the function comment and add a CHANGELOG entry under Unreleased / Fixed.

Tradeoffs and alternatives

  • I kept the fixed-size -c buffer and only made it large enough for the documented 100 cells. Allocating it dynamically would remove the limit, but parseArgs scans into a fixed buffer through scanFormat, so that would be a larger change to the arg parser.
  • An alternative for the tail bug was to always scan to the end of the data and skip the carry-over step. That would break cells split across file reads, which the carry-over exists to handle.
  • A -c list longer than 1700 characters is still cut off silently, same as before for lists longer than 1500. Raising an error there seemed out of scope.

Testing

New CLI tests in tests/cli/uncompactCells.txt with two new input files:

  • tests/inputfiles/uncompact_test4.txt: 100 resolution 1 cells separated by , (1698 characters plus a newline).
  • tests/inputfiles/uncompact_test5.txt: exactly 1500 bytes of newline separated cells with no trailing newline, so the last cell starts at offset 1485.

Results with uncompactCells -r 1 ... -f newline | wc -l:

Input master (28d83cd) this PR
-c "$(cat uncompact_test4.txt)" 88 100
-i uncompact_test5.txt 92 93
-i -- < uncompact_test5.txt 92 93

The new tests fail on master and pass with this change. All 322 ctest tests pass locally, and clang-format 14 reports no changes.

AI disclosure: this change was found, written and tested with help from an AI assistant.

Copilot AI balanced review requested due to automatic review settings October 20, 2026 09:06
Copilot AI left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai
coderabbitai Bot commented Oct 20, 2026 •
Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: db69f911-37fe-43a0-8c54-2115c1badeaf
Commits

Reviewing files that changed from the base of the PR and between 7cecbb5 and 7f8e848.

Files selected for processing: 2
  • CHANGELOG.md
  • src/apps/filters/h3.c
Files skipped from review as they are similar to previous changes: 1
  • CHANGELOG.md

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

Walkthrough

The CLI cell-list buffer limit increased to 1,700 characters. The input reader now scans final data through its actual length and processes the carried-over tail at EOF. Tests cover argument, file, and stdin input.

Changes

Cell-list parsing

Layer / File(s) Summary
Expand CLI cell-list capacity
src/apps/filters/h3.c
The compactCells, uncompactCells, and cellsToMultiPolygon commands now use a shared 1,701-byte buffer and scan up to 1,700 characters.
Scan input through its final cell
src/apps/filters/h3.c, tests/cli/uncompactCells.txt, tests/inputfiles/uncompact_test4.txt, tests/inputfiles/uncompact_test5.txt, CHANGELOG.md
readCellsFromFile preserves split cells across streamed chunks and scans the final tail at EOF. CLI tests cover 100-cell argument input and file and stdin input where the final cell falls within the last 15 bytes. The changelog records the correction.

Priority: Low

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

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: Minimal · up to 7f8e8

The changed CLI paths cover the reported 100-cell and trailing-file-cell cases. No issue identified here needs resolution before merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 … 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 names the main change: the CLI subcommands (compactCells, uncompactCells, cellsToMultiPolygon) no longer drop cells near the end of the input. The changeset adds a larger --cells buffer and …
Description check Passed The description states the problem (cells dropped by the --cells buffer limit and by the readCellsFromFile tail handling), the root cause, the fix (new 1701-byte buffer with %1700c, strlen-based scan …
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: Title check

Explanation

The title names the main change: the CLI subcommands (compactCells, uncompactCells, cellsToMultiPolygon) no longer drop cells near the end of the input. The changeset adds a larger --cells buffer and fixes readCellsFromFile so the carried-over tail is scanned, which matches the title.

Full details: Description check

Explanation

The description states the problem (cells dropped by the --cells buffer limit and by the readCellsFromFile tail handling), the root cause, the fix (new 1701-byte buffer with %1700c, strlen-based scan for strings, tail scan at EOF), tradeoffs, and test results. It matches the changeset, which includes h3.c, the CHANGELOG entry, and the new CLI tests and input files.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 unsupported.)

Resolution

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

Finishing Touches
🧪 Generate unit tests (beta)
  • 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.

@CLAassistant
CLAassistant commented Oct 20, 2026 •
Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 99.758%. remained the same — unknownhackerworld:fix/cli-cells-near-end into uber:master

Signed-off-by: Allen Joseph G <63872540+unknownhackerworld@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

4 participants

0