tree-sitter / tree-sitter/node-tree-sitter

reinterpretation of a JS value as wrapped C++ object leads to seg faults

Open
#290 0 comments 0 reactions 0 assignees View on GitHub

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 current master, 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.