core-bundle/src/Resources/contao/library/Contao/ZipReader.php
protected function readCentralDirectory()
	{
		$strMbCharset = null;

		// Set the mbstring encoding to ASCII (see #5842)
		if (ini_get('mbstring.func_overload') > 0)
		{
			$strMbCharset = mb_internal_encoding();

			if (mb_internal_encoding('ASCII') === false)
			{
				$strMbCharset = null;
			}
		}

		$intOffset = 0;
		$pos = 0;
		$intInterval = min(filesize($this->strRootDir . '/' . $this->strFile), 1024);
		$strBuffer = '';

		// Read to delimiter
		do
		{
			$intOffset -= $intInterval;

			$fseek = @fseek($this->resFile, $intOffset, SEEK_END);
			$strBuffer = @fread($this->resFile, abs($intOffset)) . $strBuffer;
		}
		while ($fseek != -1 && ($pos = strpos($strBuffer, self::CENTRAL_DIR_END)) === false);

		// Reposition pointer
		fseek($this->resFile, ($intOffset + $pos), SEEK_END);
		$strSignature = @fread($this->resFile, 4);

		// Read archive header
		if ($strSignature != self::CENTRAL_DIR_END)
		{
			throw new \Exception('Error reading central directory');
		}

		$arrHeader = array();

		$arrHeader['number_of_this_disk']    = unpack('v', @fread($this->resFile, 2));
		$arrHeader['number_of_disk_with_cd'] = unpack('v', @fread($this->resFile, 2));
		$arrHeader['total_cd_entries_disk']  = unpack('v', @fread($this->resFile, 2));
		$arrHeader['total_cd_entries']       = unpack('v', @fread($this->resFile, 2));
		$arrHeader['size_of_cd']             = unpack('V', @fread($this->resFile, 4));
		$arrHeader['offset_start_cd']        = unpack('V', @fread($this->resFile, 4));
		$arrHeader['zipfile_comment_length'] = unpack('v', @fread($this->resFile, 2));
		$arrHeader['zipfile_comment']        = $arrHeader['zipfile_comment_length'][1] ? @fread($this->resFile, $arrHeader['zipfile_comment_length'][1]) : '';

		// Eliminate nested arrays
		foreach ($arrHeader as $k=>$v)
		{
			$arrHeader[$k] = \is_array($v) ? $v[1] : $v;
		}

		$this->arrHeader = $arrHeader;

		// Reposition pointer to begin of the central directory
		fseek($this->resFile, $this->arrHeader['offset_start_cd'], SEEK_SET);
		$strSignature = @fread($this->resFile, 4);

		// Build file list
		while ($strSignature == self::CENTRAL_DIR_START)
		{
			$arrFile = array();

			$arrFile['version_made_by']           = unpack('v', @fread($this->resFile, 2));
			$arrFile['version_needed_to_extract'] = unpack('v', @fread($this->resFile, 2));
			$arrFile['general_purpose_bit_flag']  = unpack('v', @fread($this->resFile, 2));
			$arrFile['compression_method']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['last_mod_file_time']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['last_mod_file_date']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['crc-32']                    = unpack('V', @fread($this->resFile, 4));
			$arrFile['compressed_size']           = unpack('V', @fread($this->resFile, 4));
			$arrFile['uncompressed_size']         = unpack('V', @fread($this->resFile, 4));
			$arrFile['file_name_length']          = unpack('v', @fread($this->resFile, 2));
			$arrFile['extra_field_length']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['file_comment_length']       = unpack('v', @fread($this->resFile, 2));
			$arrFile['disk_number_start']         = unpack('v', @fread($this->resFile, 2));
			$arrFile['internal_file_attributes']  = unpack('v', @fread($this->resFile, 2));
			$arrFile['external_file_attributes']  = unpack('V', @fread($this->resFile, 4));
			$arrFile['offset_of_local_header']    = unpack('V', @fread($this->resFile, 4));
			$arrFile['file_name']                 = @fread($this->resFile, $arrFile['file_name_length'][1]);
			$arrFile['extra_field']               = $arrFile['extra_field_length'][1] ? @fread($this->resFile, $arrFile['extra_field_length'][1]) : '';
			$arrFile['file_comment']              = $arrFile['file_comment_length'][1] ? @fread($this->resFile, $arrFile['file_comment_length'][1]) : '';

			// Skip directories
			if (substr($arrFile['file_name'], -1) == '/')
			{
				$strSignature = @fread($this->resFile, 4);
				continue;
			}

			// Eliminate nested arrays
			foreach ($arrFile as $k=>$v)
			{
				$arrFile[$k] = \is_array($v) ? $v[1] : $v;
			}

			// Split file path
			$arrFile['file_basename'] = basename($arrFile['file_name']);
			$arrFile['file_dirname'] = (($path = \dirname($arrFile['file_name'])) != '.' ? $path : '');

			// Add UNIX time
			$arrFile['last_mod_file_unix'] = $this->decToUnix((int) $arrFile['last_mod_file_time'], (int) $arrFile['last_mod_file_date']);

			// Read next signature
			$strSignature = @fread($this->resFile, 4);
			$this->arrFiles[] = $arrFile;
		}

		$this->intLast = (\count($this->arrFiles) - 1);

		// Restore the mbstring encoding (see #5842)
		$strMbCharset && mb_internal_encoding($strMbCharset);
	}
protected function readCentralDirectory()
	{
		$strMbCharset = null;

		// Set the mbstring encoding to ASCII (see #5842)
		if (ini_get('mbstring.func_overload') > 0)
		{
			$strMbCharset = mb_internal_encoding();

			if (mb_internal_encoding('ASCII') === false)
			{
				$strMbCharset = null;
			}
		}

		$intOffset = 0;
		$pos = 0;
		$intInterval = min(filesize($this->strRootDir . '/' . $this->strFile), 1024);
		$strBuffer = '';

		// Read to delimiter
		do
		{
			$intOffset -= $intInterval;

			$fseek = @fseek($this->resFile, $intOffset, SEEK_END);
			$strBuffer = @fread($this->resFile, abs($intOffset)) . $strBuffer;
		}
		while ($fseek != -1 && ($pos = strpos($strBuffer, self::CENTRAL_DIR_END)) === false);

		// Reposition pointer
		fseek($this->resFile, ($intOffset + $pos), SEEK_END);
		$strSignature = @fread($this->resFile, 4);

		// Read archive header
		if ($strSignature != self::CENTRAL_DIR_END)
		{
			throw new \Exception('Error reading central directory');
		}

		$arrHeader = array();

		$arrHeader['number_of_this_disk']    = unpack('v', @fread($this->resFile, 2));
		$arrHeader['number_of_disk_with_cd'] = unpack('v', @fread($this->resFile, 2));
		$arrHeader['total_cd_entries_disk']  = unpack('v', @fread($this->resFile, 2));
		$arrHeader['total_cd_entries']       = unpack('v', @fread($this->resFile, 2));
		$arrHeader['size_of_cd']             = unpack('V', @fread($this->resFile, 4));
		$arrHeader['offset_start_cd']        = unpack('V', @fread($this->resFile, 4));
		$arrHeader['zipfile_comment_length'] = unpack('v', @fread($this->resFile, 2));
		$arrHeader['zipfile_comment']        = $arrHeader['zipfile_comment_length'][1] ? @fread($this->resFile, $arrHeader['zipfile_comment_length'][1]) : '';

		// Eliminate nested arrays
		foreach ($arrHeader as $k=>$v)
		{
			$arrHeader[$k] = \is_array($v) ? $v[1] : $v;
		}

		$this->arrHeader = $arrHeader;

		// Reposition pointer to begin of the central directory
		fseek($this->resFile, $this->arrHeader['offset_start_cd'], SEEK_SET);
		$strSignature = @fread($this->resFile, 4);

		// Build file list
		while ($strSignature == self::CENTRAL_DIR_START)
		{
			$arrFile = array();

			$arrFile['version_made_by']           = unpack('v', @fread($this->resFile, 2));
			$arrFile['version_needed_to_extract'] = unpack('v', @fread($this->resFile, 2));
			$arrFile['general_purpose_bit_flag']  = unpack('v', @fread($this->resFile, 2));
			$arrFile['compression_method']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['last_mod_file_time']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['last_mod_file_date']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['crc-32']                    = unpack('V', @fread($this->resFile, 4));
			$arrFile['compressed_size']           = unpack('V', @fread($this->resFile, 4));
			$arrFile['uncompressed_size']         = unpack('V', @fread($this->resFile, 4));
			$arrFile['file_name_length']          = unpack('v', @fread($this->resFile, 2));
			$arrFile['extra_field_length']        = unpack('v', @fread($this->resFile, 2));
			$arrFile['file_comment_length']       = unpack('v', @fread($this->resFile, 2));
			$arrFile['disk_number_start']         = unpack('v', @fread($this->resFile, 2));
			$arrFile['internal_file_attributes']  = unpack('v', @fread($this->resFile, 2));
			$arrFile['external_file_attributes']  = unpack('V', @fread($this->resFile, 4));
			$arrFile['offset_of_local_header']    = unpack('V', @fread($this->resFile, 4));
			$arrFile['file_name']                 = @fread($this->resFile, $arrFile['file_name_length'][1]);
			$arrFile['extra_field']               = $arrFile['extra_field_length'][1] ? @fread($this->resFile, $arrFile['extra_field_length'][1]) : '';
			$arrFile['file_comment']              = $arrFile['file_comment_length'][1] ? @fread($this->resFile, $arrFile['file_comment_length'][1]) : '';

			// Skip directories
			if (substr($arrFile['file_name'], -1) == '/')
			{
				$strSignature = @fread($this->resFile, 4);
				continue;
			}

			// Eliminate nested arrays
			foreach ($arrFile as $k=>$v)
			{
				$arrFile[$k] = \is_array($v) ? $v[1] : $v;
			}

			// Split file path
			$arrFile['file_basename'] = basename($arrFile['file_name']);
			$arrFile['file_dirname'] = (($path = \dirname($arrFile['file_name'])) != '.' ? $path : '');

			// Add UNIX time
			$arrFile['last_mod_file_unix'] = $this->decToUnix((int) $arrFile['last_mod_file_time'], (int) $arrFile['last_mod_file_date']);

			// Read next signature
			$strSignature = @fread($this->resFile, 4);
			$this->arrFiles[] = $arrFile;
		}

		$this->intLast = (\count($this->arrFiles) - 1);

		// Restore the mbstring encoding (see #5842)
		$strMbCharset && mb_internal_encoding($strMbCharset);
	}
Return a list of all files in the archive

@throws \Exception If the central directory cannot be found