{"record":{"id":"ceed8a7fab44915b","repo":"fish2018/pansou","slug":"0","errorCode":null,"errorMessage":"密文长度为0","messagePattern":"密文长度为0","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugin/sdso/sdso.go","lineNumber":391,"sourceCode":"}\n\n// DecryptURL 解密SDSO网站返回的加密URL\n// 输入: Base64编码的密文\n// 输出: 解密后的原始网盘链接\nfunc DecryptURL(encryptedURL string) (string, error) {\n\tif encryptedURL == \"\" {\n\t\treturn \"\", fmt.Errorf(\"加密URL不能为空\")\n\t}\n\n\t// Base64解码\n\tciphertext, err := base64.StdEncoding.DecodeString(encryptedURL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Base64解码失败: %w\", err)\n\t}\n\n\t// 检查密文长度\n\tif len(ciphertext) == 0 {\n\t\treturn \"\", fmt.Errorf(\"密文长度为0\")\n\t}\n\n\t// 检查密文长度是否为16的倍数\n\tif len(ciphertext)%aes.BlockSize != 0 {\n\t\treturn \"\", fmt.Errorf(\"密文长度不是AES块大小的倍数\")\n\t}\n\n\t// 创建AES块加密器\n\tblock, err := aes.NewCipher([]byte(AESKey))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建AES加密器失败: %w\", err)\n\t}\n\n\t// 创建CBC模式解密器\n\tiv := []byte(AESIV)\n\tif len(iv) != aes.BlockSize {\n\t\treturn \"\", fmt.Errorf(\"IV长度不正确: 期望%d，实际%d\", aes.BlockSize, len(iv))\n\t}","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/sdso/sdso.go#L373-L409","documentation":"DecryptURL decoded the Base64 successfully but the resulting ciphertext has zero length, so there is nothing to AES-decrypt. This guards against empty plaintext that would otherwise crash CBC decryption; the plugin counts the item as skipped.","triggerScenarios":"item.URL contained only Base64 padding or decoded to an empty byte slice (e.g. the string \"====\" or an empty-after-trim value) and DecryptURL is called with it.","commonSituations":"Degenerate/corrupted records in the sdso search index; upstream truncation of the URL field; over-trimming of the input string before it reaches DecryptURL.","solutions":["Internal handling: the plugin skips the item; no caller action needed.","If frequent, log sample item.URL values and inspect the source data for truncation upstream.","Treat empty ciphertext the same as empty input: skip before Base64 decoding.","Update the plugin if the site's encoding scheme changed such that legitimate values decode to empty."],"exampleFix":"// before\nenc := strings.TrimSpace(item.URL)\ndecryptedURL, err := DecryptURL(enc)\n// after\nenc := strings.TrimSpace(item.URL)\nif enc == \"\" || enc == \"====\" {\n    skippedCount++\n    continue\n}\ndecryptedURL, err := DecryptURL(enc)","handlingStrategy":"validation","validationCode":"if len(strings.Trim(item.URL, \"=\")) == 0 { /* skip: decodes to empty ciphertext */ }","typeGuard":null,"tryCatchPattern":"decryptedURL, err := DecryptURL(item.URL)\nif err != nil {\n    skippedCount++\n    continue // empty/garbled ciphertext; move to next item\n}","preventionTips":["Validate ciphertext length right after Base64 decoding","Skip degenerate records early instead of decrypting","Monitor skip rates to detect upstream data-quality regressions"],"tags":["decryption","empty-input","validation","go"],"backgroundTag":"empty-required-field","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}