Skip to content

archive/zip: checksum error in readDataDescriptor when reading valid zip file #66157

Description

@Mechstud

Go version

go version go1.22.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/madhurbhaiya/.cache/go-build'
GOENV='/home/madhurbhaiya/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/madhurbhaiya/go/pkg/mod'
GONOPROXY='github.com/KDKSoftware/Skeleton-Backend-Go'
GONOSUMDB='github.com/KDKSoftware/Skeleton-Backend-Go'
GOOS='linux'
GOPATH='/home/madhurbhaiya/go'
GOPRIVATE='github.com/KDKSoftware/Skeleton-Backend-Go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/code/TDS-Backend-Go/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3946127579=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I have a zip file, which I can extract / read using standard zip reader of OS (Ubuntu / Windows etc.). However, on reading the same zip file using archive/zip package, I am getting zip: checksum error

The zip file is: checksum-error.zip

I could get the file extracted out to a new destination, but then the zip.Read() method fails with ErrChecksum

A sample code to reproduce this behaviour (in the code below, basePath can be changed to your local filesystem directory, where zip is placed):

package main

import (
	"archive/zip"
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
)
func main() {
	// Specify the path of the directory where zip file is placed
	basePath := "/home/madhurbhaiya/Downloads"
	inputZipFilePath := filepath.Join(basePath, "checksum-error.zip")

	// Open the zip reader
	zipFile, err := zip.OpenReader(inputZipFilePath)
	if err != nil {
		fmt.Println(err)
		return
	}
	if len(zipFile.File) == 0 {
		fmt.Println("No files in the input zip")
		return
	}

	for _, zipFl := range zipFile.File {
		destFilePath := filepath.Join(basePath,"extracted-" + zipFl.Name)
		if err = ExtractFileFromZip(zipFl, destFilePath); err != nil {
			fmt.Println(err)
		}
	}
}

// ExtractFileFromZip extracts a file from given zip srcfile and stores the content at destFilePath
func ExtractFileFromZip(srcfile *zip.File, destFilePath string) error {
	// Open the Zip file
	src, err := srcfile.Open()
	if err != nil {
		return err
	}
	defer func(src io.ReadCloser) {
		err = src.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(src)

	// Create the destintation file
	_ = os.MkdirAll(filepath.Dir(destFilePath), os.ModePerm)
	out, err := os.Create(destFilePath)
	if err != nil {
		return err
	}
	defer func(out *os.File) {
		err = out.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(out)

	// Copy in chunks for G110: Potential DoS vulnerability via decompression bomb (gosec)
	err = nil // Reinitialize err
	for {
		_, err = io.CopyN(out, src, 1024_00) // 100 * 1024 = 100 kB
		if err != nil {
			break
		}
	}
	// Reached EOF - All ok, else it is some other error, Need to return it.
	if errors.Is(err, io.EOF) {
		return nil
	}
	return err
}

What did you see happen?

Output of the mentioned sample code is:

zip: checksum error

Process finished with the exit code 0

What did you expect to see?

No errors.

The zip file can be read successfully using other softwares.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions