mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 00:36:13 +08:00
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import path from 'path';
|
|
|
|
export const LEGACY_LOG_OUTPUT_REF_PREFIX = 'legacy-log-v1.';
|
|
export const MAX_LEGACY_LOG_PATH_BYTES = 360;
|
|
export const MAX_LEGACY_LOG_OUTPUT_REF_BYTES = 512;
|
|
|
|
function normalizeRelativeLogPath(value: string): string {
|
|
if (
|
|
!value ||
|
|
value.includes('\0') ||
|
|
value.includes('\\') ||
|
|
path.posix.isAbsolute(value) ||
|
|
path.win32.isAbsolute(value) ||
|
|
Buffer.byteLength(value, 'utf8') > MAX_LEGACY_LOG_PATH_BYTES
|
|
) {
|
|
throw new Error('Legacy log path must be a bounded relative POSIX path');
|
|
}
|
|
const normalized = path.posix.normalize(value);
|
|
if (
|
|
normalized === '.' ||
|
|
normalized === '..' ||
|
|
normalized.startsWith('../') ||
|
|
normalized.split('/').includes('..')
|
|
) {
|
|
throw new Error('Legacy log path escapes its configured root');
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
export function createLegacyLogOutputRef(logPath: string): string {
|
|
const normalized = normalizeRelativeLogPath(logPath);
|
|
const outputRef = `${LEGACY_LOG_OUTPUT_REF_PREFIX}${Buffer.from(
|
|
normalized,
|
|
'utf8',
|
|
).toString('base64url')}`;
|
|
if (Buffer.byteLength(outputRef, 'utf8') > MAX_LEGACY_LOG_OUTPUT_REF_BYTES) {
|
|
throw new Error('Legacy log output reference exceeds its size limit');
|
|
}
|
|
return outputRef;
|
|
}
|
|
|
|
export function parseLegacyLogOutputRef(outputRef?: string): string | null {
|
|
if (
|
|
!outputRef ||
|
|
!outputRef.startsWith(LEGACY_LOG_OUTPUT_REF_PREFIX) ||
|
|
Buffer.byteLength(outputRef, 'utf8') > MAX_LEGACY_LOG_OUTPUT_REF_BYTES
|
|
) {
|
|
return null;
|
|
}
|
|
const encoded = outputRef.slice(LEGACY_LOG_OUTPUT_REF_PREFIX.length);
|
|
if (!encoded || !/^[A-Za-z0-9_-]+$/.test(encoded)) return null;
|
|
try {
|
|
const bytes = Buffer.from(encoded, 'base64url');
|
|
if (bytes.toString('base64url') !== encoded) return null;
|
|
const decoded = bytes.toString('utf8');
|
|
if (Buffer.from(decoded, 'utf8').compare(bytes) !== 0) return null;
|
|
const normalized = normalizeRelativeLogPath(decoded);
|
|
return normalized === decoded ? decoded : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|