Merge release/0.3.83: keep master in step with what shipped as 0.3.83
This commit is contained in:
commit
0044a157f0
3 changed files with 47 additions and 3 deletions
|
|
@ -249,6 +249,19 @@ async function fetchVerifiedPackage({ id, version, url, sha256, log }) {
|
|||
return { status: "extract-failed", newVer: version, detail: e.message };
|
||||
}
|
||||
|
||||
// No links of any kind. A community extension runs sandboxed with read
|
||||
// access to its own folder, and Node's permission model follows links, so
|
||||
// a packaged symlink or junction to the profile (passwords.vault, the
|
||||
// wallet store) would be a way out. tar.exe only fails to create symlinks
|
||||
// where Windows withholds the privilege; with Developer Mode it makes them.
|
||||
const links = findLinks(tmpDir);
|
||||
if (links.length) {
|
||||
log(`updates: ${id}@${version} contains links (${links.slice(0, 3).join(", ")}), refusing`);
|
||||
try { fs.rmSync(tmpFile, { force: true }); } catch {}
|
||||
try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
|
||||
return { status: "extract-failed", newVer: version, detail: "package contains links" };
|
||||
}
|
||||
|
||||
// A package may wrap everything in one top-level folder (tar -czf x.tgz my-ext);
|
||||
// unwrap it so addon.json sits at the root like the bundled add-ons.
|
||||
let root = tmpDir;
|
||||
|
|
@ -266,6 +279,27 @@ async function fetchVerifiedPackage({ id, version, url, sha256, log }) {
|
|||
return { ok: true, tmpDir: root, tmpTop: tmpDir, tmpFile, manifest: extracted };
|
||||
}
|
||||
|
||||
// Every symlink, junction or hard-linked file under root (relative paths).
|
||||
// lstat reports a junction as a symbolic link; it is not followed.
|
||||
function findLinks(root) {
|
||||
const out = [];
|
||||
const walk = (dir, rel) => {
|
||||
let entries = [];
|
||||
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
||||
for (const de of entries) {
|
||||
const p = path.join(dir, de.name), r = rel ? rel + "/" + de.name : de.name;
|
||||
let st;
|
||||
try { st = fs.lstatSync(p); } catch { out.push(r); continue; }
|
||||
if (st.isSymbolicLink()) { out.push(r); continue; }
|
||||
if (st.isDirectory()) { walk(p, r); continue; }
|
||||
if (st.isFile() && st.nlink > 1) out.push(r);
|
||||
else if (!st.isFile()) out.push(r);
|
||||
}
|
||||
};
|
||||
walk(root, "");
|
||||
return out;
|
||||
}
|
||||
|
||||
// Move an extracted package into place (rename, with copy fallback across volumes).
|
||||
function placeDir(from, to) {
|
||||
try { fs.renameSync(from, to); }
|
||||
|
|
@ -420,7 +454,7 @@ async function checkAndStageUpdates({ addonsDir, stagedDir, pubkeysHex, verifyPu
|
|||
return { report };
|
||||
}
|
||||
|
||||
module.exports = { communityUpdateProblem,
|
||||
module.exports = { communityUpdateProblem, findLinks,
|
||||
cmpVer,
|
||||
promoteStagedUpdates,
|
||||
checkAndStageUpdates,
|
||||
|
|
|
|||
|
|
@ -635,7 +635,17 @@ class AddonHost {
|
|||
let mod;
|
||||
const holder = { active: null };
|
||||
const sandboxed = this._shouldSandbox(manifest);
|
||||
if (sandboxed) mod = this._sandboxModule(manifest, folder, mainPath, holder);
|
||||
if (sandboxed) {
|
||||
// The permission model follows links, so read access to a folder that
|
||||
// holds a symlink, junction or hard link to the profile is read access
|
||||
// to the profile. Installs refuse such packages; a folder that has one
|
||||
// anyway (an older install, a hand edit) does not start.
|
||||
const { findLinks } = require("./addon-updater.js");
|
||||
const scratch = path.join(this.dataDir, ".sandbox", "scratch", manifest.id);
|
||||
const links = [...findLinks(folder), ...(fs.existsSync(scratch) ? findLinks(scratch).map((r) => "scratch/" + r) : [])];
|
||||
if (links.length) throw new Error(`not started: the extension folder contains links (${links.slice(0, 3).join(", ")})`);
|
||||
mod = this._sandboxModule(manifest, folder, mainPath, holder);
|
||||
}
|
||||
else try {
|
||||
// Bust the require cache so a manual reload picks up edits — cheap since
|
||||
// add-ons are small. When the version changed (a hot-applied update) the
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "theseus-navigator",
|
||||
"version": "0.3.82",
|
||||
"version": "0.3.83",
|
||||
"license": "MPL-2.0",
|
||||
"description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.",
|
||||
"author": "Silent Mode",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue