chore(scripts): 侧车导出加固——site-id UUID 校验与 audit 非 CDATA 匹配
评审两条非阻塞加固:--site-id 拼入 SQL 前过 UUID 形态白名单(非 UUID 拒绝并 明确报错);--audit 的 attachment_url 抽取正则同时匹配 CDATA 与裸文本两形态。 对真实数据重跑数字不变(859 条 / 855 对 836 命中,输出哈希一致)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,14 @@ const DEFAULT_CONTAINER = 'infrastructure-postgres-1'
|
||||
const DEFAULT_USER = 'cms'
|
||||
const DEFAULT_DB = 'cms'
|
||||
|
||||
/** 唯一一条对 cms 执行的 SQL(只读 SELECT;source_url IS NOT NULL——867 中 8 行 NULL 不带出) */
|
||||
/** site-id 白名单校验:UUID 形态(评审加固)——SQL 里 site_id 以字面量内插,非 UUID 输入在拼 SQL 前拒绝 */
|
||||
function assertValidSiteId(siteId) {
|
||||
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(siteId)) {
|
||||
throw new Error(`--site-id 不是合法 UUID(36 位形态):${siteId}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** 唯一一条对 cms 执行的 SQL(只读 SELECT;site_id 已过 UUID 校验;source_url IS NOT NULL——867 中 8 行 NULL 不带出) */
|
||||
function exportSql(siteId) {
|
||||
return (
|
||||
`SELECT source_url, file_path FROM media_assets ` +
|
||||
@@ -90,9 +97,10 @@ async function auditAgainstWxr(mapPath, wxrPath) {
|
||||
const sidecarByExact = new Set(map.map((e) => e.sourceUrl))
|
||||
const sidecarByNormalized = new Set(map.map((e) => normalizeUrl(e.sourceUrl)))
|
||||
const wxr = await readFile(wxrPath, 'utf8')
|
||||
const attachmentUrls = [...wxr.matchAll(/<wp:attachment_url><!\[CDATA\[([^\]]*)\]\]><\/wp:attachment_url>/g)].map(
|
||||
(m) => m[1],
|
||||
)
|
||||
// CDATA 与裸文本两种形态都匹配(评审加固:WXR 导出器未必总包 CDATA);分支互斥,m[1] ?? m[2]
|
||||
const attachmentUrls = [
|
||||
...wxr.matchAll(/<wp:attachment_url>(?:<!\[CDATA\[([^\]]*)\]\]>|([^<]*))<\/wp:attachment_url>/g),
|
||||
].map((m) => m[1] ?? m[2] ?? '')
|
||||
const seen = new Set()
|
||||
const hitsExact = [] // 归一前即完全相等
|
||||
const hitsNormalized = [] // 仅归一后相等(大小写/尾斜杠救回)
|
||||
@@ -156,6 +164,7 @@ function parseArgs(argv) {
|
||||
|
||||
async function main() {
|
||||
const args = parseArgs(process.argv.slice(2))
|
||||
assertValidSiteId(args.siteId)
|
||||
const sql = exportSql(args.siteId)
|
||||
|
||||
process.stderr.write(`[export-media-map] 只读查询:docker exec ${args.container} psql -U ${args.user} -d ${args.db}\n`)
|
||||
|
||||
Reference in New Issue
Block a user