Highlighting now takes account of character set width
This commit is contained in:
parent
08b91fd7ff
commit
a141873db8
@ -6,6 +6,8 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import cptable from "codepage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Character encoding format mappings.
|
* Character encoding format mappings.
|
||||||
*/
|
*/
|
||||||
@ -175,6 +177,46 @@ for (const name in CHR_ENC_CODE_PAGES) {
|
|||||||
CHR_ENC_SIMPLE_REVERSE_LOOKUP[CHR_ENC_CODE_PAGES[name]] = simpleName;
|
CHR_ENC_SIMPLE_REVERSE_LOOKUP[CHR_ENC_CODE_PAGES[name]] = simpleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width of the character set for the given codepage.
|
||||||
|
* For example, UTF-8 is a Single Byte Character Set, whereas
|
||||||
|
* UTF-16 is a Double Byte Character Set.
|
||||||
|
*
|
||||||
|
* @param {number} page - The codepage number
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
export function chrEncWidth(page) {
|
||||||
|
if (typeof page !== "number") return 0;
|
||||||
|
|
||||||
|
// Raw Bytes have a width of 1
|
||||||
|
if (page === 0) return 1;
|
||||||
|
|
||||||
|
const pageStr = page.toString();
|
||||||
|
// Confirm this page is legitimate
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(CHR_ENC_SIMPLE_REVERSE_LOOKUP, pageStr))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Statically defined code pages
|
||||||
|
if (Object.prototype.hasOwnProperty.call(cptable, pageStr))
|
||||||
|
return cptable[pageStr].dec.length > 256 ? 2 : 1;
|
||||||
|
|
||||||
|
// Cached code pages
|
||||||
|
if (cptable.utils.cache.sbcs.includes(pageStr))
|
||||||
|
return 1;
|
||||||
|
if (cptable.utils.cache.dbcs.includes(pageStr))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
// Dynamically generated code pages
|
||||||
|
if (Object.prototype.hasOwnProperty.call(cptable.utils.magic, pageStr)) {
|
||||||
|
// Generate a single character and measure it
|
||||||
|
const a = cptable.utils.encode(page, "a");
|
||||||
|
return a.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unicode Normalisation Forms
|
* Unicode Normalisation Forms
|
||||||
*
|
*
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {EditorSelection} from "@codemirror/state";
|
import {EditorSelection} from "@codemirror/state";
|
||||||
|
import {chrEncWidth} from "../../core/lib/ChrEnc.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle events related to highlighting in CyberChef.
|
* Waiter to handle events related to highlighting in CyberChef.
|
||||||
@ -50,12 +50,23 @@ class HighlighterWaiter {
|
|||||||
// Confirm some non-empty ranges are set
|
// Confirm some non-empty ranges are set
|
||||||
const selectionRanges = e.state.selection.ranges;
|
const selectionRanges = e.state.selection.ranges;
|
||||||
|
|
||||||
|
// Adjust offsets based on the width of the character set
|
||||||
|
const inputCharacterWidth = chrEncWidth(this.manager.input.inputChrEnc);
|
||||||
|
const outputCharacterWidth = chrEncWidth(this.manager.output.outputChrEnc);
|
||||||
|
let ratio = 1;
|
||||||
|
if (inputCharacterWidth !== outputCharacterWidth &&
|
||||||
|
inputCharacterWidth !== 0 && outputCharacterWidth !== 0) {
|
||||||
|
ratio = io === "input" ?
|
||||||
|
inputCharacterWidth / outputCharacterWidth :
|
||||||
|
outputCharacterWidth / inputCharacterWidth;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop through ranges and send request for output offsets for each one
|
// Loop through ranges and send request for output offsets for each one
|
||||||
const direction = io === "input" ? "forward" : "reverse";
|
const direction = io === "input" ? "forward" : "reverse";
|
||||||
for (const range of selectionRanges) {
|
for (const range of selectionRanges) {
|
||||||
const pos = [{
|
const pos = [{
|
||||||
start: range.from,
|
start: Math.floor(range.from * ratio),
|
||||||
end: range.to
|
end: Math.floor(range.to * ratio)
|
||||||
}];
|
}];
|
||||||
this.manager.worker.highlight(this.app.getRecipeConfig(), direction, pos);
|
this.manager.worker.highlight(this.app.getRecipeConfig(), direction, pos);
|
||||||
}
|
}
|
||||||
@ -80,8 +91,7 @@ class HighlighterWaiter {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the relevant HTML to the specified highlight element such that highlighting appears
|
* Sends selection updates to the relevant EditorView.
|
||||||
* underneath the correct offset.
|
|
||||||
*
|
*
|
||||||
* @param {string} io - The input or output
|
* @param {string} io - The input or output
|
||||||
* @param {Object[]} ranges - An array of position objects to highlight
|
* @param {Object[]} ranges - An array of position objects to highlight
|
||||||
|
Loading…
x
Reference in New Issue
Block a user