Skip to content

Extracting from Buffer with trailing zeros cause 'Invalid or unsupported zip format. No END header found' error #264

Closed

Description

@verebes

Problem

I try to call getEntries() on an AdmZip object initialized with a Buffer object. The buffer is larger than the actual zip content so there are trailing zeros after the ENDSIG (PK\005\006).
When I try to extract the file I get "Invalid or unsupported zip format. No END header found" error.

How to reproduce:

  • Initialize a large buffer with zeros
  • Copy the zip content into the buffer ( leave at least 65535 zeros in the buffer after the zip content )
  • Create an AdmZip object with the buffer
  • Try to call the getEntries() method on the AdmZip
    ---> you should get "Invalid or unsupported zip format. No END header found" error

Reason:

In the zipFile.js, readMainHeader() checks the existence of the END header (PK\005\006).
But it is assumed that the END header is in the last 0xFFFF bytes, because this is the maximum zip file comment length. But this is not true if there are trailing zero bytes.

How to fix:

skip the trailing zero bytes before searching the END header. Take care, there can be trailing zeros in the END header too, so we can not start the search from the end - 22 bytes (where 22 bytes is the size of the end header)


	function readMainHeader() {
		var i = inBuffer.length -1,			
			endOffset = -1; // Start offset of the END header
		while ( inBuffer[i] === 0x00 ) {
			i--;
		} 
		// i is the index of the last non-zero value

		var n = Math.max(0, i - ( 0xFFFF + Utils.Constants.ENDHDR)); // 0xFFFF is the max zip file comment length
		i = Math.max(0, i - 3); //  "PK\005\006"
		for (i; i >= n; i--) {
			if (inBuffer[i] !== 0x50) continue; // quick check that the byte is 'P'
			if (inBuffer.readUInt32LE(i) === Utils.Constants.ENDSIG) { // "PK\005\006"
				endOffset = i;
				break;
			}
		}
		if (!~endOffset)
			throw Utils.Errors.INVALID_FORMAT;

		mainHeader.loadFromBinary(inBuffer.slice(endOffset, endOffset + Utils.Constants.ENDHDR));
		if (mainHeader.commentLength) {
			_comment = inBuffer.slice(endOffset + Utils.Constants.ENDHDR);
		}
		readEntries();
	}

Activity

  1. changed the title [-]Extracting from Buffer with leading zeros cause 'Invalid or unsupported zip format. No END header found' error[/-] [+]Extracting from Buffer with trailing zeros cause 'Invalid or unsupported zip format. No END header found' error[/+] on Nov 14, 2018
  2. 5saviahv commented on May 28, 2019

    @5saviahv
    Collaborator

    It is not wrong approach what adm-zip does, but many programs search header from entire file. So you can include something like recovery records, signatures etc to the end of you file.

  3. Month7 commented on May 11, 2021

    @Month7

    I have the same problem, how can I solve this problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions