tree-sitter / tree-sitter/node-tree-sitter
reinterpretation of a JS value as wrapped C++ object leads to seg faults
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 876
- Forks
- 172
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Several native methods reinterpret a JavaScript value as a wrapped C++ object and then dereference the result without checking it. These methods can be reached from ordinary JavaScript with a receiver/argument of the wrong shape, causing a hard crash (SIGSEGV, exit 139).
Environment
- Package:
tree-sitter(confirmed against currentmaster, v0.25.1) - Node: v24.21.0
- node-addon-api: ^8.5.0
- OS: Linux x64
Example programs
const Parser = require('tree-sitter');
const JavaScript = require('tree-sitter-javascript');
const { LookaheadIterator } = Parser;
const parser = new Parser();
parser.setLanguage(JavaScript);
const tree = parser.parse('1');
const desc = Object.getOwnPropertyDescriptor(LookaheadIterator.prototype, 'currentType');
desc.get.call(tree); // SIGSEGV
const Parser = require('tree-sitter');
const { SyntaxNode, Tree } = Parser;
const fakeTree = Object.create(Tree.prototype);
SyntaxNode.prototype.toString.call({ tree: fakeTree }); // SIGSEGV
const Parser = require('tree-sitter');
const JavaScript = require('tree-sitter-javascript');
const parser = new Parser();
parser.setLanguage(JavaScript);
const tree = parser.parse('function foo(a, b) { return a + b; } let x = foo(1,2);');
const cursor = tree.walk();
cursor.resetTo(tree); // type confusion
cursor.gotoFirstChild();
cursor.currentNode(); // SIGSEGV / garbage
Each program crashes the process with SIGSEGV (exit 139); (3) is heap-dependent and crashes in the large majority of runs, otherwise returns corrupted cursor state.
Expected behaviour
Reaching any of these with a wrong receiver/argument should raise a catchable TypeError, not crash (or silently corrupt) the host process.
I have a patch ready and will open a PR.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the native implementations behind LookaheadIterator.prototype.currentType, SyntaxNode.prototype.toString, and the cursor methods resetTo and currentNode. Reproduce the listed wrong-receiver and wrong-argument examples, then verify that each case raises a catchable TypeError without a crash, corrupted state, or exit 139.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, javascript, node.js
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100