fix: avoid invalid UTF-16 in truncation (#567)
This commit is contained in:
55
src/utils.ts
55
src/utils.ts
@@ -95,6 +95,61 @@ export function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function isHighSurrogate(codeUnit: number): boolean {
|
||||
return codeUnit >= 0xd800 && codeUnit <= 0xdbff;
|
||||
}
|
||||
|
||||
function isLowSurrogate(codeUnit: number): boolean {
|
||||
return codeUnit >= 0xdc00 && codeUnit <= 0xdfff;
|
||||
}
|
||||
|
||||
export function sliceUtf16Safe(
|
||||
input: string,
|
||||
start: number,
|
||||
end?: number,
|
||||
): string {
|
||||
const len = input.length;
|
||||
|
||||
let from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
|
||||
let to =
|
||||
end === undefined
|
||||
? len
|
||||
: end < 0
|
||||
? Math.max(len + end, 0)
|
||||
: Math.min(end, len);
|
||||
|
||||
if (to < from) {
|
||||
const tmp = from;
|
||||
from = to;
|
||||
to = tmp;
|
||||
}
|
||||
|
||||
if (from > 0 && from < len) {
|
||||
const codeUnit = input.charCodeAt(from);
|
||||
if (
|
||||
isLowSurrogate(codeUnit) &&
|
||||
isHighSurrogate(input.charCodeAt(from - 1))
|
||||
) {
|
||||
from += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (to > 0 && to < len) {
|
||||
const codeUnit = input.charCodeAt(to - 1);
|
||||
if (isHighSurrogate(codeUnit) && isLowSurrogate(input.charCodeAt(to))) {
|
||||
to -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return input.slice(from, to);
|
||||
}
|
||||
|
||||
export function truncateUtf16Safe(input: string, maxLen: number): string {
|
||||
const limit = Math.max(0, Math.floor(maxLen));
|
||||
if (input.length <= limit) return input;
|
||||
return sliceUtf16Safe(input, 0, limit);
|
||||
}
|
||||
|
||||
export function resolveUserPath(input: string): string {
|
||||
const trimmed = input.trim();
|
||||
if (!trimmed) return trimmed;
|
||||
|
||||
Reference in New Issue
Block a user