localStorage: a malformed backing file aborts the process via CHECK
还没有人认领这个 Issue。
- 主要语言
- JavaScript
- 星标
- 122k
- 派生
- 37.4k
- 平均合并
- 4 天 3 小时
- 30 天内合并 PR
- 272
描述
Version
v27.0.0-pre (9f7ae86d8b5)
Platform
Darwin 25.6.0 arm64
Subsystem
webstorage, sqlite
What steps will reproduce the bug?
src/node_webstorage.cc asserts the SQLite type of every column it reads, but the backing file is a user-specified path. Node's own tables are STRICT, but the DDL is CREATE TABLE IF NOT EXISTS, so a file that already contains tables of those names is adopted as-is, STRICT or not.
// craft.cjs
const { DatabaseSync } = require('node:sqlite');
const out = '/tmp/ws.db';
for (const s of ['', '-wal', '-shm']) require('node:fs').rmSync(out + s, { force: true });
// Node's schema, minus STRICT. BLOB has no affinity, so a TEXT value stays TEXT.
const db = new DatabaseSync(out);
db.exec(`
CREATE TABLE nodejs_webstorage(
key BLOB NOT NULL, value BLOB NOT NULL, PRIMARY KEY(key));
CREATE TABLE nodejs_webstorage_state(
max_size INTEGER NOT NULL DEFAULT 10485760, total_size INTEGER NOT NULL,
schema_version INTEGER NOT NULL DEFAULT 1,
single_row_ INTEGER NOT NULL DEFAULT 1 CHECK(single_row_ = 1),
PRIMARY KEY(single_row_));
`);
// A real UTF-16LE key, so that lookups still match; only the value is TEXT.
db.prepare('INSERT INTO nodejs_webstorage (key, value) VALUES (?, ?)')
.run(Buffer.from('greeting', 'utf16le'), 'hello');
db.prepare('INSERT INTO nodejs_webstorage_state (total_size, schema_version)' +
' VALUES (0, 1)').run();
db.close();
$ node craft.cjs
$ node --localstorage-file=/tmp/ws.db -e "localStorage.getItem('greeting')"
How often does it reproduce? Is there a required condition?
The only condition is that the file exists with the wrong stored type.
What is the expected behavior? Why is that the expected behavior?
A thrown error.
What do you see instead?
SIGABRT, exit 134:
# node[96447]: MaybeLocal<Value> node::webstorage::Storage::Load(Local<Name>)
# at ../src/node_webstorage.cc:354
# Assertion failed: sqlite3_column_type(stmt.get(), 0) == 4
Additional information
Separately, line 187 re-runs init_sql_v0 and overwrites the result of the sqlite3_prepare_v2() five lines above it, so prepare failures go unreported. Given a nodejs_webstorage_state table with no schema_version column, the real error is replaced by Error: bad parameter or other API misuse.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
阅读 src/node_webstorage.cc 第 187 行和第 354 行附近的代码,然后运行 craft.cjs,接着运行 node --localstorage-file 命令以复现 abort。完成标准是:格式错误的 backing-file 数据会产生一个抛出的错误,而不是 SIGABRT,并且第 187 行附近描述的 prepare 失败会被报告,而不是被后续错误替代。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- javascript, node.js, sqlite
- 领域
- backend, databases
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 活跃
- 描述清晰度
- 描述清楚
- 新手友好度
- 68/100