feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,32 @@
{
"name": "@qinglong/local-command-file",
"version": "3.0.0-alpha.0",
"private": true,
"description": "QingLong 3.0 bounded private durable command-file protocol",
"license": "Apache-2.0",
"engines": {
"node": ">=24.18.0 <25"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"files": [
"dist/**/*.js",
"dist/**/*.d.ts"
],
"scripts": {
"build": "tsc -p tsconfig.json",
"check": "node ../../scripts/ql3-build-package-closure.cjs && tsc -p tsconfig.json --noEmit",
"test": "node ../../scripts/ql3-build-package-closure.cjs && node --test test/*.test.cjs"
},
"devDependencies": {
"@types/node": "24.13.3",
"typescript": "5.9.3"
}
}
@@ -0,0 +1,7 @@
export {
MAX_PRIVATE_LOCAL_JSON_FILE_BYTES,
PrivateLocalCommandFileError,
readPrivateLocalCommandFile,
readPrivateLocalJsonFile,
type ReadPrivateLocalJsonFileOptions,
} from './protocol/privateLocalCommandFile';
@@ -0,0 +1,160 @@
import fs from 'node:fs';
import path from 'node:path';
const MAX_COMMAND_FILE_BYTES = 16 * 1024;
export const MAX_PRIVATE_LOCAL_JSON_FILE_BYTES = 1024 * 1024;
const MAX_PATH_BYTES = 4096;
export interface ReadPrivateLocalJsonFileOptions {
readonly maxBytes: number;
}
export class PrivateLocalCommandFileError extends TypeError {
readonly code = 'PRIVATE_LOCAL_COMMAND_FILE_INVALID';
constructor(message: string, readonly cause?: unknown) {
super(`Private local command file is invalid: ${message}`);
this.name = 'PrivateLocalCommandFileError';
}
}
function currentUid(): number {
if (
typeof process.getuid !== 'function' ||
typeof process.geteuid !== 'function'
) {
throw new PrivateLocalCommandFileError(
'POSIX user identity is unavailable',
);
}
const uid = process.getuid();
const effectiveUid = process.geteuid();
if (
!Number.isSafeInteger(uid) ||
uid < 0 ||
!Number.isSafeInteger(effectiveUid) ||
effectiveUid < 0 ||
uid !== effectiveUid
) {
throw new PrivateLocalCommandFileError(
'real and effective POSIX users must match',
);
}
return uid;
}
function commandPath(value: string): string {
if (
typeof value !== 'string' ||
!path.isAbsolute(value) ||
Buffer.byteLength(value) < 1 ||
Buffer.byteLength(value) > MAX_PATH_BYTES ||
value.includes('\0') ||
path.normalize(value) !== value
) {
throw new PrivateLocalCommandFileError(
'path must be normalized, bounded and absolute',
);
}
return value;
}
function readLimit(value: ReadPrivateLocalJsonFileOptions): number {
if (
!value ||
typeof value !== 'object' ||
Array.isArray(value) ||
Object.keys(value).length !== 1 ||
!Number.isSafeInteger(value.maxBytes) ||
value.maxBytes < 1 ||
value.maxBytes > MAX_PRIVATE_LOCAL_JSON_FILE_BYTES
) {
throw new PrivateLocalCommandFileError('read options are invalid');
}
return value.maxBytes;
}
export function readPrivateLocalJsonFile(
candidatePath: string,
options: ReadPrivateLocalJsonFileOptions,
): unknown {
const filePath = commandPath(candidatePath);
const maxBytes = readLimit(options);
const uid = currentUid();
let descriptor: number | undefined;
let material: Buffer | undefined;
try {
const before = fs.lstatSync(filePath, { bigint: true });
if (
!before.isFile() ||
before.isSymbolicLink() ||
Number(before.uid) !== uid ||
(Number(before.mode) & 0o777) !== 0o600 ||
before.size < 1n ||
before.size > BigInt(maxBytes)
) {
throw new PrivateLocalCommandFileError(
'file must be a bounded private regular file',
);
}
descriptor = fs.openSync(
filePath,
fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0),
);
const opened = fs.fstatSync(descriptor, { bigint: true });
if (
!opened.isFile() ||
opened.dev !== before.dev ||
opened.ino !== before.ino ||
opened.size !== before.size ||
Number(opened.uid) !== uid ||
(Number(opened.mode) & 0o777) !== 0o600
) {
throw new PrivateLocalCommandFileError(
'file identity changed while opening',
);
}
material = Buffer.allocUnsafe(Number(opened.size) + 1);
let offset = 0;
while (offset < material.byteLength) {
const bytesRead = fs.readSync(
descriptor,
material,
offset,
material.byteLength - offset,
null,
);
if (bytesRead === 0) break;
offset += bytesRead;
}
const after = fs.fstatSync(descriptor, { bigint: true });
if (
offset !== Number(opened.size) ||
after.dev !== opened.dev ||
after.ino !== opened.ino ||
after.size !== opened.size ||
Number(after.uid) !== uid ||
(Number(after.mode) & 0o777) !== 0o600
) {
throw new PrivateLocalCommandFileError(
'file identity changed while reading',
);
}
material = material.subarray(0, offset);
return JSON.parse(
new TextDecoder('utf-8', { fatal: true }).decode(material),
) as unknown;
} catch (error) {
if (error instanceof PrivateLocalCommandFileError) throw error;
throw new PrivateLocalCommandFileError('file cannot be read', error);
} finally {
material?.fill(0);
if (descriptor !== undefined) fs.closeSync(descriptor);
}
}
export function readPrivateLocalCommandFile(candidatePath: string): unknown {
return readPrivateLocalJsonFile(candidatePath, {
maxBytes: MAX_COMMAND_FILE_BYTES,
});
}
@@ -0,0 +1,93 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { test } = require('node:test');
const {
MAX_PRIVATE_LOCAL_JSON_FILE_BYTES,
PrivateLocalCommandFileError,
readPrivateLocalCommandFile,
readPrivateLocalJsonFile,
} = require('../dist');
function fixture(t, value = { schemaVersion: 1, operation: 'test' }) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-command-file-'));
const filePath = path.join(root, 'command.json');
fs.writeFileSync(filePath, `${JSON.stringify(value)}\n`, { mode: 0o600 });
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
return { root, filePath };
}
test('reads one bounded private JSON intent', (t) => {
const value = { schemaVersion: 1, operation: 'test', mutationId: 'stable' };
const { filePath } = fixture(t, value);
assert.deepEqual(readPrivateLocalCommandFile(filePath), value);
});
test('rejects relative, broad, symlinked, oversized and malformed files', (t) => {
assert.throws(
() => readPrivateLocalCommandFile('command.json'),
PrivateLocalCommandFileError,
);
const broad = fixture(t);
fs.chmodSync(broad.filePath, 0o644);
assert.throws(
() => readPrivateLocalCommandFile(broad.filePath),
PrivateLocalCommandFileError,
);
const linked = fixture(t);
const linkPath = path.join(linked.root, 'link.json');
fs.symlinkSync(linked.filePath, linkPath);
assert.throws(
() => readPrivateLocalCommandFile(linkPath),
PrivateLocalCommandFileError,
);
const oversized = fixture(t);
fs.writeFileSync(oversized.filePath, 'x'.repeat(16 * 1024 + 1), {
mode: 0o600,
});
assert.throws(
() => readPrivateLocalCommandFile(oversized.filePath),
PrivateLocalCommandFileError,
);
const malformed = fixture(t);
fs.writeFileSync(malformed.filePath, '{', { mode: 0o600 });
assert.throws(
() => readPrivateLocalCommandFile(malformed.filePath),
PrivateLocalCommandFileError,
);
const invalidUtf8 = fixture(t);
fs.writeFileSync(
invalidUtf8.filePath,
Buffer.from([0x7b, 0x22, 0x78, 0x22, 0x3a, 0x22, 0xff, 0x22, 0x7d]),
{ mode: 0o600 },
);
assert.throws(
() => readPrivateLocalCommandFile(invalidUtf8.filePath),
PrivateLocalCommandFileError,
);
});
test('reuses the private descriptor protocol for explicitly bounded JSON', (t) => {
const value = { payload: 'x'.repeat(32 * 1024) };
const { filePath } = fixture(t, value);
assert.deepEqual(
readPrivateLocalJsonFile(filePath, { maxBytes: 64 * 1024 }),
value,
);
assert.throws(
() => readPrivateLocalCommandFile(filePath),
PrivateLocalCommandFileError,
);
for (const options of [
{},
{ maxBytes: 0 },
{ maxBytes: MAX_PRIVATE_LOCAL_JSON_FILE_BYTES + 1 },
{ maxBytes: 64 * 1024, widened: true },
]) {
assert.throws(
() => readPrivateLocalJsonFile(filePath, options),
PrivateLocalCommandFileError,
);
}
});
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "Node",
"declaration": true,
"outDir": "dist",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}