feat(okr): delt bundle-root-relativ lenke-resolver + zero-dangling relasjoner (SC relasjoner) [skip-docs]
This commit is contained in:
parent
d011fb1922
commit
2b0c520efd
3 changed files with 174 additions and 0 deletions
39
lib/okf-links.mjs
Normal file
39
lib/okf-links.mjs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// okf-links.mjs
|
||||
// Delt bundle-root-relativ lenke-resolver (Step 6), brukt av BAADE relasjons-
|
||||
// emitteringen (innboks-relations) og okf-check++ --strict-ingest (Step 8).
|
||||
// Konvensjon: en trygg bundle-lenke er ROOT-RELATIV med leading '/' (resolveres
|
||||
// mot bundle-rota, jf. SC-regex \]\(/.*\.md\)). Avviser '../'-escape, absolutt
|
||||
// Windows-sti (backslash), og scheme-lenker (file://, http(s)://). Den ENESTE
|
||||
// lenke-allow-listen -- delt slik at emit og validering aldri divergerer.
|
||||
// Zero npm dependencies.
|
||||
|
||||
import path from 'node:path';
|
||||
|
||||
// Scheme-prefiks (file://, http://, https://, ...) -- avvises uansett.
|
||||
const SCHEME_RE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
||||
// '..'-segment hvor som helst i stien (escape ut av bundle-rota).
|
||||
const PARENT_SEGMENT_RE = /(^|\/)\.\.(\/|$)/;
|
||||
|
||||
// Sann hvis target er en trygg, bundle-root-relativ .md-lenke (leading '/').
|
||||
export function isSafeBundleLink(target) {
|
||||
if (typeof target !== 'string' || target === '') return false;
|
||||
if (target.includes('\0')) return false; // null-byte
|
||||
if (target.includes('\\')) return false; // backslash (Windows-sti)
|
||||
if (SCHEME_RE.test(target)) return false; // file://, http(s)://, ...
|
||||
if (!target.startsWith('/')) return false; // maa vaere bundle-root-relativ
|
||||
if (PARENT_SEGMENT_RE.test(target)) return false; // ingen '..'-escape
|
||||
if (!target.endsWith('.md')) return false; // bundle-konseptlenker er .md
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolverer en trygg bundle-lenke til absolutt sti UNDER bundleRoot, ellers null.
|
||||
// Belt-and-suspenders: isSafeBundleLink avviser '..' allerede, men confinement
|
||||
// re-sjekkes paa den resolverte stien.
|
||||
export function resolveBundleLink(target, bundleRoot) {
|
||||
if (!isSafeBundleLink(target)) return null;
|
||||
const rel = target.replace(/^\/+/, '');
|
||||
const root = path.resolve(bundleRoot);
|
||||
const resolved = path.resolve(root, rel);
|
||||
if (resolved !== root && !resolved.startsWith(root + path.sep)) return null;
|
||||
return resolved;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue