CyberChef/src/js/operations/HTML.js

851 lines
18 KiB
JavaScript
Raw Normal View History

import Utils from '../core/Utils';
2016-11-28 10:42:58 +00:00
/**
* HTML operations.
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*
* @namespace
*/
2016-11-29 00:22:34 +00:00
const HTML = {
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
CONVERT_ALL: false,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
CONVERT_OPTIONS: ['Named entities where possible', 'Numeric entities', 'Hex entities'],
2016-11-28 10:42:58 +00:00
/**
* To HTML Entity operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
2016-11-29 00:22:34 +00:00
run_to_entity(input, args) {
let convert_all = args[0],
numeric = args[1] == 'Numeric entities',
hexa = args[1] == 'Hex entities';
const charcodes = Utils.str_to_charcode(input);
let output = '';
for (let i = 0; i < charcodes.length; i++) {
if (convert_all && numeric) {
output += `&#${charcodes[i]};`;
} else if (convert_all && hexa) {
output += `&#x${Utils.hex(charcodes[i])};`;
} else if (convert_all) {
output += HTML._byte_to_entity[charcodes[i]] || `&#${charcodes[i]};`;
} else if (numeric) {
if (charcodes[i] > 255 || HTML._byte_to_entity.hasOwnProperty(charcodes[i])) {
output += `&#${charcodes[i]};`;
} else {
output += Utils.chr(charcodes[i]);
}
} else if (hexa) {
if (charcodes[i] > 255 || HTML._byte_to_entity.hasOwnProperty(charcodes[i])) {
output += `&#x${Utils.hex(charcodes[i])};`;
} else {
output += Utils.chr(charcodes[i]);
}
} else {
output += HTML._byte_to_entity[charcodes[i]] || (
2016-11-28 10:42:58 +00:00
charcodes[i] > 255 ?
2016-11-29 00:22:34 +00:00
`&#${charcodes[i]};` :
2016-11-28 10:42:58 +00:00
Utils.chr(charcodes[i])
);
2016-11-29 00:22:34 +00:00
}
}
return output;
},
2016-11-28 10:42:58 +00:00
/**
* From HTML Entity operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
2016-11-29 00:22:34 +00:00
run_from_entity(input, args) {
let regex = /&(#?x?[a-zA-Z0-9]{1,8});/g,
output = '',
m,
i = 0;
while (m = regex.exec(input)) {
2016-11-28 10:42:58 +00:00
// Add up to match
2016-11-29 00:22:34 +00:00
for (; i < m.index;) {
output += input[i++];
}
2016-11-28 10:42:58 +00:00
// Add match
2016-11-29 00:22:34 +00:00
const bite = HTML._entity_to_byte[m[1]];
if (bite) {
output += Utils.chr(bite);
} else if (!bite && m[1][0] == '#' && m[1].length > 1 && /^#\d{1,5}$/.test(m[1])) {
2016-11-28 10:42:58 +00:00
// Numeric entity (e.g. &#10;)
2016-11-29 00:22:34 +00:00
const num = m[1].slice(1, m[1].length);
output += Utils.chr(parseInt(num, 10));
} else if (!bite && m[1][0] == '#' && m[1].length > 3 && /^#x[\dA-F]{2,8}$/i.test(m[1])) {
2016-11-28 10:42:58 +00:00
// Hex entity (e.g. &#x3A;)
2016-11-29 00:22:34 +00:00
const hex = m[1].slice(2, m[1].length);
output += Utils.chr(parseInt(hex, 16));
} else {
2016-11-28 10:42:58 +00:00
// Not a valid entity, print as normal
2016-11-29 00:22:34 +00:00
for (; i < regex.lastIndex;) { output += input[i++]; }
}
i = regex.lastIndex;
}
2016-11-28 10:42:58 +00:00
// Add all after final match
2016-11-29 00:22:34 +00:00
for (; i < input.length;) {
output += input[i++];
}
return output;
},
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
REMOVE_INDENTATION: true,
2016-11-28 10:42:58 +00:00
/**
* @constant
* @default
*/
2016-11-29 00:22:34 +00:00
REMOVE_LINE_BREAKS: true,
2016-11-28 10:42:58 +00:00
/**
* Strip HTML tags operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
2016-11-29 00:22:34 +00:00
run_strip_tags(input, args) {
let remove_indentation = args[0],
remove_line_breaks = args[1];
input = Utils.strip_html_tags(input);
if (remove_indentation) {
input = input.replace(/\n[ \f\t]+/g, '\n');
}
if (remove_line_breaks) {
input = input.replace(/^\s*\n/, '') // first line
.replace(/(\n\s*){2,}/g, '\n'); // all others
}
return input;
},
2016-11-28 10:42:58 +00:00
/**
* Parse colour code operation.
*
* @param {string} input
* @param {Object[]} args
* @returns {html}
*/
2016-11-29 00:22:34 +00:00
run_parse_colour_code(input, args) {
var m = null,
r = 0,
g = 0,
b = 0,
a = 1;
2016-11-28 10:42:58 +00:00
// Read in the input
2016-11-29 00:22:34 +00:00
if (m = input.match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i)) {
2016-11-28 10:42:58 +00:00
// Hex - #d9edf7
2016-11-29 00:22:34 +00:00
r = parseInt(m[1], 16);
g = parseInt(m[2], 16);
b = parseInt(m[3], 16);
} else if (m = input.match(/rgba?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)(?:,\s?(\d(?:\.\d+)?))?\)/i)) {
2016-11-28 10:42:58 +00:00
// RGB or RGBA - rgb(217,237,247) or rgba(217,237,247,1)
2016-11-29 00:22:34 +00:00
r = parseFloat(m[1]);
g = parseFloat(m[2]);
b = parseFloat(m[3]);
a = m[4] ? parseFloat(m[4]) : 1;
} else if (m = input.match(/hsla?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)%,\s?(\d{1,3}(?:\.\d+)?)%(?:,\s?(\d(?:\.\d+)?))?\)/i)) {
2016-11-28 10:42:58 +00:00
// HSL or HSLA - hsl(200, 65%, 91%) or hsla(200, 65%, 91%, 1)
2016-11-29 00:22:34 +00:00
let h_ = parseFloat(m[1]) / 360,
s_ = parseFloat(m[2]) / 100,
l_ = parseFloat(m[3]) / 100,
rgb_ = HTML._hsl_to_rgb(h_, s_, l_);
r = rgb_[0];
g = rgb_[1];
b = rgb_[2];
a = m[4] ? parseFloat(m[4]) : 1;
} else if (m = input.match(/cmyk\((\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?)\)/i)) {
2016-11-28 10:42:58 +00:00
// CMYK - cmyk(0.12, 0.04, 0.00, 0.03)
2016-11-29 00:22:34 +00:00
let c_ = parseFloat(m[1]),
m_ = parseFloat(m[2]),
y_ = parseFloat(m[3]),
k_ = parseFloat(m[4]);
r = Math.round(255 * (1 - c_) * (1 - k_));
g = Math.round(255 * (1 - m_) * (1 - k_));
b = Math.round(255 * (1 - y_) * (1 - k_));
}
var hsl_ = HTML._rgb_to_hsl(r, g, b),
h = Math.round(hsl_[0] * 360),
s = Math.round(hsl_[1] * 100),
l = Math.round(hsl_[2] * 100),
k = 1 - Math.max(r / 255, g / 255, b / 255),
c = (1 - r / 255 - k) / (1 - k),
y = (1 - b / 255 - k) / (1 - k);
m = (1 - g / 255 - k) / (1 - k);
2016-11-29 00:22:34 +00:00
c = isNaN(c) ? '0' : c.toFixed(2);
m = isNaN(m) ? '0' : m.toFixed(2);
y = isNaN(y) ? '0' : y.toFixed(2);
k = k.toFixed(2);
let hex = `#${
Utils.pad_left(Math.round(r).toString(16), 2)
}${Utils.pad_left(Math.round(g).toString(16), 2)
}${Utils.pad_left(Math.round(b).toString(16), 2)}`,
rgb = `rgb(${r}, ${g}, ${b})`,
rgba = `rgba(${r}, ${g}, ${b}, ${a})`,
hsl = `hsl(${h}, ${s}%, ${l}%)`,
hsla = `hsla(${h}, ${s}%, ${l}%, ${a})`,
cmyk = `cmyk(${c}, ${m}, ${y}, ${k})`;
2016-11-28 10:42:58 +00:00
// Generate output
return `${"<div data-cyber-chef-func='colorpicker' data-rgba='" + rgba + "' id='colorpicker' style='display: inline-block'></div>" +
2016-11-29 00:22:34 +00:00
'Hex: '}${hex}\n` +
`RGB: ${rgb}\n` +
`RGBA: ${rgba}\n` +
`HSL: ${hsl}\n` +
`HSLA: ${hsla}\n` +
`CMYK: ${cmyk
}`;
2016-11-29 00:22:34 +00:00
},
2016-11-28 10:42:58 +00:00
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @private
* @author Mohsen (http://stackoverflow.com/a/9493060)
*
* @param {number} h - The hue
* @param {number} s - The saturation
* @param {number} l - The lightness
* @return {Array} The RGB representation
*/
2016-11-29 00:22:34 +00:00
_hsl_to_rgb(h, s, l) {
let r,
g,
b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
},
2016-11-28 10:42:58 +00:00
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* @private
* @author Mohsen (http://stackoverflow.com/a/9493060)
*
* @param {number} r - The red color value
* @param {number} g - The green color value
* @param {number} b - The blue color value
* @return {Array} The HSL representation
*/
2016-11-29 00:22:34 +00:00
_rgb_to_hsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
let max = Math.max(r, g, b),
min = Math.min(r, g, b),
h,
s,
l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
},
2016-11-28 10:42:58 +00:00
/**
* Lookup table to translate byte values to their HTML entity codes.
*
* @private
* @constant
*/
2016-11-29 00:22:34 +00:00
_byte_to_entity: {
34: '&quot;',
38: '&amp;',
39: '&apos;',
60: '&lt;',
62: '&gt;',
160: '&nbsp;',
161: '&iexcl;',
162: '&cent;',
163: '&pound;',
164: '&curren;',
165: '&yen;',
166: '&brvbar;',
167: '&sect;',
168: '&uml;',
169: '&copy;',
170: '&ordf;',
171: '&laquo;',
172: '&not;',
173: '&shy;',
174: '&reg;',
175: '&macr;',
176: '&deg;',
177: '&plusmn;',
178: '&sup2;',
179: '&sup3;',
180: '&acute;',
181: '&micro;',
182: '&para;',
183: '&middot;',
184: '&cedil;',
185: '&sup1;',
186: '&ordm;',
187: '&raquo;',
188: '&frac14;',
189: '&frac12;',
190: '&frac34;',
191: '&iquest;',
192: '&Agrave;',
193: '&Aacute;',
194: '&Acirc;',
195: '&Atilde;',
196: '&Auml;',
197: '&Aring;',
198: '&AElig;',
199: '&Ccedil;',
200: '&Egrave;',
201: '&Eacute;',
202: '&Ecirc;',
203: '&Euml;',
204: '&Igrave;',
205: '&Iacute;',
206: '&Icirc;',
207: '&Iuml;',
208: '&ETH;',
209: '&Ntilde;',
210: '&Ograve;',
211: '&Oacute;',
212: '&Ocirc;',
213: '&Otilde;',
214: '&Ouml;',
215: '&times;',
216: '&Oslash;',
217: '&Ugrave;',
218: '&Uacute;',
219: '&Ucirc;',
220: '&Uuml;',
221: '&Yacute;',
222: '&THORN;',
223: '&szlig;',
224: '&agrave;',
225: '&aacute;',
226: '&acirc;',
227: '&atilde;',
228: '&auml;',
229: '&aring;',
230: '&aelig;',
231: '&ccedil;',
232: '&egrave;',
233: '&eacute;',
234: '&ecirc;',
235: '&euml;',
236: '&igrave;',
237: '&iacute;',
238: '&icirc;',
239: '&iuml;',
240: '&eth;',
241: '&ntilde;',
242: '&ograve;',
243: '&oacute;',
244: '&ocirc;',
245: '&otilde;',
246: '&ouml;',
247: '&divide;',
248: '&oslash;',
249: '&ugrave;',
250: '&uacute;',
251: '&ucirc;',
252: '&uuml;',
253: '&yacute;',
254: '&thorn;',
255: '&yuml;',
338: '&OElig;',
339: '&oelig;',
352: '&Scaron;',
353: '&scaron;',
376: '&Yuml;',
402: '&fnof;',
710: '&circ;',
732: '&tilde;',
913: '&Alpha;',
914: '&Beta;',
915: '&Gamma;',
916: '&Delta;',
917: '&Epsilon;',
918: '&Zeta;',
919: '&Eta;',
920: '&Theta;',
921: '&Iota;',
922: '&Kappa;',
923: '&Lambda;',
924: '&Mu;',
925: '&Nu;',
926: '&Xi;',
927: '&Omicron;',
928: '&Pi;',
929: '&Rho;',
931: '&Sigma;',
932: '&Tau;',
933: '&Upsilon;',
934: '&Phi;',
935: '&Chi;',
936: '&Psi;',
937: '&Omega;',
945: '&alpha;',
946: '&beta;',
947: '&gamma;',
948: '&delta;',
949: '&epsilon;',
950: '&zeta;',
951: '&eta;',
952: '&theta;',
953: '&iota;',
954: '&kappa;',
955: '&lambda;',
956: '&mu;',
957: '&nu;',
958: '&xi;',
959: '&omicron;',
960: '&pi;',
961: '&rho;',
962: '&sigmaf;',
963: '&sigma;',
964: '&tau;',
965: '&upsilon;',
966: '&phi;',
967: '&chi;',
968: '&psi;',
969: '&omega;',
977: '&thetasym;',
978: '&upsih;',
982: '&piv;',
8194: '&ensp;',
8195: '&emsp;',
8201: '&thinsp;',
8204: '&zwnj;',
8205: '&zwj;',
8206: '&lrm;',
8207: '&rlm;',
8211: '&ndash;',
8212: '&mdash;',
8216: '&lsquo;',
8217: '&rsquo;',
8218: '&sbquo;',
8220: '&ldquo;',
8221: '&rdquo;',
8222: '&bdquo;',
8224: '&dagger;',
8225: '&Dagger;',
8226: '&bull;',
8230: '&hellip;',
8240: '&permil;',
8242: '&prime;',
8243: '&Prime;',
8249: '&lsaquo;',
8250: '&rsaquo;',
8254: '&oline;',
8260: '&frasl;',
8364: '&euro;',
8465: '&image;',
8472: '&weierp;',
8476: '&real;',
8482: '&trade;',
8501: '&alefsym;',
8592: '&larr;',
8593: '&uarr;',
8594: '&rarr;',
8595: '&darr;',
8596: '&harr;',
8629: '&crarr;',
8656: '&lArr;',
8657: '&uArr;',
8658: '&rArr;',
8659: '&dArr;',
8660: '&hArr;',
8704: '&forall;',
8706: '&part;',
8707: '&exist;',
8709: '&empty;',
8711: '&nabla;',
8712: '&isin;',
8713: '&notin;',
8715: '&ni;',
8719: '&prod;',
8721: '&sum;',
8722: '&minus;',
8727: '&lowast;',
8730: '&radic;',
8733: '&prop;',
8734: '&infin;',
8736: '&ang;',
8743: '&and;',
8744: '&or;',
8745: '&cap;',
8746: '&cup;',
8747: '&int;',
8756: '&there4;',
8764: '&sim;',
8773: '&cong;',
8776: '&asymp;',
8800: '&ne;',
8801: '&equiv;',
8804: '&le;',
8805: '&ge;',
8834: '&sub;',
8835: '&sup;',
8836: '&nsub;',
8838: '&sube;',
8839: '&supe;',
8853: '&oplus;',
8855: '&otimes;',
8869: '&perp;',
8901: '&sdot;',
8942: '&vellip;',
8968: '&lceil;',
8969: '&rceil;',
8970: '&lfloor;',
8971: '&rfloor;',
9001: '&lang;',
9002: '&rang;',
9674: '&loz;',
9824: '&spades;',
9827: '&clubs;',
9829: '&hearts;',
9830: '&diams;',
},
2016-11-28 10:42:58 +00:00
/**
* Lookup table to translate HTML entity codes to their byte values.
*
* @private
* @constant
*/
2016-11-29 00:22:34 +00:00
_entity_to_byte: {
quot: 34,
amp: 38,
apos: 39,
lt: 60,
gt: 62,
nbsp: 160,
iexcl: 161,
cent: 162,
pound: 163,
curren: 164,
yen: 165,
brvbar: 166,
sect: 167,
uml: 168,
copy: 169,
ordf: 170,
laquo: 171,
not: 172,
shy: 173,
reg: 174,
macr: 175,
deg: 176,
plusmn: 177,
sup2: 178,
sup3: 179,
acute: 180,
micro: 181,
para: 182,
middot: 183,
cedil: 184,
sup1: 185,
ordm: 186,
raquo: 187,
frac14: 188,
frac12: 189,
frac34: 190,
iquest: 191,
Agrave: 192,
Aacute: 193,
Acirc: 194,
Atilde: 195,
Auml: 196,
Aring: 197,
AElig: 198,
Ccedil: 199,
Egrave: 200,
Eacute: 201,
Ecirc: 202,
Euml: 203,
Igrave: 204,
Iacute: 205,
Icirc: 206,
Iuml: 207,
ETH: 208,
Ntilde: 209,
Ograve: 210,
Oacute: 211,
Ocirc: 212,
Otilde: 213,
Ouml: 214,
times: 215,
Oslash: 216,
Ugrave: 217,
Uacute: 218,
Ucirc: 219,
Uuml: 220,
Yacute: 221,
THORN: 222,
szlig: 223,
agrave: 224,
aacute: 225,
acirc: 226,
atilde: 227,
auml: 228,
aring: 229,
aelig: 230,
ccedil: 231,
egrave: 232,
eacute: 233,
ecirc: 234,
euml: 235,
igrave: 236,
iacute: 237,
icirc: 238,
iuml: 239,
eth: 240,
ntilde: 241,
ograve: 242,
oacute: 243,
ocirc: 244,
otilde: 245,
ouml: 246,
divide: 247,
oslash: 248,
ugrave: 249,
uacute: 250,
ucirc: 251,
uuml: 252,
yacute: 253,
thorn: 254,
yuml: 255,
OElig: 338,
oelig: 339,
Scaron: 352,
scaron: 353,
Yuml: 376,
fnof: 402,
circ: 710,
tilde: 732,
Alpha: 913,
Beta: 914,
Gamma: 915,
Delta: 916,
Epsilon: 917,
Zeta: 918,
Eta: 919,
Theta: 920,
Iota: 921,
Kappa: 922,
Lambda: 923,
Mu: 924,
Nu: 925,
Xi: 926,
Omicron: 927,
Pi: 928,
Rho: 929,
Sigma: 931,
Tau: 932,
Upsilon: 933,
Phi: 934,
Chi: 935,
Psi: 936,
Omega: 937,
alpha: 945,
beta: 946,
gamma: 947,
delta: 948,
epsilon: 949,
zeta: 950,
eta: 951,
theta: 952,
iota: 953,
kappa: 954,
lambda: 955,
mu: 956,
nu: 957,
xi: 958,
omicron: 959,
pi: 960,
rho: 961,
sigmaf: 962,
sigma: 963,
tau: 964,
upsilon: 965,
phi: 966,
chi: 967,
psi: 968,
omega: 969,
thetasym: 977,
upsih: 978,
piv: 982,
ensp: 8194,
emsp: 8195,
thinsp: 8201,
zwnj: 8204,
zwj: 8205,
lrm: 8206,
rlm: 8207,
ndash: 8211,
mdash: 8212,
lsquo: 8216,
rsquo: 8217,
sbquo: 8218,
ldquo: 8220,
rdquo: 8221,
bdquo: 8222,
dagger: 8224,
Dagger: 8225,
bull: 8226,
hellip: 8230,
permil: 8240,
prime: 8242,
Prime: 8243,
lsaquo: 8249,
rsaquo: 8250,
oline: 8254,
frasl: 8260,
euro: 8364,
image: 8465,
weierp: 8472,
real: 8476,
trade: 8482,
alefsym: 8501,
larr: 8592,
uarr: 8593,
rarr: 8594,
darr: 8595,
harr: 8596,
crarr: 8629,
lArr: 8656,
uArr: 8657,
rArr: 8658,
dArr: 8659,
hArr: 8660,
forall: 8704,
part: 8706,
exist: 8707,
empty: 8709,
nabla: 8711,
isin: 8712,
notin: 8713,
ni: 8715,
prod: 8719,
sum: 8721,
minus: 8722,
lowast: 8727,
radic: 8730,
prop: 8733,
infin: 8734,
ang: 8736,
and: 8743,
or: 8744,
cap: 8745,
cup: 8746,
int: 8747,
there4: 8756,
sim: 8764,
cong: 8773,
asymp: 8776,
ne: 8800,
equiv: 8801,
le: 8804,
ge: 8805,
sub: 8834,
sup: 8835,
nsub: 8836,
sube: 8838,
supe: 8839,
oplus: 8853,
otimes: 8855,
perp: 8869,
sdot: 8901,
vellip: 8942,
lceil: 8968,
rceil: 8969,
lfloor: 8970,
rfloor: 8971,
lang: 9001,
rang: 9002,
loz: 9674,
spades: 9824,
clubs: 9827,
hearts: 9829,
diams: 9830,
},
2016-11-28 10:42:58 +00:00
};
export default HTML;