Esempio n. 1
0
bool ZLZipHeader::readFrom(ZLInputStream &stream) {
	std::size_t startOffset = stream.offset();
	Signature = readLong(stream);
	switch (Signature) {
		default:
			return stream.offset() == startOffset + 4;
		case SignatureCentralDirectory:
		{
			Version = readLong(stream);
			Flags = readShort(stream);
			CompressionMethod = readShort(stream);
			ModificationTime = readShort(stream);
			ModificationDate = readShort(stream);
			CRC32 = readLong(stream);
			CompressedSize = readLong(stream);
			UncompressedSize = readLong(stream);
			if (CompressionMethod == 0 && CompressedSize != UncompressedSize) {
				ZLLogger::Instance().println("zip", "Different compressed & uncompressed size for stored entry; the uncompressed one will be used.");
				CompressedSize = UncompressedSize;
			}
			NameLength = readShort(stream);
			ExtraLength = readShort(stream);
			const unsigned short toSkip = readShort(stream);
			stream.seek(12 + NameLength + ExtraLength + toSkip, false);
			return stream.offset() == startOffset + 42 + NameLength + ExtraLength + toSkip;
		}
		case SignatureLocalFile:
			Version = readShort(stream);
			Flags = readShort(stream);
			CompressionMethod = readShort(stream);
			ModificationTime = readShort(stream);
			ModificationDate = readShort(stream);
			CRC32 = readLong(stream);
			CompressedSize = readLong(stream);
			UncompressedSize = readLong(stream);
			if (CompressionMethod == 0 && CompressedSize != UncompressedSize) {
				ZLLogger::Instance().println("zip", "Different compressed & uncompressed size for stored entry; the uncompressed one will be used.");
				CompressedSize = UncompressedSize;
			}
			NameLength = readShort(stream);
			ExtraLength = readShort(stream);
			return stream.offset() == startOffset + 30 && NameLength != 0;
		case SignatureEndOfCentralDirectory:
		{
			stream.seek(16, false);
			const unsigned short toSkip = readShort(stream);
			stream.seek(toSkip, false);
			UncompressedSize = 0;
			return stream.offset() == startOffset + 18 + toSkip;
		}
		case SignatureData:
			CRC32 = readLong(stream);
			CompressedSize = readLong(stream);
			UncompressedSize = readLong(stream);
			NameLength = 0;
			ExtraLength = 0;
			return stream.offset() == startOffset + 16;
	}
}
Esempio n. 2
0
void ZLZipHeader::skipEntry(ZLInputStream &stream, const ZLZipHeader &header) {
	if (header.Flags & 0x08) {
		stream.seek(header.ExtraLength);
		ZLZDecompressor decompressor((size_t)-1);
		while (decompressor.decompress(stream, 0, 2048) == 2048) {
		}
		stream.seek(16);
	} else {
		stream.seek(header.ExtraLength + header.CompressedSize);
	}
}
Esempio n. 3
0
bool ZLTarHeader::read(ZLInputStream &stream) {
	size_t startOffset = stream.offset();

	char fileName[101];
	stream.read(fileName, 100);
	if (fileName[0] == '\0') {
		return false;
	}
	fileName[100] = '\0';
	if (Name.empty()) {
		Name = fileName;
	}

	stream.seek(24, false);
	
	char fileSizeString[12];
	stream.read(fileSizeString, 12);
	Size = 0;
	for (int i = 0; i < 12; ++i) {
		if (!isdigit(fileSizeString[i])) {
			break;
		}
		Size *= 8;
		Size += fileSizeString[i] - '0';
	}
	
	stream.seek(20, false);
	char linkFlag;
	stream.read(&linkFlag, 1);
	
	IsRegularFile = (linkFlag == '\0') || (linkFlag == '0');

	stream.seek(355, false);
	
	if (((linkFlag == 'L') || (linkFlag == 'K')) && (Name == "././@LongLink") && (Size < 10240)) {
		Name.erase();
		Name.append(Size - 1, '\0');
		stream.read(const_cast<char*>(Name.data()), Size - 1);
		const int skip = 512 - (Size & 0x1ff);
		stream.seek(skip + 1, false);
		return (stream.offset() == startOffset + Size + skip + 512) && read(stream);
	} else {
		DataOffset = stream.offset();
		return DataOffset == startOffset + 512;
	}
}
Esempio n. 4
0
void ZLZipHeader::skipEntry(ZLInputStream &stream, ZLZipHeader &header) {
	switch (header.Signature) {
		default:
			break;
		case SignatureLocalFile:
			if ((header.Flags & 0x08) == 0x08 && header.CompressionMethod != 0) {
				stream.seek(header.ExtraLength, false);
				ZLZDecompressor decompressor((std::size_t)-1);
				std::size_t size;
				do {
					size = decompressor.decompress(stream, 0, 2048);
					header.UncompressedSize += size;
				} while (size == 2048);
				//stream.seek(16, false);
			} else {
				stream.seek(header.ExtraLength + header.CompressedSize, false);
			}
			break;
	}
}
bool PdfBookReader::readReferenceTable(ZLInputStream &stream, int xrefOffset) {
	while (true) {
		stream.seek(xrefOffset, true);
		readLine(stream, myBuffer);
		stripBuffer(myBuffer);
		if (myBuffer != "xref") {
			return false;
		}

		while (true) {
			readLine(stream, myBuffer);
			stripBuffer(myBuffer);
			if (myBuffer == "trailer") {
				break;
			}
			const int index = myBuffer.find(' ');
			const int start = atoi(myBuffer.c_str());
			const int len = atoi(myBuffer.c_str() + index + 1);
			for (int i = 0; i < len; ++i) {
				readLine(stream, myBuffer);
				stripBuffer(myBuffer);
				if (myBuffer.length() != 18) {
					return false;
				}
				const int objectOffset = atoi(myBuffer.c_str());
				const int objectGeneration = atoi(myBuffer.c_str() + 11);
				const bool objectInUse = myBuffer[17] == 'n';
				if (objectInUse) {
					myObjectLocationMap[std::pair<int,int>(start + i, objectGeneration)] = objectOffset;
				}
			}
		}
		char ch = 0;
		shared_ptr<PdfObject> trailer = PdfObject::readObject(stream, ch);
		if (trailer.isNull() || (trailer->type() != PdfObject::DICTIONARY)) {
			return false;
		}
		if (myTrailer.isNull()) {
			myTrailer = trailer;
		}
		PdfDictionaryObject &trailerDictionary = (PdfDictionaryObject&)*trailer;
		shared_ptr<PdfObject> previous = trailerDictionary["Prev"];
		if (previous.isNull()) {
			return true;
		}

		if (previous->type() != PdfObject::INTEGER_NUMBER) {
			return false;
		}
		xrefOffset = ((PdfIntegerObject&)*previous).value();
	}
}
Esempio n. 6
0
ZLTarHeaderCache::ZLTarHeaderCache(ZLInputStream &baseStream) {
	if (!baseStream.open()) {
		return;
	}

	ZLTarHeader header;
	while (header.read(baseStream)) {
		if (header.IsRegularFile) {
			myHeaderMap[header.Name] = header;
		}
		baseStream.seek((header.Size + 0x1ff) & -0x200, false);
		header.erase();
	}
	baseStream.close();
}
Esempio n. 7
0
void ZLZipHeader::skipEntry(ZLInputStream &stream, ZLZipHeader &header) {
	switch (header.Signature) {
		default:
			break;
		case SignatureLocalFile:
			if (header.Flags & 0x08) {
				stream.seek(header.ExtraLength, false);
				AppLog("ZLZDecompressor decompressor %d", (size_t)-1);
				ZLZDecompressor decompressor((size_t)-1);
				size_t size;
				do {
					//AppLog("ZLZipHeader::skipEntry 1");
					size = decompressor.decompress(stream, 0, BUFFER_SIZE);
					//AppLog("decompress size=%d",size);
					header.UncompressedSize += size;
				} while (size == BUFFER_SIZE);
				AppLog("header.UncompressedSize %d",header.UncompressedSize);
				//stream.seek(16, false);
			} else {
				stream.seek(header.ExtraLength + header.CompressedSize, false);
			}
			break;
	}
}
Esempio n. 8
0
bool CHMFileInfo::moveToEntry(ZLInputStream &stream, const std::string &entryName) {
	RecordMap::const_iterator it = myRecords.find(entryName);
	if (it == myRecords.end()) {
		return false;
	}
	RecordInfo recordInfo = it->second;
	if (recordInfo.Section > mySectionInfos.size()) {
		return false;
	}
	if (recordInfo.Section != 0) {
		// TODO: ???
		return false;
	}

	stream.seek(mySection0Offset + recordInfo.Offset, true);
	return true;
}
Esempio n. 9
0
bool PPLBookReader::readDocument(ZLInputStream &stream) {
	std::cout<<"PPLBookReader::readDocument\n";
	if (!stream.open()) {
		return false;
	}

	myModelReader.setMainTextModel();
	myModelReader.pushKind(REGULAR);
	myCurrentParagraph.erase();
	myEmptyLineCounter = 0;

	// "PPL\r\n"
	stream.seek(5);

	size_t size;
	do {
		size = stream.read(myBuffer, BUFFER_SIZE);
		myBuffer[size] = '\0';

		const char *start = myBuffer;
		const char *end = myBuffer + size;
		const char *eol;
		do {
			eol = strchr(start, '\n');
			if (eol != 0) {
				if (start < eol) {
					myConverter->convert(myCurrentParagraph, start, eol);
				}
				addParagraph();
				start = eol + 1;
			} else {
				if (start < end) {
					myConverter->convert(myCurrentParagraph, start, end);
				}
			}
		} while (eol != 0);
	} while (size == BUFFER_SIZE);

	addParagraph();

	stream.close();

	return true;
}
Esempio n. 10
0
HuffDecompressor::HuffDecompressor(ZLInputStream& stream, 
                        const std::vector<unsigned long>::const_iterator beginIt, 
                        const std::vector<unsigned long>::const_iterator endIt,
						const unsigned long endHuffDataOffset, const unsigned long extraFlags) : myExtraFlags(extraFlags), myErrorCode(ERROR_NONE) {
	

	const unsigned long huffHeaderOffset = *beginIt;
	const unsigned long huffRecordsNumber = endIt - beginIt;
	const unsigned long huffDataOffset = *(beginIt + 1);
	
	stream.seek(huffHeaderOffset, true);
	stream.seek(16, false);
	unsigned long cacheTableOffset, baseTableOffset;
	PdbUtil::readUnsignedLongBE(stream, cacheTableOffset);
	PdbUtil::readUnsignedLongBE(stream, baseTableOffset); 
	

	myCacheTable = new unsigned long[256];
	stream.seek(huffHeaderOffset + cacheTableOffset, true);
	for (size_t i = 0; i < 256; ++i) {
		PdbUtil::readUnsignedLongLE(stream, myCacheTable[i]); //LE
	}
	
	myBaseTable = new unsigned long[64]; 
	stream.seek(huffHeaderOffset + baseTableOffset, true);
	for (size_t i = 0; i < 64; ++i) {
		PdbUtil::readUnsignedLongLE(stream, myBaseTable[i]); //LE
	}
	
	stream.seek(huffDataOffset + 12, true);
	PdbUtil::readUnsignedLongBE(stream, myEntryBits);	
	
	size_t huffDataSize = endHuffDataOffset - huffDataOffset;
	myData = new unsigned char[huffDataSize];
	stream.seek(huffDataOffset, true);
	if (huffDataSize == stream.read((char*)myData, huffDataSize)) {	
		myDicts = new unsigned char* [huffRecordsNumber - 1];
		for(size_t i = 0; i < huffRecordsNumber - 1;  ++i) {	
			size_t shift = *(beginIt + i + 1) - huffDataOffset;
			myDicts[i] = myData + shift;
		}
	} else {
		myErrorCode = ERROR_CORRUPTED_FILE;
	}
	
	myTargetBuffer = 0;
	myTargetBufferEnd = 0;
	myTargetBufferPtr = 0;
}
shared_ptr<PdfObject> PdfBookReader::readObjectFromLocation(ZLInputStream &stream, const std::pair<int,int> &address) {
	std::map<std::pair<int,int>,int>::const_iterator jt = myObjectLocationMap.find(address);
	if (jt == myObjectLocationMap.end()) {
		return 0;
	}
	stream.seek(jt->second, true);
	char ch = 0;
	PdfObject::readToken(stream, myBuffer, ch);
	if (address.first != atoi(myBuffer.c_str())) {
		return 0;
	}
	PdfObject::readToken(stream, myBuffer, ch);
	if (address.second != atoi(myBuffer.c_str())) {
		return 0;
	}
	PdfObject::readToken(stream, myBuffer, ch);
	if (myBuffer != "obj") {
		return 0;
	}
	return PdfObject::readObject(stream, ch);
}
Esempio n. 12
0
size_t ZLZDecompressor::decompress(ZLInputStream &stream, char *buffer, size_t maxSize) {
	while ((myBuffer.length() < maxSize) && (myAvailableSize > 0)) {
		size_t size = std::min(myAvailableSize, (size_t)IN_BUFFER_SIZE);

		myZStream->next_in = (Bytef*)myInBuffer;
		myZStream->avail_in = stream.read(myInBuffer, size);
		if (myZStream->avail_in == size) {
			myAvailableSize -= size;
		} else {
			myAvailableSize = 0;
		}
		while (myZStream->avail_in == 0) {
			break;
		}
		while (myZStream->avail_in > 0) {
			myZStream->avail_out = OUT_BUFFER_SIZE;
			myZStream->next_out = (Bytef*)myOutBuffer;
			int code = ::inflate(myZStream, Z_SYNC_FLUSH);
			if ((code != Z_OK) && (code != Z_STREAM_END)) {
				break;
			}
			if (OUT_BUFFER_SIZE == myZStream->avail_out) {
				break;
			}
			myBuffer.append(myOutBuffer, OUT_BUFFER_SIZE - myZStream->avail_out);
			if (code == Z_STREAM_END) {
				myAvailableSize = 0;
				stream.seek(0 - myZStream->avail_in, false);
				break;
			}
		}
	}

	size_t realSize = std::min(maxSize, myBuffer.length());
	if (buffer != 0) {
		memcpy(buffer, myBuffer.data(), realSize);
	}
	myBuffer.erase(0, realSize);
	return realSize;
}
Esempio n. 13
0
bool CHMFileInfo::init(ZLInputStream &stream) {
	{
		// header start
		if (readString(stream, 4) != "ITSF") {
			return false;
		}

		unsigned long version = readUnsignedDWord(stream);

		// DWORD total length
		// DWORD unknown
		// DWORD timestamp
		// DWORD language id
		// 0x10 bytes 1st GUID
		// 0x10 bytes 2nd GUID
		// QWORD section 0 offset
		// QWORD section 0 length
		stream.seek(4 * 4 + 2 * 0x10 + 2 * 8, false);
		
		unsigned long long sectionOffset1 = readUnsignedQWord(stream);
		unsigned long long sectionLength1 = readUnsignedQWord(stream);
		mySection0Offset = sectionOffset1 + sectionLength1;
		// header end

		// additional header data start
		if (version > 2) {
			mySection0Offset = readUnsignedQWord(stream);
		}
		// additional header data end

		stream.seek(sectionOffset1, true);
		// header section 1 start
		// directory header start
		if (readString(stream, 4) != "ITSP") {
			return false;
		}

		// DWORD version
		// DWORD length
		// DWORD 0x000A
		// DWORD chunk size
		// DWORD density
		// DWORD depth
		// DWORD root chunk number
		// DWORD first chunk number
		// DWORD last chunk number
		// DWORD -1
		stream.seek(10 * 4, false);
		unsigned long dirChunkNumber = readUnsignedDWord(stream);
		// ...
		stream.seek(36, false);
		// header section 1 end

		std::size_t nextOffset = stream.offset();
		for (unsigned long i = 0; i < dirChunkNumber; ++i) {
			nextOffset += 4096;
			std::string header = readString(stream, 4);
			if (header == "PMGL") {
				unsigned long quickRefAreaSize = readUnsignedDWord(stream) % 4096;
				stream.seek(12, false);
				std::size_t startOffset = stream.offset();
				std::size_t oldOffset = startOffset;
				while (startOffset < nextOffset - quickRefAreaSize) {
					int nameLength = readEncodedInteger(stream);
					std::string name = readString(stream, nameLength);
					int contentSection = readEncodedInteger(stream);
					int offset = readEncodedInteger(stream);
					int length = readEncodedInteger(stream);
					if (name.substr(0, 2) != "::") {
						name = ZLUnicodeUtil::toLower(name);
					}
					myRecords.insert(
						std::make_pair(
							name,
							CHMFileInfo::RecordInfo(contentSection, offset, length)
						)
					);
					startOffset = stream.offset();
					if (oldOffset == startOffset) {
						break;
					}
					oldOffset = startOffset;
				}
			} else if (header == "PMGI") {
				unsigned long quickRefAreaSize = readUnsignedDWord(stream);
				std::size_t startOffset = stream.offset();
				std::size_t oldOffset = startOffset;
				while (startOffset < nextOffset - quickRefAreaSize) {
					int nameLength = readEncodedInteger(stream);
					std::string name = readString(stream, nameLength);
					// chunk number
					readEncodedInteger(stream);
					startOffset = stream.offset();
					if (oldOffset == startOffset) {
						break;
					}
					oldOffset = startOffset;
				}
			}
			stream.seek(nextOffset, true);
			if (stream.offset() != nextOffset) {
				break;
			}
		}
	}

	{
		if (!moveToEntry(stream, "::DataSpace/NameList")) {
			return false;
		}
		stream.seek(2, false);
		const int sectionNumber = readUnsignedWord(stream);
		for (int i = 0; i < sectionNumber; ++i) {
			const int length = readUnsignedWord(stream);
			std::string sectionName;
			sectionName.reserve(length);
			for (int j = 0; j < length; ++j) {
				sectionName += (char)readUnsignedWord(stream);
			}
			stream.seek(2, false);
			mySectionNames.push_back(sectionName);
		}
	}

	{
		for (unsigned int i = 1; i < mySectionNames.size(); ++i) {
			RecordMap::const_iterator it =
				myRecords.find("::DataSpace/Storage/" + mySectionNames[i] + "/Content");
			if (it == myRecords.end()) {
				return false;
			}
			RecordInfo recordInfo = it->second;
			if (recordInfo.Section != 0) {
				return false;
			}
			mySectionInfos.push_back(SectionInfo());
			SectionInfo &info = mySectionInfos.back();
			info.Offset = mySection0Offset + recordInfo.Offset;
			info.Length = recordInfo.Length;

			if (!moveToEntry(stream, "::DataSpace/Storage/" + mySectionNames[i] + "/ControlData")) {
				return false;
			}
			stream.seek(4, false);
			std::string lzxc = readString(stream, 4);
			if (lzxc != "LZXC") {
				return false;
			}
			const int version = readUnsignedDWord(stream);
			if ((version <= 0) || (version > 2)) {
				return false;
			}
			info.ResetInterval = readUnsignedDWord(stream);
			if (version == 1) {
				info.ResetInterval /= 0x8000;
			}
			info.WindowSizeIndex = (version == 1) ? 0 : 15;
			{
				int ws = readUnsignedDWord(stream);
				if (ws > 0) {
					while ((ws & 1) == 0) {
						ws >>= 1;
						info.WindowSizeIndex++;
					}
				}
			}

			if (!moveToEntry(stream, "::DataSpace/Storage/" + mySectionNames[i] + "/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable")) {
				return false;
			}
			stream.seek(4, false);
			const std::size_t entriesNumber = readUnsignedDWord(stream);
			if (entriesNumber == 0) {
				return false;
			}
			if (entriesNumber > 2048) {
				// file size is greater than 60 Mb
				return false;
			}
			info.ResetTable.reserve(entriesNumber);
			stream.seek(8, false);
			info.UncompressedSize = readUnsignedQWord(stream);
			if ((info.UncompressedSize - 1) / 0x8000 != entriesNumber - 1) {
				return false;
			}
			info.CompressedSize = readUnsignedQWord(stream);
			stream.seek(8, false);
			std::size_t previous = 0;
			for (std::size_t j = 0; j < entriesNumber; ++j) {
				std::size_t value = readUnsignedQWord(stream);
				if ((j > 0) == (value <= previous)) {
					return false;
				}
				info.ResetTable.push_back(value);
				previous = value;
			}
		}
	}

	return true;
}