{"record":{"id":"5e3458242ffde542","repo":"fish2018/pansou","slug":"error-5e3458","errorCode":null,"errorMessage":"空响应无法去填充","messagePattern":"空响应无法去填充","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/check_mobile_crypto.go","lineNumber":104,"sourceCode":"\t\t\t}\n\t\t\treturn raw, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"不支持的请求类型: %T\", value)\n\t}\n}\n\nfunc addMobilePadding(data []byte, blockSize int) []byte {\n\tpaddingSize := blockSize - len(data)%blockSize\n\tpadding := make([]byte, paddingSize)\n\tfor index := range padding {\n\t\tpadding[index] = byte(paddingSize)\n\t}\n\treturn append(data, padding...)\n}\n\nfunc removeMobilePadding(data []byte) ([]byte, error) {\n\tif len(data) == 0 {\n\t\treturn nil, fmt.Errorf(\"空响应无法去填充\")\n\t}\n\n\tpaddingSize := int(data[len(data)-1])\n\tif paddingSize <= 0 || paddingSize > len(data) {\n\t\treturn nil, fmt.Errorf(\"填充长度非法\")\n\t}\n\n\tfor index := len(data) - paddingSize; index < len(data); index++ {\n\t\tif data[index] != byte(paddingSize) {\n\t\t\treturn nil, fmt.Errorf(\"填充校验失败\")\n\t\t}\n\t}\n\n\treturn data[:len(data)-paddingSize], nil\n}\n","sourceCodeStart":86,"sourceCodeEnd":120,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/service/check_mobile_crypto.go#L86-L120","documentation":"removeMobilePadding in the mobile check crypto path rejects an empty ciphertext buffer before attempting to strip custom padding. It guards the last-byte padding-size read; an empty payload means decryption produced nothing usable or the caller passed nil/empty data.","triggerScenarios":"decryptMobilePayload calls removeMobilePadding with a zero-length byte slice — the decrypted output was empty because the upstream response body was empty or AES decryption silently produced no data.","commonSituations":"Server returned HTTP 200 with an empty body; a decryption step failed upstream and returned an empty slice instead of an error; wrong key/IV causing a zeroed pipeline result.","solutions":["Validate the encrypted payload is non-empty before decrypting (len(payload) > 0 and a multiple of the block size).","Check why decryptMobilePayload produced empty output — log payload length at each stage.","Fix upstream to return the HTTP error body instead of an empty response."],"exampleFix":"// before\nplain, err := decryptMobilePayload(respBody, key)\n// after\nif len(respBody) == 0 {\n    return fmt.Errorf(\"empty payload\")\n}\nplain, err := decryptMobilePayload(respBody, key)","handlingStrategy":"validation","validationCode":"if len(payload) == 0 || len(payload)%aes.BlockSize != 0 {\n    return fmt.Errorf(\"bad payload length: %d\", len(payload))\n}","typeGuard":null,"tryCatchPattern":"plain, err := removeMobilePadding(data)\nif err != nil {\n    return fmt.Errorf(\"payload undecryptable: %w\", err)\n}","preventionTips":["Check upstream HTTP response is non-empty before decrypting.","Fail loudly upstream instead of passing empty buffers down the crypto pipeline."],"tags":["crypto","padding","validation"],"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"}