Skip to content

Fix TraceStateBuilder.remove corrupting the builder when the same key is removed twice#8613

Draft
thswlsqls wants to merge 1 commit into
open-telemetry:mainfrom
thswlsqls:fix/trace-state-builder-double-remove
Draft

Fix TraceStateBuilder.remove corrupting the builder when the same key is removed twice#8613
thswlsqls wants to merge 1 commit into
open-telemetry:mainfrom
thswlsqls:fix/trace-state-builder-double-remove

Conversation

@thswlsqls

Copy link
Copy Markdown
Contributor

Fixes #8612

Description

  • ArrayBasedTraceStateBuilder.remove() decremented numEntries without checking whether the value was already null, so removing a key twice drove the counter below the real count.
  • build() trusts numEntries in three places, so the drift leaks a {a=null} entry, silently drops live entries, or throws ArrayIndexOutOfBoundsException.
  • Mirrors the sibling put() (same class, line 74-78), which already does this check; first removal is unchanged.
  • No in-repo caller, but TraceStateBuilder is stable public API for external instrumentation and vendor propagators. The silent data loss contradicts the no-op contract of the remove(String) Javadoc ("if it is present") and of removeNotPresent(), and is reachable via reuseBuilder().
  • Same defect shape as Fix PooledHashMap dropping live entries when an entry is removed during forEach #8499 (PooledHashMap dropping live entries).

Testing done

  • Added TraceStateTest#removeTwice, #removeTwice_KeepsRemainingEntry, #removeTwice_KeepsRemainingEntries for one, two, and three entries. All three fail without the fix; 41 pass with it.
  • ./gradlew :api:all:check — passed, 504 tests.
  • No signature change (package-private class): apidiff unchanged.
  • CHANGELOG.md ## Unreleased### API entry added.

@thswlsqls
thswlsqls force-pushed the fix/trace-state-builder-double-remove branch from 184a512 to 0b8dc2f Compare July 16, 2026 21:00
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.63%. Comparing base (63ebd94) to head (0b8dc2f).

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #8613   +/-   ##
=========================================
  Coverage     91.63%   91.63%           
- Complexity    10326    10327    +1     
=========================================
  Files          1013     1013           
  Lines         27295    27296    +1     
  Branches       3205     3206    +1     
=========================================
+ Hits          25011    25013    +2     
  Misses         1558     1558           
+ Partials        726      725    -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.

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.

TraceStateBuilder.remove corrupts the builder when the same key is removed twice

1 participant