fix(unescape) str.replace is not suitable to store single byte above \x90 -> use Uint8Array

This commit is contained in:
kerms 2024-06-25 16:51:05 +08:00
parent 3b6c48f1d0
commit 5b9d6f878f
1 changed files with 58 additions and 45 deletions

View File

@ -45,32 +45,57 @@ function escapeHTML(text: string) {
return element.innerHTML; return element.innerHTML;
} }
function unescapeString(str: string) { function unescapeString(str: string): Uint8Array {
return str.replace(/\\(u[0-9a-fA-F]{4}|x[0-9a-fA-F]{2}|[0-7]{1,3}|.)/g, (_, escapeChar) => { const resultArray = [];
switch (escapeChar[0]) { let i = 0;
case 'n':
return '\n'; while (i < str.length) {
case 'r': if (str[i] === '\\' && i + 1 < str.length) {
return '\r'; i++;
case 't': switch (str[i]) {
return '\t'; case 'n':
case 'b': resultArray.push('\n'.charCodeAt(0));
return '\b'; break;
case 'v': case 'r':
return '\v'; resultArray.push('\r'.charCodeAt(0));
case '0': break;
return '\0'; case 't':
case 'x': resultArray.push('\t'.charCodeAt(0));
return String.fromCharCode(parseInt(escapeChar.slice(1), 16)); break;
case 'u': case 'b':
return String.fromCharCode(parseInt(escapeChar.slice(1), 16)); resultArray.push('\b'.charCodeAt(0));
default: break;
if (/^[0-7]{1,3}$/.test(escapeChar)) { case 'v':
return String.fromCharCode(parseInt(escapeChar, 8)); resultArray.push('\v'.charCodeAt(0));
} break;
return escapeChar; case '0':
resultArray.push('\0'.charCodeAt(0));
break;
case 'x':
if (i + 2 < str.length) {
const hex = str.slice(i + 1, i + 3);
resultArray.push(parseInt(hex, 16));
i += 2;
}
break;
case 'u':
if (i + 4 < str.length) {
const hex = str.slice(i + 1, i + 5);
resultArray.push(parseInt(hex, 16));
i += 4;
}
break;
default:
resultArray.push(str[i].charCodeAt(0));
break;
}
} else {
resultArray.push(str[i].charCodeAt(0));
} }
}); i++;
}
return new Uint8Array(resultArray);
} }
const zeroPad = (num: number, places: number) => String(num).padStart(places, '0'); const zeroPad = (num: number, places: number) => String(num).padStart(places, '0');
@ -227,9 +252,7 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
const frameBreakSequence = ref("\\n"); const frameBreakSequence = ref("\\n");
const frameBreakAfterSequence = ref(true); const frameBreakAfterSequence = ref(true);
const frameBreakSequenceNormalized = computed(() => { const frameBreakSequenceNormalized = computed(() => {
const unescapedStr = unescapeString(frameBreakSequence.value); return unescapeString(frameBreakSequence.value);
const encoder = new TextEncoder();
return encoder.encode(unescapedStr);
}); });
const frameBreakDelay = ref(0); const frameBreakDelay = ref(0);
let frameBreakDelayTimeoutID: number = -1; let frameBreakDelayTimeoutID: number = -1;
@ -339,10 +362,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
},]) },])
function addStringMessage(input: string, isRX: boolean, doSend: boolean = false) { function addStringMessage(input: string, isRX: boolean, doSend: boolean = false) {
const encoder = new TextEncoder(); const unescaped = unescapeString(input);
input = unescapeString(input); addSegment(unescaped, isRX, doSend);
const encodedStr = encoder.encode(input);
addSegment(encodedStr, isRX, doSend);
} }
function addSegment(input: Uint8Array, isRX: boolean, doSend: boolean = false) { function addSegment(input: Uint8Array, isRX: boolean, doSend: boolean = false) {
@ -438,21 +459,15 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
const filterValue = ref(""); const filterValue = ref("");
const computedFilterValue = computed(() => { const computedFilterValue = computed(() => {
const str = unescapeString(filterValue.value); return unescapeString(filterValue.value);
const encoder = new TextEncoder();
return encoder.encode(str);
}) })
const computedSuffixValue = computed(() => { const computedSuffixValue = computed(() => {
const str = unescapeString(textSuffixValue.value); return unescapeString(textSuffixValue.value);
const encoder = new TextEncoder();
return encoder.encode(str);
}) })
const computedPrefixValue = computed(() => { const computedPrefixValue = computed(() => {
const str = unescapeString(textPrefixValue.value); return unescapeString(textPrefixValue.value);
const encoder = new TextEncoder();
return encoder.encode(str);
}) })
const dataBuf: IDataBuf[] = []; const dataBuf: IDataBuf[] = [];
@ -501,10 +516,8 @@ export const useDataViewerStore = defineStore('text-viewer', () => {
}, 200); }, 200);
function addString(item: string, isRX: boolean = false, doSend: boolean = false, type: number = 0) { function addString(item: string, isRX: boolean = false, doSend: boolean = false, type: number = 0) {
const encoder = new TextEncoder(); const unescaped = unescapeString(item);
item = unescapeString(item); return addItem(unescaped, isRX, doSend, type);
const encodedStr = encoder.encode(item);
return addItem(encodedStr, isRX, doSend, type);
} }
function addHexString(item: string, isRX: boolean = false, doSend: boolean = false, type: number = 0) { function addHexString(item: string, isRX: boolean = false, doSend: boolean = false, type: number = 0) {