Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
verebes opened this issue Nov 13, 2018 · 2 comments

Comments

@verebes
Copy link

verebes commented Nov 13, 2018

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();
	}
@verebes verebes 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 Nov 14, 2018
@5saviahv
Copy link
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.

@Month7
Copy link

Month7 commented May 11, 2021

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants