diff --git a/lib/routes/ichunqiu/index.ts b/lib/routes/ichunqiu/index.ts index 621aa7ccb8..1cd3a7a315 100644 --- a/lib/routes/ichunqiu/index.ts +++ b/lib/routes/ichunqiu/index.ts @@ -1,7 +1,7 @@ import { createHash } from 'node:crypto'; -import vm from 'node:vm'; import { load } from 'cheerio'; +import { VM } from 'vm2'; import type { Route } from '@/types'; import { generateHeaders } from '@/utils/header-generator'; @@ -60,7 +60,7 @@ async function handler() { const challenge = body.match(/go\((\{.+?\})\)/s); if (assignment) { // get 1st __jsl_clearance_s - const [name, value] = vm.runInNewContext(assignment[1], Object.create(null), { timeout: 1000 }).split(';', 1)[0].split('=', 2); + const [name, value] = new VM({ timeout: 1000 }).run(assignment[1]).split(';', 1)[0].split('=', 2); cookies.set(name, value); } else if (challenge) { // get 2nd __jsl_clearance_s diff --git a/lib/routes/locals/feed.ts b/lib/routes/locals/feed.ts index b1d4d09b8e..548586f013 100644 --- a/lib/routes/locals/feed.ts +++ b/lib/routes/locals/feed.ts @@ -1,4 +1,4 @@ -import vm from 'node:vm'; +import { VM } from 'vm2'; import { config } from '@/config'; import ConfigNotFoundError from '@/errors/types/config-not-found'; @@ -215,8 +215,7 @@ function parseUnknownResponse(body: string, instanceId: string): T { sandbox.self.$R = sandbox.$R; - vm.createContext(sandbox); - vm.runInContext(body, sandbox, { timeout: 5000 }); + new VM({ timeout: 5000, sandbox }).run(body); const value = sandbox.self.$R?.[instanceId]?.[0] as T | undefined; if (!value) { diff --git a/lib/shims/typescript.ts b/lib/shims/typescript.ts new file mode 100644 index 0000000000..5a3a2bdc07 --- /dev/null +++ b/lib/shims/typescript.ts @@ -0,0 +1,2 @@ +// TypeScript compiler shim for Cloudflare Workers for vm2 +throw new Error('The TypeScript compiler is not available in Workers'); diff --git a/package.json b/package.json index 3447f2be63..d7c8ba7d20 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,7 @@ "ufo": "1.6.4", "undici": "8.10.0", "uuid": "14.0.2", + "vm2": "3.11.6", "winston": "3.19.0", "xxhash-wasm": "1.1.0", "youtube-caption-extractor": "1.10.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10946fdb1a..83927f6423 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -268,6 +268,9 @@ importers: uuid: specifier: 14.0.2 version: 14.0.2 + vm2: + specifier: 3.11.6 + version: 3.11.6 winston: specifier: 3.19.0 version: 3.19.0 @@ -3286,6 +3289,10 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + acorn@8.18.0: resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} engines: {node: '>=0.4.0'} @@ -3789,7 +3796,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} difflib@https://codeload.github.com/postlight/difflib.js/tar.gz/32e8e38c7fcd935241b9baab71bb432fd9b166ed: - resolution: {gitHosted: true, tarball: https://codeload.github.com/postlight/difflib.js/tar.gz/32e8e38c7fcd935241b9baab71bb432fd9b166ed} + resolution: {tarball: https://codeload.github.com/postlight/difflib.js/tar.gz/32e8e38c7fcd935241b9baab71bb432fd9b166ed} version: 0.2.6 discord-api-types@0.38.53: @@ -6365,6 +6372,11 @@ packages: jsdom: optional: true + vm2@3.11.6: + resolution: {integrity: sha512-35hVTcKieg7jJMntHhgWT5c2a1J2vmpXm66Xs1Z8ayHOJTj8rzIlXKzba3nO1Om/sonmnkjlAOMt9p8lYJXsWw==} + engines: {node: '>=6.0'} + hasBin: true + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -8724,6 +8736,10 @@ snapshots: dependencies: acorn: 8.18.0 + acorn-walk@8.3.5: + dependencies: + acorn: 8.18.0 + acorn@8.18.0: {} adm-zip@0.6.0: {} @@ -12171,6 +12187,11 @@ snapshots: transitivePeerDependencies: - msw + vm2@3.11.6: + dependencies: + acorn: 8.18.0 + acorn-walk: 8.3.5 + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 diff --git a/tsdown-worker.config.ts b/tsdown-worker.config.ts index 274d352b94..bd4fb9539e 100644 --- a/tsdown-worker.config.ts +++ b/tsdown-worker.config.ts @@ -86,6 +86,7 @@ export default defineConfig({ '@sentry/node': path.resolve('./lib/shims/sentry-node.ts'), '@honeybadger-io/js': path.resolve('./lib/shims/honeybadger.ts'), 'xxhash-wasm': path.resolve('./lib/shims/xxhash-wasm.ts'), + typescript: path.resolve('./lib/shims/typescript.ts'), // Routes file with Worker-specific build (match relative import from lib/) '../assets/build/routes.js': path.resolve('./assets/build/routes-worker.js'), // routes.json is only used in test environment, but rolldown still tries to resolve it