fix(release-cleanup): 加入分頁上限並編碼刪除 URL 路徑片段
- fetchAllPages 加入 MAX_PAGES(1000)安全斷點,避免 API 異常時無限迴圈 - 刪除 release/tag 時對 id 與 tag 名稱做 encodeURIComponent, 防止特殊字元造成路徑穿越(正常數值/版本字串編碼後不變) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
49ac5d4ec4
commit
aa4f6364e2
@@ -4,6 +4,9 @@
|
|||||||
// 單一 HTTP 請求的逾時(毫秒)。避免 API 緩慢或掛起時容器永久卡死。
|
// 單一 HTTP 請求的逾時(毫秒)。避免 API 緩慢或掛起時容器永久卡死。
|
||||||
const REQUEST_TIMEOUT_MS = 30000
|
const REQUEST_TIMEOUT_MS = 30000
|
||||||
|
|
||||||
|
// 分頁讀取的最大頁數上限,作為安全斷點:即使 API 異常未以空陣列結尾,也不致無限迴圈耗盡資源。
|
||||||
|
const MAX_PAGES = 1000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 將回應內容整理成可安全寫入錯誤訊息的片段:移除控制字元(避免換行等造成的 log 注入)並限制長度。
|
* 將回應內容整理成可安全寫入錯誤訊息的片段:移除控制字元(避免換行等造成的 log 注入)並限制長度。
|
||||||
* @param {string} text 原始回應文字
|
* @param {string} text 原始回應文字
|
||||||
@@ -49,6 +52,10 @@ export class GiteaClient {
|
|||||||
let page = 1
|
let page = 1
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (page > MAX_PAGES) {
|
||||||
|
throw new Error(`GET ${baseUrl} exceeded MAX_PAGES (${MAX_PAGES}); aborting to avoid an unbounded loop`)
|
||||||
|
}
|
||||||
|
|
||||||
const url = `${baseUrl}?page=${page}`
|
const url = `${baseUrl}?page=${page}`
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
|
|||||||
+2
-1
@@ -56,7 +56,8 @@ export async function cleanupReleases(client, config) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${config.releaseApiUrl}/${id}`
|
// 對 id 做編碼,避免非預期內容被拼接進 URL(防路徑穿越);正常數值 id 編碼後不變。
|
||||||
|
const url = `${config.releaseApiUrl}/${encodeURIComponent(id)}`
|
||||||
info(`DELETE ${tag} (${name})`)
|
info(`DELETE ${tag} (${name})`)
|
||||||
|
|
||||||
const code = await client.deleteResource(url)
|
const code = await client.deleteResource(url)
|
||||||
|
|||||||
+2
-1
@@ -61,7 +61,8 @@ export async function cleanupOrphanTags(client, config) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `${config.tagApiUrl}/${tag.name}`
|
// 對 tag 名稱做編碼,避免名稱中的特殊字元被拼接進 URL(防路徑穿越);一般 tag 名編碼後不變。
|
||||||
|
const url = `${config.tagApiUrl}/${encodeURIComponent(tag.name)}`
|
||||||
info(`DELETE tag ${tag.name}`)
|
info(`DELETE tag ${tag.name}`)
|
||||||
|
|
||||||
const code = await client.deleteResource(url)
|
const code = await client.deleteResource(url)
|
||||||
|
|||||||
Reference in New Issue
Block a user