Repository navigation
fix(lint): slice definitions by UTF-8 byte offset; report unparseable definitions - #374
Conversation
… definitions libpg_query reports stmt_location/stmt_len and node locations as byte offsets into the UTF-8 source, but the file runner sliced the JS string by code unit. Any multi-byte character earlier in a file shifted every later CREATE FUNCTION slice, the definition failed to parse, and the engine dropped the parse error — so the file reported no findings at all. - slice statements and count lines over the encoded bytes (util.ts) - SQL-language body fragments and the C1 SET clause map byte offsets too - lintDefinition returns parseError; lintSqlText/lintFiles/lintSource report it as a parse-error (P0) finding, severity configurable
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Review complete. 🟡 1 medium 📍 Findings outside the diff (1) — 🟡 1 medium — defects on lines GitHub can't attach comments to🟡 Medium — // packages/lint/src/file-runner.ts
158 if (parseError) findings.push(parseErrorFinding(parseError, subject, startLine + 1, options));
159 const absLine = (p: LintProblem): number => startLine + p.line; // p.line is 1-based within input.text
160 for (const p of problems) findings.push(toFinding(p, subject, absLine(p), false));
161 for (const s of suppressed) {
162 findings.push(toFinding(s, subject, absLine(s), true, s.reason, s.scope));
163 }
164 }
165 findings.sort((a, b) => a.line - b.line || a.ruleId.localeCompare(b.ruleId));
166 return findings;
167 }
168
169 function toFinding(
The change adds a parse-error detection pipeline to the new
Reviewed commit: 0473fb0 |
parseErrorFinding resolved the configured severity but was pushed unconditionally, so a config that turned the pseudo-rule off still failed the run. Return nothing for off, as lintDefinition does for rules.
Summary
@pgsql/lintapplied libpg_query offsets (stmt_location/stmt_len, nodelocations) to the JS string, but those are byte offsets into the UTF-8 source. Any multi-byte character earlier in a file (→,—in a comment) shifted every laterCREATE FUNCTIONslice; the shifted text failed to parse,engine.tsdropped the parse error, and the file reported zero findings for C1–C4.Changes in
packages/lint:util.ts:utf8(text),sliceBytes(bytes, start, len),newlinesBeforeByte(bytes, off);lineOfOffsetnow counts over bytes.file-runner.ts: statement slicing andstartLinere-anchoring go through the byte helpers.parse-unit.ts: SQL-language body fragment offsets and the C1SETclause locations are mapped via bytes as well.lintDefinitionreturnsparseError, and the file/sql-text runners emit aparse-error(P0) finding (PARSE_ERRORmeta exported; severity configurable like any rule, e.g.--warn parse-error). The CLI's special-case warning path for parse errors is removed so they count like other findings.Tests:
__fixtures__/multibyte.sql(Unicode comment before functions tripping C1/C3/C4) with a Unicode-vs-ASCII-folded equivalence test and a P0 test; all three fail onmainand pass here. README and.agents/skills/pgsql-lintupdated.Link to Devin session: https://app.devin.ai/sessions/55f7e7b0c9bb4304b9989b993362571e
Open in Devin Desktop: https://app.devin.ai/desktop/session/55f7e7b0c9bb4304b9989b993362571e?variant=devin
Requested by: @pyramation