Skip to content

THRIFT-3669: Keep the lib/js TJSONProtocol read stack aligned after empty lists - #4059

Merged
Jens-G merged 1 commit into
apache:masterfrom
Jens-G:THRIFT-3669
Oct 28, 2026
Merged

Jens-G merged 1 commit into
apache:masterfrom
Jens-G:THRIFT-3669

Conversation

@Jens-G

@Jens-G Jens-G commented Oct 28, 2026

Copy link
Copy Markdown
Member

THRIFT-3669

readListEnd in lib/js/src/thrift.js popped a single entry off the read stack before it pushed the next element of the enclosing list. An empty list has no first element and leaves an undefined entry above itself, so after an empty list the single pop left the emptied list on the stack, and the next element went on top of it. From there the elements of the enclosing list were lost or read from the wrong place: [[],[],[1,2]] came back as [[],[],[]]. Sets end through readListEnd and were affected the same way.

readListEnd now pops back to the enclosing container before it pushes the next element, as the Node.js library does since THRIFT-6409 (#4054). readMapEnd already pops back to its saved position, so a map is only affected through the lists it holds.

New QUnit page lib/js/test/test-nested-empty-lists.html, registered in Gruntfile.js with the other pages:

case master this branch
[[],[],[1,2]], [[1],[],[],[2]], [[[1,2],[]],[],[[3]]] elements lost or misplaced read back unchanged
a list of sets [[],[],[5,6]] elements lost read back unchanged
a map with nested-list values {"0":[[],[]],"1":[[7]]} the second key reads as "undefined" read back unchanged
list<list<string>> and list<list<list<string>>> through generated code elements lost read back unchanged

Run as the lib-js CI job does, in thrift:jammy: make -C lib/js check passes with 12 QUnit pages, 189 tests and 763 assertions; jshint passes. On master the new page fails 7 of 7 tests. A comment in container_size_limit.test.js that described the old behaviour is updated.

  • Apache Jira ticket: THRIFT-3669
  • Single commit
  • Code change, so the commit carries no CI-skip marker.

🤖 Generated with Claude Code

…mpty lists

Client: js

readListBegin pushes the first element of a list onto the read stack,
and readListEnd popped a single entry before it pushed the next element
of the enclosing list. After a non-empty list that entry is the list
itself. An empty list has no first element and leaves an undefined
entry above itself, so the single pop left the emptied list on the
stack, and the next element went on top of it. The stack stayed out of
step from there, and the elements of the enclosing list that followed
were lost or read from the wrong place: [[],[],[1,2]] came back as
[[],[],[]]. Sets end through readListEnd and were affected the same
way.

readListEnd now pops back to the enclosing container before it pushes
the next element, as the Node.js library does since THRIFT-6409.

test-nested-empty-lists.html reads nested lists, a list of sets and a
map of nested lists with empty lists before, between and after
non-empty ones, and round-trips list<list<string>> and
list<list<list<string>>> through the code generated from
JsDeepConstructorTest.thrift. Gruntfile.js runs it with the other QUnit
pages. A comment in container_size_limit.test.js that described the old
behaviour is updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jens-G
Jens-G requested a review from emmenlau as a code owner October 28, 2026 09:03
@mergeable mergeable Bot added the javascript Pull requests that update Javascript code label Oct 28, 2026
@Jens-G
Jens-G merged commit b812d84 into apache:master Oct 28, 2026
109 checks passed
@Jens-G
Jens-G deleted the THRIFT-3669 branch October 28, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant