void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) { d.VolFlags = ReadByte(); ReadBytes(d.SystemId, sizeof(d.SystemId)); ReadBytes(d.VolumeId, sizeof(d.VolumeId)); SkipZeros(8); d.VolumeSpaceSize = ReadUInt32(); ReadBytes(d.EscapeSequence, sizeof(d.EscapeSequence)); d.VolumeSetSize = ReadUInt16(); d.VolumeSequenceNumber = ReadUInt16(); d.LogicalBlockSize = ReadUInt16(); d.PathTableSize = ReadUInt32(); d.LPathTableLocation = ReadUInt32Le(); d.LOptionalPathTableLocation = ReadUInt32Le(); d.MPathTableLocation = ReadUInt32Be(); d.MOptionalPathTableLocation = ReadUInt32Be(); ReadDirRecord(d.RootDirRecord); ReadBytes(d.VolumeSetId, sizeof(d.VolumeSetId)); ReadBytes(d.PublisherId, sizeof(d.PublisherId)); ReadBytes(d.DataPreparerId, sizeof(d.DataPreparerId)); ReadBytes(d.ApplicationId, sizeof(d.ApplicationId)); ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId)); ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId)); ReadBytes(d.BibFileId, sizeof(d.BibFileId)); ReadDateTime(d.CTime); ReadDateTime(d.MTime); ReadDateTime(d.ExpirationTime); ReadDateTime(d.EffectiveTime); d.FileStructureVersion = ReadByte(); // = 1 SkipZeros(1); ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); SkipZeros(653); }
bool AtomMDHD::ReadDataVersion1() { if (!ReadUInt64(_creationTime)) { FATAL("Unable to read creation time"); return false; } if (!ReadUInt64(_modificationTime)) { FATAL("Unable to read modification time"); return false; } if (!ReadUInt32(_timeScale)) { FATAL("Unable to read time scale"); return false; } if (!ReadUInt64(_duration)) { FATAL("Unable to read duration"); return false; } if (!ReadUInt16(_language)) { FATAL("Unable to read language"); return false; } if (!ReadUInt16(_quality)) { FATAL("Unable to read quality"); return false; } return true; }
bool AtomSMHD::ReadData() { if (!ReadUInt16(_balance)) { FATAL("Unable to read balance"); return false; } if (!ReadUInt16(_reserved)) { FATAL("Unable to read reserved"); return false; } return true; }
CStringW CFileDataIO::ReadStringUTF8() { UINT uRawSize = ReadUInt16(); const UINT uMaxShortRawSize = SHORT_RAW_ED2K_UTF8_STR; if (uRawSize <= uMaxShortRawSize) { char acRaw[uMaxShortRawSize]; Read(acRaw, uRawSize); WCHAR awc[uMaxShortRawSize]; int iChars = ByteStreamToWideChar(acRaw, uRawSize, awc, ARRSIZE(awc)); if (iChars >= 0) return CStringW(awc, iChars); return CStringW(acRaw, uRawSize); // use local codepage } else { Array<char> acRaw(uRawSize); Read(acRaw, uRawSize); Array<WCHAR> awc(uRawSize); int iChars = ByteStreamToWideChar(acRaw, uRawSize, awc, uRawSize); if (iChars >= 0) return CStringW(awc, iChars); return CStringW(acRaw, uRawSize); // use local codepage; } }
std::string BinaryStream::ReadString() { if(myGetPos+2 > myBuffer.size()) { myGetPos = myBuffer.size(); return ""; } uint16_t size = ReadUInt16(); if(myGetPos+size+1 > myBuffer.size()) { myGetPos = myBuffer.size(); return ""; } bool nowrite = false; std::string ret; for(uint16_t i = 0; i < size; i++) { if(myBuffer[myGetPos] == 0) nowrite = true; else if(!nowrite) ret += myBuffer[myGetPos]; myGetPos++; } myGetPos++; return ret; }
uint64 CFileDataIO::GetIntTagValue() const { uint8 type = ReadUInt8(); ReadString(false); switch (type) { case TAGTYPE_UINT64: return ReadUInt64(); break; case TAGTYPE_UINT32: return ReadUInt32(); break; case TAGTYPE_UINT16: return ReadUInt16(); break; case TAGTYPE_UINT8: return ReadUInt8(); break; default: throw wxString(wxT("Wrong tag type reading int tag")); } }
bool EXIFParser::ParseOrientation(uint16_t aType, uint32_t aCount, Orientation& aOut) { // Sanity check the type and count. if (aType != ShortType || aCount != 1) return false; uint16_t value; if (!ReadUInt16(value)) return false; switch (value) { case 1: aOut = Orientation(Angle::D0, Flip::Unflipped); break; case 2: aOut = Orientation(Angle::D0, Flip::Horizontal); break; case 3: aOut = Orientation(Angle::D180, Flip::Unflipped); break; case 4: aOut = Orientation(Angle::D180, Flip::Horizontal); break; case 5: aOut = Orientation(Angle::D90, Flip::Horizontal); break; case 6: aOut = Orientation(Angle::D90, Flip::Unflipped); break; case 7: aOut = Orientation(Angle::D270, Flip::Horizontal); break; case 8: aOut = Orientation(Angle::D270, Flip::Unflipped); break; default: return false; } // This is a 32-bit field, but the orientation value only occupies the first // 16 bits. We need to advance another 16 bits to consume the entire field. Advance(2); return true; }
void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) { r.ExtendedAttributeRecordLen = ReadByte(); if (r.ExtendedAttributeRecordLen != 0) throw 1; r.ExtentLocation = ReadUInt32(); r.DataLength = ReadUInt32(); ReadRecordingDateTime(r.DateTime); r.FileFlags = ReadByte(); r.FileUnitSize = ReadByte(); r.InterleaveGapSize = ReadByte(); r.VolSequenceNumber = ReadUInt16(); Byte idLen = ReadByte(); r.FileId.SetCapacity(idLen); ReadBytes((Byte *)r.FileId, idLen); int padSize = 1 - (idLen & 1); // SkipZeros(1 - (idLen & 1)); Skip(1 - (idLen & 1)); // it's bug in some cd's. Must be zeros int curPos = 33 + idLen + padSize; if (curPos > len) throw 1; int rem = len - curPos; r.SystemUse.SetCapacity(rem); ReadBytes((Byte *)r.SystemUse, rem); }
const char* BsonDeserizer::ReadString() { #if USE_STRING_COUNT_HEAD uint16_t count = ReadUInt16(); const char* pStr = this->m_pPtr; this->m_pPtr += count; BEHAVIAC_ASSERT(*(this->m_pPtr - 1) == 0); return pStr; #else const char* pStr = this->m_pPtr; while (*this->m_pPtr) { this->m_pPtr++; } //skip the ending 0 this->m_pPtr++; return pStr; #endif }
bool AtomELST::ReadData() { uint32_t count = 0; if (!ReadUInt32(count)) { FATAL("Unable to read elst entries count"); return false; } //FINEST("-------"); ELSTEntry entry; for (uint32_t i = 0; i < count; i++) { if (_version == 1) { if (!ReadUInt64(entry.value._64.segmentDuration)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt64(entry.value._64.mediaTime)) { FATAL("Unable to read elst atom"); return false; } } else { if (!ReadUInt32(entry.value._32.segmentDuration)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt32(entry.value._32.mediaTime)) { FATAL("Unable to read elst atom"); return false; } } if (!ReadUInt16(entry.mediaRateInteger)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt16(entry.mediaRateFraction)) { FATAL("Unable to read elst atom"); return false; } // FINEST("version: %"PRIu8"; segmentDuration: %"PRIu32"; mediaTime: %"PRIu32"; mediaRateInteger: %"PRIu16"; mediaRateFraction: %"PRIu16, // _version, // entry.value._32.segmentDuration, // entry.value._32.mediaTime, // entry.mediaRateInteger, // entry.mediaRateFraction); _entries.push_back(entry); } return SkipRead(false); }
void CStChannelImpl::Invoke(LrpInvokeHandler handler) { bool status = Receive(); if (status) { status = m_buffer.GetSize() >= 12; } if (status) { m_buffer.SetPosition(12); size_t componentId = ReadUInt16(m_buffer); size_t methodId = ReadUInt16(m_buffer); handler(componentId, methodId, m_buffer, m_handle); status = Send(); } m_continue = status; }
///////////////////////////////////////////////////////// // Parse the entries in IFD0. (Section 4.6.2) ///////////////////////////////////////////////////////// bool EXIFParser::ParseIFD0(Orientation& aOrientationOut) { uint16_t entryCount; if (!ReadUInt16(entryCount)) { return false; } for (uint16_t entry = 0 ; entry < entryCount ; ++entry) { // Read the fields of the entry. uint16_t tag; if (!ReadUInt16(tag)) { return false; } // Right now, we only care about orientation, so we immediately skip to the // next entry if we find anything else. if (tag != OrientationTag) { Advance(10); continue; } uint16_t type; if (!ReadUInt16(type)) { return false; } uint32_t count; if (!ReadUInt32(count)) { return false; } // We should have an orientation value here; go ahead and parse it. if (!ParseOrientation(type, count, aOrientationOut)) { return false; } // Since the orientation is all we care about, we're done. return true; } // We didn't find an orientation field in the IFD. That's OK; we assume the // default orientation in that case. aOrientationOut = Orientation(); return true; }
bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) { if (!FindAndReadMarker(searchHeaderSizeLimit)) return false; Byte buf[NHeader::NArchive::kArchiveHeaderSize]; UInt32 processedSize; ReadBytes(buf, sizeof(buf), &processedSize); if (processedSize != sizeof(buf)) return false; m_CurData = buf; m_CurPos = 0; m_PosLimit = sizeof(buf); m_ArchiveHeader.CRC = ReadUInt16(); m_ArchiveHeader.Type = ReadByte(); m_ArchiveHeader.Flags = ReadUInt16(); m_ArchiveHeader.Size = ReadUInt16(); m_ArchiveHeader.Reserved1 = ReadUInt16(); m_ArchiveHeader.Reserved2 = ReadUInt32(); m_ArchiveHeader.EncryptVersion = 0; UInt32 crc = CRC_INIT_VAL; crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.Type); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Flags); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Size); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Reserved1); crc = CrcUpdateUInt32(crc, m_ArchiveHeader.Reserved2); if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) { ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); if (processedSize != 1) return false; crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); } if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) return false; m_ArchiveCommentPosition = m_Position; m_SeekOnArchiveComment = true; return true; }
String ^ByteArrayReader::ReadUTF() { UInt16 value = ReadUInt16(); if (value > 0) { array<Byte> ^result = ReadBytes(value); return Encoding::UTF8->GetString(result); } return nullptr; }
void CInArchive::ReadHeaderReal(CItemEx &item) { item.Flags = m_BlockHeader.Flags; item.PackSize = ReadUInt32(); item.Size = ReadUInt32(); item.HostOS = ReadByte(); item.FileCRC = ReadUInt32(); item.MTime.DosTime = ReadUInt32(); item.UnPackVersion = ReadByte(); item.Method = ReadByte(); int nameSize = ReadUInt16(); item.Attrib = ReadUInt32(); item.MTime.LowSecond = 0; item.MTime.SubTime[0] = item.MTime.SubTime[1] = item.MTime.SubTime[2] = 0; if((item.Flags & NHeader::NFile::kSize64Bits) != 0) { item.PackSize |= ((UInt64)ReadUInt32() << 32); item.Size |= ((UInt64)ReadUInt32() << 32); } ReadName(item, nameSize); if (item.HasSalt()) for (int i = 0; i < sizeof(item.Salt); i++) item.Salt[i] = ReadByte(); // some rar archives have HasExtTime flag without field. if (m_CurPos < m_PosLimit && item.HasExtTime()) { Byte accessMask = (Byte)(ReadByte() >> 4); Byte b = ReadByte(); Byte modifMask = (Byte)(b >> 4); Byte createMask = (Byte)(b & 0xF); if ((modifMask & 8) != 0) ReadTime(modifMask, item.MTime); item.CTimeDefined = ((createMask & 8) != 0); if (item.CTimeDefined) { item.CTime.DosTime = ReadUInt32(); ReadTime(createMask, item.CTime); } item.ATimeDefined = ((accessMask & 8) != 0); if (item.ATimeDefined) { item.ATime.DosTime = ReadUInt32(); ReadTime(accessMask, item.ATime); } }
xString xBinaryReader::ReadString() { xString result; xUInt16 len = ReadUInt16(); if (len > 0) { result.Reserve(len+1); xChar* buffer = (xChar*)result.c_str(); mStream->Read(buffer, len); buffer[len] = 0; } return result; }
HRESULT CLrpStClientImpl::Invoke(MemoryBuffer& buffer) { uint32 size = static_cast<uint32>(buffer.GetSize()); if (size < sizeof(uint32)) { throw runtime_error("Input buffer is too small"); } buffer.SetPosition(0); WriteInt32(size - 4, buffer); buffer.SetPosition(12); uint16 componentId = ReadUInt16(buffer); uint16 methodId = ReadUInt16(buffer); Translate(componentId, methodId); buffer.SetPosition(12); WriteUInt16(componentId, buffer); WriteUInt16(methodId, buffer); CTimeout timeout(m_operationTimeoutInMs); if (!SendEx(m_socket, timeout, buffer.GetData(), buffer.GetSize())) { closesocket(m_socket); m_socket = INVALID_SOCKET; throw runtime_error("Couldn't send data"); } if (!ReceiveEx(m_socket, timeout, buffer)) { closesocket(m_socket); m_socket = INVALID_SOCKET; throw runtime_error("Couldn't receive data"); } buffer.SetPosition(12); const HRESULT result = ReadInt32(buffer); return result; }
void CInArchive::ReadUString(unsigned size, UString &s) { s.Empty(); while (size-- != 0) { wchar_t c = ReadUInt16(); if (c == 0) { Skip(2 * size); return; } s += c; } }
bool AtomMDHD::ReadDataVersion0() { uint32_t temp = 0; if (!ReadUInt32(temp)) { FATAL("Unable to read creation time"); return false; } _creationTime = temp; if (!ReadUInt32(temp)) { FATAL("Unable to read modification time"); return false; } _modificationTime = temp; if (!ReadUInt32(_timeScale)) { FATAL("Unable to read time scale"); return false; } if (!ReadUInt32(temp)) { FATAL("Unable to read duration"); return false; } _duration = temp; if (!ReadUInt16(_language)) { FATAL("Unable to read language"); return false; } if (!ReadUInt16(_quality)) { FATAL("Unable to read quality"); return false; } return true; }
wxString CFileDataIO::ReadString(bool bOptUTF8, uint8 SizeLen, bool SafeRead) const { uint32 readLen; switch (SizeLen) { case sizeof(uint16): readLen = ReadUInt16(); break; case sizeof(uint32): readLen = ReadUInt32(); break; default: MULE_VALIDATE_PARAMS(false, wxT("Invalid SizeLen value in ReadString")); } if (SafeRead) { readLen = std::min<uint64>(readLen, GetLength() - GetPosition()); } return ReadOnlyString(bOptUTF8, readLen); }
MR_UInt32 ClassicObjStream::ReadStringLength() { MR_UInt8 b; ReadUInt8(b); if (b < 0xff) return b; MR_UInt16 w; ReadUInt16(w); if (w == 0xfffe) { // Unicode (length follows). ASSERT(FALSE); throw std::exception(); } else if (w == 0xffff) { MR_UInt32 dw; ReadUInt32(dw); return dw; } else { return w; } }
HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit, CDatabase &database) { database.Clear(); RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition)); RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize, searchHeaderSizeLimit, database.StartPosition)); RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL)); if (!inBuffer.Create(1 << 17)) return E_OUTOFMEMORY; inBuffer.SetStream(stream); inBuffer.Init(); CInArchiveInfo &archiveInfo = database.ArchiveInfo; archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes if (ReadUInt32() != 0) return S_FALSE; archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry if (ReadUInt32() != 0) return S_FALSE; archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet archiveInfo.Flags = ReadUInt16(); if (archiveInfo.Flags > 7) return S_FALSE; archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set if (archiveInfo.ReserveBlockPresent()) { archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area Skeep(archiveInfo.PerCabinetAreaSize); } { if (archiveInfo.IsTherePrev()) ReadOtherArchive(archiveInfo.PreviousArchive); if (archiveInfo.IsThereNext()) ReadOtherArchive(archiveInfo.NextArchive); } int i; for(i = 0; i < archiveInfo.NumFolders; i++) { CFolder folder; folder.DataStart = ReadUInt32(); folder.NumDataBlocks = ReadUInt16(); folder.CompressionTypeMajor = ReadByte(); folder.CompressionTypeMinor = ReadByte(); Skeep(archiveInfo.PerFolderAreaSize); database.Folders.Add(folder); } RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); inBuffer.SetStream(stream); inBuffer.Init(); for(i = 0; i < archiveInfo.NumFiles; i++) { CItem item; item.Size = ReadUInt32(); item.Offset = ReadUInt32(); item.FolderIndex = ReadUInt16(); UInt16 pureDate = ReadUInt16(); UInt16 pureTime = ReadUInt16(); item.Time = ((UInt32(pureDate) << 16)) | pureTime; item.Attributes = ReadUInt16(); item.Name = SafeReadName(); int folderIndex = item.GetFolderIndex(database.Folders.Size()); if (folderIndex >= database.Folders.Size()) return S_FALSE; database.Items.Add(item); } return S_OK; }
int16_t ReadInt16() { return (int16_t)ReadUInt16(); }
bool AtomMVHD::ReadData() { if (_version == 1) { if (!ReadUInt64(_creationTime)) { FATAL("Unable to read creation time"); return false; } if (!ReadUInt64(_modificationTime)) { FATAL("Unable to read modification time"); return false; } } else { uint32_t temp; if (!ReadUInt32(temp)) { FATAL("Unable to read creation time"); return false; } _creationTime = temp; if (!ReadUInt32(temp)) { FATAL("Unable to read modification time"); return false; } _modificationTime = temp; } if (!ReadUInt32(_timeScale)) { FATAL("Unable to read time scale"); return false; } if (_version == 1) { if (!ReadUInt64(_duration)) { FATAL("Unable to read duration"); return false; } } else { uint32_t temp; if (!ReadUInt32(temp)) { FATAL("Unable to read duration"); return false; } _duration = temp; } if (!ReadUInt32(_preferredRate)) { FATAL("Unable to read preferred rate"); return false; } if (!ReadUInt16(_preferredVolume)) { FATAL("Unable to read preferred volume"); return false; } if (!ReadArray(_reserved, 10)) { FATAL("Unable to read reserved"); return false; } if (!ReadArray((uint8_t *) _matrixStructure, 36)) { FATAL("Unable to read matrix structure"); return false; } if (!ReadUInt32(_previewTime)) { FATAL("Unable to read preview time"); return false; } if (!ReadUInt32(_previewDuration)) { FATAL("Unable to read preview duration"); return false; } if (!ReadUInt32(_posterTime)) { FATAL("Unable to read poster time"); return false; } if (!ReadUInt32(_selectionTime)) { FATAL("Unable to read selection time"); return false; } if (!ReadUInt32(_selectionDuration)) { FATAL("Unable to read selection duration"); return false; } if (!ReadUInt32(_currentTime)) { FATAL("Unable to read current time"); return false; } if (!ReadUInt32(_nextTrakId)) { FATAL("Unable to read next track ID"); return false; } return true; }
HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit, CDatabase &database) { database.Clear(); RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition)); RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize, searchHeaderSizeLimit, database.StartPosition)); RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL)); if (!inBuffer.Create(1 << 17)) return E_OUTOFMEMORY; inBuffer.SetStream(stream); inBuffer.Init(); CInArchiveInfo &ai = database.ArchiveInfo; ai.Size = ReadUInt32(); if (ReadUInt32() != 0) return S_FALSE; ai.FileHeadersOffset = ReadUInt32(); if (ReadUInt32() != 0) return S_FALSE; ai.VersionMinor = ReadByte(); ai.VersionMajor = ReadByte(); ai.NumFolders = ReadUInt16(); ai.NumFiles = ReadUInt16(); ai.Flags = ReadUInt16(); if (ai.Flags > 7) return S_FALSE; ai.SetID = ReadUInt16(); ai.CabinetNumber = ReadUInt16(); if (ai.ReserveBlockPresent()) { ai.PerCabinetAreaSize = ReadUInt16(); ai.PerFolderAreaSize = ReadByte(); ai.PerDataBlockAreaSize = ReadByte(); Skip(ai.PerCabinetAreaSize); } { if (ai.IsTherePrev()) ReadOtherArchive(ai.PreviousArchive); if (ai.IsThereNext()) ReadOtherArchive(ai.NextArchive); } int i; for (i = 0; i < ai.NumFolders; i++) { CFolder folder; folder.DataStart = ReadUInt32(); folder.NumDataBlocks = ReadUInt16(); folder.CompressionTypeMajor = ReadByte(); folder.CompressionTypeMinor = ReadByte(); Skip(ai.PerFolderAreaSize); database.Folders.Add(folder); } RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL)); inBuffer.SetStream(stream); inBuffer.Init(); for (i = 0; i < ai.NumFiles; i++) { CItem item; item.Size = ReadUInt32(); item.Offset = ReadUInt32(); item.FolderIndex = ReadUInt16(); UInt16 pureDate = ReadUInt16(); UInt16 pureTime = ReadUInt16(); item.Time = ((UInt32(pureDate) << 16)) | pureTime; item.Attributes = ReadUInt16(); item.Name = SafeReadName(); int folderIndex = item.GetFolderIndex(database.Folders.Size()); if (folderIndex >= database.Folders.Size()) return S_FALSE; database.Items.Add(item); } return S_OK; }
CTag *CFileDataIO::ReadTag(bool bOptACP) const { CTag *retVal = NULL; wxString name; byte type = 0; try { type = ReadUInt8(); name = ReadString(false); switch (type) { // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade // the net in some months. // // And still.. it doesnt't work this way without breaking backward compatibility. To properly // do this without messing up the network the following would have to be done: // - those tag types have to be ignored by any client, otherwise those tags would also be sent (and // that's really the problem) // // - ignoring means, each client has to read and right throw away those tags, so those tags get // get never stored in any tag list which might be sent by that client to some other client. // // - all calling functions have to be changed to deal with the 'nr. of tags' attribute (which was // already parsed) correctly.. just ignoring those tags here is not enough, any taglists have to // be built with the knowledge that the 'nr. of tags' attribute may get decreased during the tag // reading.. // // If those new tags would just be stored and sent to remote clients, any malicious or just bugged // client could let send a lot of nodes "corrupted" packets... // case TAGTYPE_HASH16: { retVal = new CTagHash(name, ReadHash()); break; } case TAGTYPE_STRING: retVal = new CTagString(name, ReadString(bOptACP)); break; case TAGTYPE_UINT64: retVal = new CTagInt64(name, ReadUInt64()); break; case TAGTYPE_UINT32: retVal = new CTagInt32(name, ReadUInt32()); break; case TAGTYPE_UINT16: retVal = new CTagInt16(name, ReadUInt16()); break; case TAGTYPE_UINT8: retVal = new CTagInt8(name, ReadUInt8()); break; case TAGTYPE_FLOAT32: retVal = new CTagFloat(name, ReadFloat()); break; // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade // the net in some months. // // And still.. it doesnt't work this way without breaking backward compatibility case TAGTYPE_BSOB: { uint8 size = 0; CScopedArray<unsigned char> value(ReadBsob(&size)); retVal = new CTagBsob(name, value.get(), size); break; } default: throw wxString(CFormat(wxT("Invalid Kad tag type; type=0x%02x name=%s\n")) % type % name); } } catch(const CMuleException& e) { AddLogLineN(e.what()); delete retVal; throw; } catch(const wxString& e) { AddLogLineN(e); throw; } return retVal; }
bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) { extraBlock.Clear(); UInt32 remain = extraSize; while (remain >= 4) { CExtraSubBlock subBlock; subBlock.ID = ReadUInt16(); unsigned dataSize = ReadUInt16(); remain -= 4; if (dataSize > remain) // it's bug { HeadersWarning = true; Skip(remain); return false; } if (subBlock.ID == NFileHeader::NExtraID::kZip64) { if (unpackSize == 0xFFFFFFFF) { if (dataSize < 8) { HeadersWarning = true; Skip(remain); return false; } unpackSize = ReadUInt64(); remain -= 8; dataSize -= 8; } if (packSize == 0xFFFFFFFF) { if (dataSize < 8) break; packSize = ReadUInt64(); remain -= 8; dataSize -= 8; } if (localHeaderOffset == 0xFFFFFFFF) { if (dataSize < 8) break; localHeaderOffset = ReadUInt64(); remain -= 8; dataSize -= 8; } if (diskStartNumber == 0xFFFF) { if (dataSize < 4) break; diskStartNumber = ReadUInt32(); remain -= 4; dataSize -= 4; } Skip(dataSize); } else { ReadBuffer(subBlock.Data, dataSize); extraBlock.SubBlocks.Add(subBlock); } remain -= dataSize; } if (remain != 0) { ExtraMinorError = true; // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. // so we don't return false, but just set warning flag // return false; } Skip(remain); return true; }
HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) { UInt32 headerSize = ReadUInt32(); if (headerSize != 0x60) return S_FALSE; database.PhySize = headerSize; UInt32 unknown1 = ReadUInt32(); if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file return S_FALSE; IsArc = true; /* UInt32 timeStamp = */ ReadUInt32(); // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and // fractional seconds (second byte). // The third and fourth bytes may contain even more fractional bits. // The 4 least significant bits in the last byte are constant. /* UInt32 lang = */ ReadUInt32(); Byte g[16]; ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} const unsigned kNumSections = 2; UInt64 sectionOffsets[kNumSections]; UInt64 sectionSizes[kNumSections]; unsigned i; for (i = 0; i < kNumSections; i++) { sectionOffsets[i] = ReadUInt64(); sectionSizes[i] = ReadUInt64(); UInt64 end = sectionOffsets[i] + sectionSizes[i]; database.UpdatePhySize(end); } // if (chmVersion == 3) database.ContentOffset = ReadUInt64(); /* else database.ContentOffset = database.StartPosition + 0x58 */ // Section 0 ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); if (sectionSizes[0] < 0x18) return S_FALSE; if (ReadUInt32() != 0x01FE) return S_FALSE; ReadUInt32(); // unknown: 0 UInt64 fileSize = ReadUInt64(); database.UpdatePhySize(fileSize); ReadUInt32(); // unknown: 0 ReadUInt32(); // unknown: 0 // Section 1: The Directory Listing ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); if (ReadUInt32() != kSignature_ITSP) return S_FALSE; if (ReadUInt32() != 1) // version return S_FALSE; /* UInt32 dirHeaderSize = */ ReadUInt32(); ReadUInt32(); // 0x0A (unknown) UInt32 dirChunkSize = ReadUInt32(); // $1000 if (dirChunkSize < 32) return S_FALSE; /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, // 2 if there is one level of PMGI chunks. /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none // (though at least one file has 0 despite there being no // index chunk, probably a bug.) /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk ReadUInt32(); // -1 (unknown) UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) /* UInt32 windowsLangId = */ ReadUInt32(); ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} ReadUInt32(); // 0x54 (This is the length again) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) for (UInt32 ci = 0; ci < numDirChunks; ci++) { UInt64 chunkPos = _inBuffer.GetProcessedSize(); if (ReadUInt32() == kSignature_PMGL) { // The quickref area is written backwards from the end of the chunk. // One quickref entry exists for every n entries in the file, where n // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt32(); // Always 0 ReadUInt32(); // Chunk number of previous listing chunk when reading // directory in sequence (-1 if this is the first listing chunk) ReadUInt32(); // Chunk number of next listing chunk when reading // directory in sequence (-1 if this is the last listing chunk) unsigned numItems = 0; for (;;) { UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; RINOK(ReadDirEntry(database)); numItems++; } Skip(quickrefLength - 2); unsigned rrr = ReadUInt16(); if (rrr != numItems) { // Lazarus 9-26-2 chm contains 0 here. if (rrr != 0) return S_FALSE; } } else Skip(dirChunkSize - 4); } return S_OK; }
int16_t BinaryReader::ReadInt16() { return (int16_t)ReadUInt16(); }
HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) { if (ReadUInt32() != 1) // version return S_FALSE; if (ReadUInt32() != 0x28) // Location of header section table return S_FALSE; UInt32 numHeaderSections = ReadUInt32(); const unsigned kNumHeaderSectionsMax = 5; if (numHeaderSections != kNumHeaderSectionsMax) return S_FALSE; IsArc = true; ReadUInt32(); // Len of post-header table Byte g[16]; ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} // header section table UInt64 sectionOffsets[kNumHeaderSectionsMax]; UInt64 sectionSizes[kNumHeaderSectionsMax]; UInt32 i; for (i = 0; i < numHeaderSections; i++) { sectionOffsets[i] = ReadUInt64(); sectionSizes[i] = ReadUInt64(); UInt64 end = sectionOffsets[i] + sectionSizes[i]; database.UpdatePhySize(end); } // Post-Header ReadUInt32(); // 2 ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) // ----- Directory information ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 ReadUInt64(); // Chunk number of first AOLL chunk in directory ReadUInt64(); // Chunk number of last AOLL chunk in directory ReadUInt64(); // 0 (unknown) ReadUInt32(); // $2000 (Directory chunk size of directory) ReadUInt32(); // Quickref density for main directory, usually 2 ReadUInt32(); // 0 (unknown) ReadUInt32(); // Depth of main directory index tree // 1 there is no index, 2 if there is one level of AOLI chunks. ReadUInt64(); // 0 (unknown) UInt64 numDirEntries = ReadUInt64(); // Number of directory entries // ----- Directory Index Information ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) ReadUInt64(); // Chunk number of first AOLL chunk in directory index ReadUInt64(); // Chunk number of last AOLL chunk in directory index ReadUInt64(); // 0 (unknown) ReadUInt32(); // $200 (Directory chunk size of directory index) ReadUInt32(); // Quickref density for directory index, usually 2 ReadUInt32(); // 0 (unknown) ReadUInt32(); // Depth of directory index index tree. ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. ReadUInt64(); // Number of directory index entries (same as number of AOLL // chunks in main directory) // (The obvious guess for the following two fields, which recur in a number // of places, is they are maximum sizes for the directory and directory index. // However, I have seen no direct evidence that this is the case.) ReadUInt32(); // $100000 (Same as field following chunk size in directory) ReadUInt32(); // $20000 (Same as field following chunk size in directory index) ReadUInt64(); // 0 (unknown) if (ReadUInt32() != kSignature_CAOL) return S_FALSE; if (ReadUInt32() != 2) // (Most likely a version number) return S_FALSE; UInt32 caolLength = ReadUInt32(); // $50 (Len of the CAOL section, which includes the ITSF section) if (caolLength >= 0x2C) { /* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built. // Does not appear to be a checksum. Many files have // 'HH' (HTML Help?) here, indicating this may be a compiler ID // field. But at least one ITOL/ITLS compiler does not set this // field to a constant value. ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. ReadUInt32(); // $2000 (Directory chunk size of directory) ReadUInt32(); // $200 (Directory chunk size of directory index) ReadUInt32(); // $100000 (Same as field following chunk size in directory) ReadUInt32(); // $20000 (Same as field following chunk size in directory index) ReadUInt32(); // 0 (unknown) ReadUInt32(); // 0 (Unknown) if (caolLength == 0x2C) { // fprintf(stdout, "\n !!!NewFormat\n"); // fflush(stdout); database.ContentOffset = 0; // maybe we must add database.StartPosition here? database.NewFormat = true; } else if (caolLength == 0x50) { ReadUInt32(); // 0 (Unknown) if (ReadUInt32() != kSignature_ITSF) return S_FALSE; if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) return S_FALSE; if (ReadUInt32() != 0x20) // $20 (length of ITSF) return S_FALSE; UInt32 unknown = ReadUInt32(); if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; return S_FALSE; database.ContentOffset = database.StartPosition + ReadUInt64(); /* UInt32 timeStamp = */ ReadUInt32(); // A timestamp of some sort. // Considered as a big-endian DWORD, it appears to contain // seconds (MSB) and fractional seconds (second byte). // The third and fourth bytes may contain even more fractional // bits. The 4 least significant bits in the last byte are constant. /* UInt32 lang = */ ReadUInt32(); // BE? } else return S_FALSE; } // Section 0 ReadChunk(inStream, database.StartPosition + sectionOffsets[0], sectionSizes[0]); if (sectionSizes[0] < 0x18) return S_FALSE; if (ReadUInt32() != 0x01FE) return S_FALSE; ReadUInt32(); // unknown: 0 UInt64 fileSize = ReadUInt64(); database.UpdatePhySize(fileSize); ReadUInt32(); // unknown: 0 ReadUInt32(); // unknown: 0 // Section 1: The Directory Listing ReadChunk(inStream, database.StartPosition + sectionOffsets[1], sectionSizes[1]); if (ReadUInt32() != kSignature_IFCM) return S_FALSE; if (ReadUInt32() != 1) // (probably a version number) return S_FALSE; UInt32 dirChunkSize = ReadUInt32(); // $2000 if (dirChunkSize < 64) return S_FALSE; ReadUInt32(); // $100000 (unknown) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) UInt32 numDirChunks = ReadUInt32(); ReadUInt32(); // 0 (unknown, probably high word of above) for (UInt32 ci = 0; ci < numDirChunks; ci++) { UInt64 chunkPos = _inBuffer.GetProcessedSize(); if (ReadUInt32() == kSignature_AOLL) { UInt32 quickrefLength = ReadUInt32(); // Len of quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt64(); // Directory chunk number // This must match physical position in file, that is // the chunk size times the chunk number must be the // offset from the end of the directory header. ReadUInt64(); // Chunk number of previous listing chunk when reading // directory in sequence (-1 if first listing chunk) ReadUInt64(); // Chunk number of next listing chunk when reading // directory in sequence (-1 if last listing chunk) ReadUInt64(); // Number of first listing entry in this chunk ReadUInt32(); // 1 (unknown -- other values have also been seen here) ReadUInt32(); // 0 (unknown) unsigned numItems = 0; for (;;) { UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; if (database.NewFormat) { UInt16 nameLen = ReadUInt16(); if (nameLen == 0) return S_FALSE; UString name; ReadUString((unsigned)nameLen, name); AString s; ConvertUnicodeToUTF8(name, s); Byte b = ReadByte(); s.Add_Space(); PrintByte(b, s); s.Add_Space(); UInt64 len = ReadEncInt(); // then number of items ? // then length ? // then some data (binary encoding?) while (len-- != 0) { b = ReadByte(); PrintByte(b, s); } database.NewFormatString += s; database.NewFormatString += "\r\n"; } else { RINOK(ReadDirEntry(database)); } numItems++; } Skip(quickrefLength - 2); if (ReadUInt16() != numItems) return S_FALSE; if (numItems > numDirEntries) return S_FALSE; numDirEntries -= numItems; } else Skip(dirChunkSize - 4); } return numDirEntries == 0 ? S_OK : S_FALSE; }