{"record":{"id":"fafbdcdc37a1eebc","repo":"AlistGo/alist","slug":"errarchiveillegalpath-fafbdc","errorCode":"ErrArchiveIllegalPath","errorMessage":"archive entry has illegal path: %s","messagePattern":"archive entry has illegal path: (.+?)","errorType":"exception","errorClass":"ErrArchiveIllegalPath","httpStatus":null,"severity":"error","filePath":"internal/archive/rardecode/utils.go","lineNumber":189,"sourceCode":"\t}\n\topts := []rardecode.Option{fsOpt}\n\tif password != \"\" {\n\t\topts = append(opts, rardecode.Password(password))\n\t}\n\trc, err := rardecode.OpenReader(fileName, opts...)\n\tif err != nil {\n\t\treturn nil, filterPassword(err)\n\t}\n\tss[0].Closers.Add(rc)\n\treturn &rc.Reader, nil\n}\n\nfunc decompress(reader *rardecode.Reader, header *rardecode.FileHeader, dstPath string, limiter *tool.SizeLimiter) error {\n\tif header.IsDir {\n\t\treturn os.MkdirAll(dstPath, 0700)\n\t}\n\tif !header.Mode().IsRegular() {\n\t\treturn fmt.Errorf(\"%w: %s\", tool.ErrArchiveIllegalPath, header.Name)\n\t}\n\tif err := os.MkdirAll(filepath.Dir(dstPath), 0700); err != nil {\n\t\treturn err\n\t}\n\treturn _decompress(reader, header, dstPath, func(_ float64) {}, limiter)\n}\n\nfunc _decompress(reader *rardecode.Reader, header *rardecode.FileHeader, dstPath string, up model.UpdateProgress, limiter *tool.SizeLimiter) error {\n\tf, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() { _ = f.Close() }()\n\t_, err = io.Copy(limiter.WrapWriter(f), &stream.ReaderUpdatingProgress{\n\t\tReader: &stream.SimpleReaderWithSize{\n\t\t\tReader: reader,\n\t\t\tSize:   header.UnPackedSize,\n\t\t},","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/archive/rardecode/utils.go#L171-L207","documentation":"Per-entry guard in internal/archive/rardecode/utils.go decompress(): after handling directory headers, any RAR entry whose header.Mode() is not regular (symlink/device/FIFO) fails with ErrArchiveIllegalPath before the output file is created with O_EXCL.","triggerScenarios":"Single-file or nested extraction of a RAR entry that is a symlink or other special type — the final copy step re-checks the mode the rardecode library reported for the header.","commonSituations":"Same as the rardecode walker guard: Linux-flavored rars with links; corrupted headers misreporting modes.","solutions":["Extract with a native RAR tool if special entries must be preserved","Repack without special entries","Verify the rar with 'rar t' / 'unrar t' to rule out corruption"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":"func rarHeaderSafe(h *rardecode.FileHeader) bool {\n    return h.IsDir || h.Mode().IsRegular()\n}","tryCatchPattern":"if err := decompress(reader, header, dstPath, limiter); err != nil {\n    if errors.Is(err, tool.ErrArchiveIllegalPath) {\n        return fmt.Errorf(\"unsafe rar member %q: %w\", header.Name, err)\n    }\n    return err\n}","preventionTips":["Validate rar headers (mode) in custom tooling before delegating extraction","Verify rar integrity with 'rar t' to rule out corrupted mode fields","Never patch out the IsRegular check to 'make it work'"],"tags":["archive","rar","security","symlink","extraction"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}