{"record":{"id":"aa72235a0a61f0b8","repo":"AlistGo/alist","slug":"negative-file-size","errorCode":null,"errorMessage":"negative file size","messagePattern":"negative file size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/chunker/util.go","lineNumber":236,"sourceCode":"func unmarshalMetadata(data []byte) (*chunkMetadata, error) {\n\tif len(data) > maxMetadataSizeWrite {\n\t\treturn nil, errors.New(\"metadata is too large\")\n\t}\n\tif data == nil || len(data) < 2 || data[0] != '{' || data[len(data)-1] != '}' {\n\t\treturn nil, errors.New(\"invalid json\")\n\t}\n\tvar meta metadataJSON\n\tif err := json.Unmarshal(data, &meta); err != nil {\n\t\treturn nil, err\n\t}\n\tif meta.Version == nil || meta.Size == nil || meta.ChunkNum == nil {\n\t\treturn nil, errors.New(\"missing required field\")\n\t}\n\tif *meta.Version < 1 {\n\t\treturn nil, errors.New(\"wrong version\")\n\t}\n\tif *meta.Size < 0 {\n\t\treturn nil, errors.New(\"negative file size\")\n\t}\n\tif *meta.ChunkNum < 1 || *meta.ChunkNum > maxSafeChunkNumber {\n\t\treturn nil, errors.New(\"wrong number of chunks\")\n\t}\n\tif meta.MD5 != \"\" {\n\t\tif _, err := hex.DecodeString(meta.MD5); err != nil || len(meta.MD5) != 32 {\n\t\t\treturn nil, errors.New(\"wrong md5 hash\")\n\t\t}\n\t}\n\tif meta.SHA1 != \"\" {\n\t\tif _, err := hex.DecodeString(meta.SHA1); err != nil || len(meta.SHA1) != 40 {\n\t\t\treturn nil, errors.New(\"wrong sha1 hash\")\n\t\t}\n\t}\n\tif *meta.Version > chunkerMetadataVerion {\n\t\treturn nil, errors.New(\"unknown metadata version\")\n\t}\n\treturn &chunkMetadata{","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/chunker/util.go#L218-L254","documentation":"The metadata's size field (original file size in bytes) must be non-negative. A negative value is physically impossible and would corrupt range math when the chunker reassembles the file, so unmarshalMetadata rejects it outright.","triggerScenarios":"A metadata file with \"size\":-1 or any negative number — from corruption, hand editing, integer overflow in an external writer, or a buggy fork. Detected whenever metadata is parsed (listing/opening a chunked file).","commonSituations":"Overflow when another tool computes size as int32/int64 difference that goes negative; metadata edited to 'reset' a file; sync tools mangling numbers.","solutions":["Delete the chunk set and re-upload the original file so the driver records the true size","If writing metadata externally, compute size as an unsigned/absolute byte count","Check for integer overflow in any pre-processing pipeline that sets size"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"var probe struct{ Size *int64 `json:\"size\"` }\nif json.Unmarshal(data, &probe) == nil && probe.Size != nil && *probe.Size < 0 {\n    return fmt.Errorf(\"metadata size must be >= 0, got %d\", *probe.Size)\n}","typeGuard":"func validMetaSize(data []byte) bool {\n    var probe struct{ Size *int64 `json:\"size\"` }\n    return json.Unmarshal(data, &probe) == nil && probe.Size != nil && *probe.Size >= 0\n}","tryCatchPattern":null,"preventionTips":["Compute file sizes from int64 byte counts, never from differences that can underflow","Regenerate metadata via re-upload rather than patching values by hand"],"tags":["chunker","metadata","validation","corruption"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}