forked from themika/panic
128 lines
4.0 KiB
JavaScript
128 lines
4.0 KiB
JavaScript
// SPDX-License-Identifier: MIT
|
|
|
|
var main_div = document.getElementById('main');
|
|
|
|
/*
|
|
* Check if the parameters are set as a url parameter or as a fragment
|
|
*/
|
|
function get_parameters() {
|
|
const queryString = window.location.search;
|
|
const fragString = window.location.hash.substring(1); //skip the leading #
|
|
|
|
const urlParams = new URLSearchParams(queryString);
|
|
const urlFragments = new URLSearchParams(fragString);
|
|
|
|
if (urlParams.get("z") || urlParams.get("zl")) {
|
|
return urlParams;
|
|
}
|
|
return urlFragments;
|
|
}
|
|
|
|
/*
|
|
* Encoding, same as Fido2 specification.
|
|
* v6.14+
|
|
*/
|
|
function numbers_to_data2(numbers) {
|
|
/* 17 decimal digits are converted to 7 bytes */
|
|
let main_len = Math.floor(numbers.length / 17) * 7;
|
|
/* and the remainings bytes, compute the reverse of [0, 3, 5, 8, 10, 13, 15, 17] */
|
|
let rem_len = Math.floor((numbers.length % 17) * 2 / 5);
|
|
|
|
let data = new Uint8Array(main_len + rem_len);
|
|
let offset = 0;
|
|
|
|
for (var i = 0; i < numbers.length; i += 17) {
|
|
let chunk = numbers.substring(i, i + 17);
|
|
let num = BigInt(chunk);
|
|
let num_bytes = 7;
|
|
if (chunk.len < 17) {
|
|
num_bytes = rem_len;
|
|
}
|
|
for (var j = 0; j < num_bytes; j++) {
|
|
data[offset] = Number(num % 256n);
|
|
num = num / 256n;
|
|
offset++;
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
/*
|
|
* Legacy encoding, found in v6.10 to v6.13
|
|
*/
|
|
function numbers_to_data(numbers) {
|
|
const num_chars_to_bits = [0, 4, 7, 10, 13];
|
|
const length_in_bits = Math.floor(numbers.length / 4) * 13 + num_chars_to_bits[numbers.length % 4];
|
|
const length_in_bytes = length_in_bits / 8;
|
|
const extra = length_in_bits % 8;
|
|
let data = new Uint8Array(length_in_bytes);
|
|
|
|
let offset = 0;
|
|
let byte_off = 0;
|
|
let rem = 0;
|
|
|
|
for (var i = 0; i < numbers.length; i += 4) {
|
|
let chunk = numbers.substring(i, i + 4);
|
|
let num = Number(chunk);
|
|
let new_length = num_chars_to_bits[chunk.length];
|
|
|
|
let b = offset + new_length;
|
|
if (byte_off * 8 + b >= length_in_bytes * 8) {
|
|
b -= extra;
|
|
}
|
|
if (b < 8) {
|
|
rem += num << (8 - b);
|
|
offset = b;
|
|
} else if (b < 16) {
|
|
data[byte_off] = rem + (num >> (b - 8));
|
|
byte_off++;
|
|
rem = (num << (16 - b)) & 0xff;
|
|
offset = (b - 8);
|
|
} else {
|
|
data[byte_off] = rem + (num >> (b - 8));
|
|
byte_off++;
|
|
data[byte_off] = num >> (b - 16);
|
|
byte_off++;
|
|
rem = num << (24 - b) & 0xff;
|
|
offset = (b - 16);
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
function add_info(name, value) {
|
|
if (value) {
|
|
div = document.createElement("div");
|
|
n = document.createElement("b");
|
|
n.innerHTML = name + ": ";
|
|
div.appendChild(n);
|
|
div.appendChild(document.createTextNode(value));
|
|
main_div.appendChild(div);
|
|
}
|
|
}
|
|
|
|
function add_data(data) {
|
|
uncompressed = pako.inflate(new Uint8Array(data));
|
|
text = String.fromCharCode.apply(null, uncompressed);
|
|
|
|
kmsg = document.createElement("pre");
|
|
kmsg.appendChild(document.createTextNode(text));
|
|
main_div.appendChild(kmsg);
|
|
}
|
|
|
|
const params = get_parameters();
|
|
|
|
add_info("Arch", params.get("a"));
|
|
add_info("Version", params.get("v"));
|
|
add_info("Distribution", params.get("d"));
|
|
|
|
const numbers = params.get("z");
|
|
const legacy_numbers = params.get("zl")
|
|
if (numbers) {
|
|
data = numbers_to_data2(numbers);
|
|
add_data(data);
|
|
} else if (legacy_numbers) {
|
|
data = numbers_to_data(legacy_numbers);
|
|
add_data(data);
|
|
}
|