mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-15 15:54:00 -04:00
* updated dank to support aqueous
* further updates
* aqueous support work
* updated to support workspace options better in aqueous
* added blur to dms shell for aqueous
* added keybinding update
* remove unneeded blur
* clean up per claud review
* swapped to ipc
* aqueous: move IPC integration to QML, delete test fixtures (since we
dont have a QML test structure even setup), delete in-repo docs
* fix staticcheck
* aqueous: consolidate more aqueous specific stuff
* add aqueous logo
---------
Co-authored-by: Zoey <[email protected]>
(cherry picked from commit b9365610c8)
108 lines
3.7 KiB
JavaScript
108 lines
3.7 KiB
JavaScript
function socketPath(path, runtime) {
|
|
if (!runtime.startsWith("/") || runtime.endsWith("/") || !path.startsWith(runtime + "/aqueous/"))
|
|
return false;
|
|
if (/[\r\n\u0000]/.test(path) || path.includes("//") || path.split("/").some(part => part === "." || part === ".."))
|
|
return false;
|
|
return /^\/aqueous\/[^/]+\/ipc\.sock$/.test(path.slice(runtime.length));
|
|
}
|
|
|
|
function byteLength(text) {
|
|
return encodeURIComponent(text).replace(/%[0-9A-F]{2}/g, "x").length;
|
|
}
|
|
|
|
function object(value) {
|
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
}
|
|
|
|
function decimal(value) {
|
|
return typeof value === "string" && /^[0-9]{1,20}$/.test(value);
|
|
}
|
|
|
|
function nextId(value) {
|
|
const digits = value.split("");
|
|
for (let i = digits.length - 1; i >= 0; i--) {
|
|
if (digits[i] !== "9") {
|
|
digits[i] = String(Number(digits[i]) + 1);
|
|
return digits.join("");
|
|
}
|
|
digits[i] = "0";
|
|
}
|
|
if (digits.length === 20)
|
|
throw new Error("IPC request IDs exhausted");
|
|
return "1" + digits.join("");
|
|
}
|
|
|
|
function hello(value) {
|
|
if (!object(value) || value.schema !== 1 || typeof value.session !== "string" || !/^[0-9a-f]{32}$/.test(value.session) || value.max_pending_requests !== 1)
|
|
throw new Error("unsupported: Aqueous IPC hello");
|
|
const limits = {max_request_bytes: 65536, max_frame_bytes: 4259840, max_batch_bytes: 4194304};
|
|
for (const key of Object.keys(limits)) {
|
|
if (!Number.isInteger(value[key]) || value[key] <= 0 || value[key] > limits[key])
|
|
throw new Error("unsupported: IPC " + key);
|
|
}
|
|
if (!object(value.capabilities))
|
|
throw new Error("unsupported: IPC capabilities");
|
|
for (const name of ["state", "commands", "keyboard", "overview", "shortcut_inhibition"]) {
|
|
if (typeof value.capabilities[name] !== "boolean")
|
|
throw new Error("unsupported: missing capability " + name);
|
|
}
|
|
if (!value.capabilities.state)
|
|
throw new Error("unsupported: shell state");
|
|
return value;
|
|
}
|
|
|
|
function envelope(line, limit) {
|
|
if (byteLength(line) > limit)
|
|
throw new Error("IPC frame exceeds size bound");
|
|
let depth = 0, quoted = false, escaped = false;
|
|
for (const c of line) {
|
|
if (quoted) {
|
|
if (escaped) {
|
|
escaped = false;
|
|
continue;
|
|
}
|
|
switch (c) {
|
|
case "\\":
|
|
escaped = true;
|
|
break;
|
|
case '"':
|
|
quoted = false;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
switch (c) {
|
|
case '"':
|
|
quoted = true;
|
|
break;
|
|
case "{":
|
|
case "[":
|
|
depth++;
|
|
break;
|
|
case "}":
|
|
case "]":
|
|
depth--;
|
|
break;
|
|
}
|
|
if (depth > 32)
|
|
throw new Error("IPC nesting exceeds limit");
|
|
}
|
|
const value = JSON.parse(line);
|
|
if (!object(value) || value.ipc !== 1)
|
|
throw new Error("unsupported: IPC envelope");
|
|
return value;
|
|
}
|
|
|
|
function response(value, id) {
|
|
if (value.id !== id || !decimal(value.id) || typeof value.ok !== "boolean" || value.event !== undefined)
|
|
throw new Error("invalid IPC response correlation");
|
|
if (value.ok) {
|
|
if (!object(value.result) || value.error !== undefined)
|
|
throw new Error("invalid IPC result");
|
|
return "";
|
|
}
|
|
if (!object(value.error) || typeof value.error.code !== "string" || !value.error.code || value.error.code.length > 128 || typeof value.error.message !== "string" || byteLength(value.error.message) > 4096 || value.result !== undefined)
|
|
throw new Error("malformed IPC error");
|
|
return value.error.code + ": " + value.error.message;
|
|
}
|