From 753f7613e7c252bd0cfb3635c176e290bfdcd33f Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 24 Sep 2025 16:06:17 +0800 Subject: [PATCH] core: support namespace for problem import --- packages/hydrooj/src/model/problem.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/hydrooj/src/model/problem.ts b/packages/hydrooj/src/model/problem.ts index f0d5ed4b9..dc56c45f7 100644 --- a/packages/hydrooj/src/model/problem.ts +++ b/packages/hydrooj/src/model/problem.ts @@ -13,7 +13,7 @@ import { extractZip, Logger, size, streamToBuffer, } from '@hydrooj/utils/lib/utils'; import { Context } from '../context'; -import { FileUploadError, ProblemNotFoundError, ValidationError } from '../error'; +import { FileUploadError, NotFoundError, ProblemNotFoundError, ValidationError } from '../error'; import type { Document, ProblemDict, ProblemStatusDoc, User, } from '../interface'; @@ -460,6 +460,8 @@ export class ProblemModel { } = options; let delSource = options.delSource; let problems: string[]; + const ddoc = await DomainModel.get(domainId); + if (!ddoc) throw new NotFoundError(domainId); try { if (filepath.endsWith('.zip')) { tmpdir = path.join(os.tmpdir(), 'hydro', `${Math.random()}.import`); @@ -502,7 +504,11 @@ export class ProblemModel { let overridePid = null; const isValidPid = async (id: string) => { - if (!(/^[A-Za-z][0-9A-Za-z]*$/.test(id))) return false; + if (!(/^(?:[a-z0-9]{1,10}-)?[a-z][0-9a-z]*$/i.test(id))) return false; + if (id.includes('-')) { + const [prefix] = id.split('-'); + if (!ddoc?.namespaces?.[prefix]) return false; + } const doc = await ProblemModel.get(domainId, id); if (doc) { if (!override) return false;