mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
harden shim origin check and fs/vault endpoints
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
// File descriptor shim - maps fake integer fds to in-memory file buffers.
|
||||
// Enables libraries like yauzl that use fs.open/fs.read/fs.close to seek
|
||||
// around files without loading them via readFileSync upfront.
|
||||
// File descriptor shim. Maps fake integer fds to in-memory file buffers.
|
||||
|
||||
import { isInputCachePath, inputCacheGet } from "./input-cache.js";
|
||||
import { resolvePath } from "./transforms.js";
|
||||
import { hasVirtualFile, getVirtualFile } from "./virtual-files.js";
|
||||
|
||||
let nextFd = 100;
|
||||
const openFiles = new Map();
|
||||
@@ -24,6 +23,15 @@ export function createFdOps(metadataCache, contentCache, transport) {
|
||||
}
|
||||
|
||||
const resolved = resolvePath(path);
|
||||
|
||||
if (hasVirtualFile(resolved)) {
|
||||
const content = getVirtualFile(resolved);
|
||||
|
||||
return typeof content === "string"
|
||||
? new TextEncoder().encode(content)
|
||||
: content;
|
||||
}
|
||||
|
||||
const cached = contentCache.get(resolved);
|
||||
|
||||
if (cached !== null) {
|
||||
@@ -60,7 +68,11 @@ export function createFdOps(metadataCache, contentCache, transport) {
|
||||
const hasInCache = isInputCachePath(path) && inputCacheGet(path) !== null;
|
||||
const resolved = resolvePath(path);
|
||||
|
||||
if (!hasInCache && !metadataCache.has(resolved)) {
|
||||
if (
|
||||
!hasInCache &&
|
||||
!hasVirtualFile(resolved) &&
|
||||
!metadataCache.has(resolved)
|
||||
) {
|
||||
const err = new Error(
|
||||
`ENOENT: no such file or directory, open '${path}'`,
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
applyWriteTransform,
|
||||
resolvePath,
|
||||
} from "./transforms.js";
|
||||
import { hasVirtualFile, getVirtualFile } from "./virtual-files.js";
|
||||
|
||||
export function createFsSync(metadataCache, contentCache, transport) {
|
||||
return {
|
||||
@@ -70,6 +71,21 @@ export function createFsSync(metadataCache, contentCache, transport) {
|
||||
const wantText = encoding === "utf8" || encoding === "utf-8";
|
||||
const resolved = resolvePath(path);
|
||||
|
||||
// Virtual plugin source overrides any cache or transport version.
|
||||
if (hasVirtualFile(resolved)) {
|
||||
const content = getVirtualFile(resolved);
|
||||
|
||||
if (wantText) {
|
||||
return typeof content === "string"
|
||||
? content
|
||||
: new TextDecoder().decode(content);
|
||||
}
|
||||
|
||||
return typeof content === "string"
|
||||
? new TextEncoder().encode(content)
|
||||
: content;
|
||||
}
|
||||
|
||||
const meta = metadataCache.get(resolved);
|
||||
if (meta && meta.type === "directory") {
|
||||
const e = new Error("EISDIR: illegal operation on a directory, read");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
function isSameOrigin(url) {
|
||||
if (
|
||||
!url ||
|
||||
url.startsWith("/") ||
|
||||
(url.startsWith("/") && !url.startsWith("//")) ||
|
||||
url.startsWith("./") ||
|
||||
url.startsWith("../")
|
||||
) {
|
||||
|
||||
25
packages/shim/src/util/url.test.js
Normal file
25
packages/shim/src/util/url.test.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||
import { isSameOrigin } from "./url.js";
|
||||
|
||||
describe("isSameOrigin", () => {
|
||||
beforeEach(() => {
|
||||
global.window = { location: { origin: "https://vault.example.com" } };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
delete global.window;
|
||||
});
|
||||
|
||||
it("treats a root-relative path as same-origin", () => {
|
||||
expect(isSameOrigin("/api/fs/readFile")).toBe(true);
|
||||
});
|
||||
|
||||
it("treats a protocol-relative URL as cross-origin", () => {
|
||||
expect(isSameOrigin("//evil.com/x")).toBe(false);
|
||||
});
|
||||
|
||||
it("matches the page origin and rejects a different host", () => {
|
||||
expect(isSameOrigin("https://vault.example.com/x")).toBe(true);
|
||||
expect(isSameOrigin("https://evil.com/x")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user