static void ReadSecBuf(SecBuf *s, const PRUint8 *&buf) { s->length = ReadUint16(buf); s->capacity = ReadUint16(buf); s->offset = ReadUint32(buf); }
static void ReadType2MsgBody(const PRUint8 *inBuf, PRUint32 start) { PRUint16 targetLen, offset; PRUint32 flags; const PRUint8 *target; const PRUint8 *cursor = inBuf + start; // read target name security buffer targetLen = ReadUint16(cursor); ReadUint16(cursor); // discard next 16-bit value offset = ReadUint32(cursor); // get offset from inBuf target = inBuf + offset; PrintBuf("target", target, targetLen); PrintBuf("flags", cursor, 4); // read flags flags = ReadUint32(cursor); PrintFlags(flags); // read challenge PrintBuf("challenge", cursor, 8); cursor += 8; PrintBuf("context", cursor, 8); cursor += 8; SecBuf secbuf; ReadSecBuf(&secbuf, cursor); PrintBuf("target information", inBuf + secbuf.offset, secbuf.length); }
/// parses event data void Parse(unsigned int uiNumParam) { // note that buffer pointer is at pos 4 already prUInt16 uiContainerType = ReadUint16(); m_uiEventCode = ReadUint16(); prUInt32 uiTransactionId = ReadUint32(); UNUSED(uiContainerType); UNUSED(uiTransactionId); // read all parameters for (unsigned int ui = 0; ui < uiNumParam; ui++) m_vecParams.push_back(ReadUint32()); }
int32 UnpackSavedataAck(EdpPacket* pkg, char** json_ack) { uint32 remainlen; uint8 flag; uint16 json_len; if (ReadRemainlen(pkg, &remainlen)) { return ERR_UNPACK_SAVEDATA_ACK; } if (ReadByte(pkg, &flag)) { return ERR_UNPACK_SAVEDATA_ACK; } if (ReadUint16(pkg, &json_len)) { return ERR_UNPACK_SAVEDATA_ACK; } if (ReadBytes(pkg, (uint8**)(json_ack), json_len)) { return ERR_UNPACK_SAVEDATA_ACK; } return 0; }
int32 UnpackEncryptResp(EdpPacket* pkg){ uint32 remainlen = 0; uint16 key_len = 0; unsigned rsa_size = 0; unsigned slice_size = 0; unsigned char key[BUFFER_SIZE] = {0}; unsigned decrypt_len = 0; int len = 0; unsigned char* from = 0; unsigned char* to = 0; uint32 i = 0; if (ReadRemainlen(pkg, &remainlen)) return ERR_UNPACK_ENCRYPT_RESP; if (ReadUint16(pkg, &key_len)) return ERR_UNPACK_ENCRYPT_RESP; if (remainlen != key_len + 2) return ERR_UNPACK_ENCRYPT_RESP; rsa_size = RSA_size(g_rsa); slice_size = rsa_size - RSA_PADDING_LEN; from = pkg->_data + pkg->_read_pos; to = key; for (i=0; i<key_len; i+=rsa_size){ len = RSA_private_decrypt(rsa_size, from+i, to, g_rsa, RSA_PKCS1_PADDING); decrypt_len += len; if (decrypt_len > BUFFER_SIZE){ return ERR_UNPACK_ENCRYPT_RESP; } to += len; } switch (g_encrypt_alg_type){ case kTypeAes: if(AES_set_encrypt_key(key, AES_KEY_LEN, &g_aes_encrypt_key) < 0) { return ERR_UNPACK_ENCRYPT_RESP; } if(AES_set_decrypt_key(key, AES_KEY_LEN, &g_aes_decrypt_key) < 0) { return ERR_UNPACK_ENCRYPT_RESP; } break; default: return ERR_UNPACK_ENCRYPT_RESP; break; } return 0; }
otError SpinelDecoder::ReadInt16(int16_t &aInt16) { otError error = OT_ERROR_NONE; uint16_t u16; SuccessOrExit(error = ReadUint16(u16)); aInt16 = static_cast<int16_t>(u16); exit: return error; }
otError SpinelDecoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen) { otError error = OT_ERROR_NONE; uint16_t len; SuccessOrExit(error = ReadUint16(len)); SuccessOrExit(error = ReadItem(&aData, len)); aDataLen = len; exit: return error; }
int32 ReadStr(EdpPacket* pkg, char** val) { uint16 len; /* read str len */ int rc = ReadUint16(pkg, &len); if (rc) return rc; if (pkg->_read_pos+len > pkg->_write_pos) return -1; /* copy str val */ *val = (char*)hx_malloc(sizeof(char) * (len + 1)); mymemset(*val, 0, len+1); strncpy(*val, (const char *)(pkg->_data + pkg->_read_pos), len); pkg->_read_pos += len; return 0; }
int32_t ReadStr(EdpPacket* pkg, int8_t** val) { uint16_t len = 0; int32_t rc = 0; /* read str len */ rc = ReadUint16(pkg, &len); if (rc) return rc; if (pkg->_read_pos + len > pkg->_write_pos) return -1; /* copy str val */ *val = malloc(sizeof(char) * (len + 1)); memset(*val, 0, len + 1); strncpy((char *)*val, (const char *)(pkg->_data + pkg->_read_pos), len); pkg->_read_pos += len; return 0; }
otError SpinelDecoder::OpenStruct(void) { otError error = OT_ERROR_NONE; uint16_t structLen; VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE); SuccessOrExit(error = ReadUint16(structLen)); VerifyOrExit(structLen <= mEnd - mIndex, error = OT_ERROR_PARSE); mPrevEnd[mNumOpenStructs] = mEnd; mEnd = (mIndex + structLen); mNumOpenStructs++; exit: return error; }
int32_t UnpackSavedataAck(EdpPacket* pkg, int8_t** json_ack) { uint32_t remainlen = 0; uint8_t flag = 0; uint16_t json_len = 0; if (ReadRemainlen(pkg, &remainlen)) return ERR_UNPACK_SAVEDATA_ACK; if (ReadByte(pkg, &flag)) return ERR_UNPACK_SAVEDATA_ACK; if (ReadUint16(pkg, &json_len)) return ERR_UNPACK_SAVEDATA_ACK; if (ReadBytes(pkg, (uint8_t**)(json_ack), json_len)) return ERR_UNPACK_SAVEDATA_ACK; return 0; }
int32_t UnpackCmdReq(EdpPacket* pkg, int8_t** cmdid, uint16_t* cmdid_len, int8_t** req, uint32_t* req_len) { uint32 remainlen; int32_t rc; if (ReadRemainlen(pkg, &remainlen)) return ERR_UNPACK_CMDREQ; rc = ReadUint16(pkg, cmdid_len); if (rc) return rc; if (ReadBytes(pkg, (uint8_t**)cmdid, *cmdid_len)) return ERR_UNPACK_CMDREQ; rc = ReadUint32(pkg, req_len); if (rc) return rc; if (ReadBytes(pkg, (uint8_t**)req, *req_len)) return ERR_UNPACK_CMDREQ; my_assert(pkg->_read_pos == pkg->_write_pos); return 0; }
bool HTTPTracker::updateData(const QByteArray & data) { //#define DEBUG_PRINT_RESPONSE #ifdef DEBUG_PRINT_RESPONSE Out(SYS_TRK | LOG_DEBUG) << "Data : " << endl; Out(SYS_TRK | LOG_DEBUG) << QString(data) << endl; #endif // search for dictionary, there might be random garbage infront of the data int i = 0; while (i < data.size()) { if (data[i] == 'd') break; i++; } if (i == data.size()) { failures++; failed(i18n("Invalid response from tracker")); return false; } BDecoder dec(data, false, i); BNode* n = 0; try { n = dec.decode(); } catch (...) { failures++; failed(i18n("Invalid data from tracker")); return false; } if (!n || n->getType() != BNode::DICT) { failures++; failed(i18n("Invalid response from tracker")); return false; } BDictNode* dict = (BDictNode*)n; if (dict->getData("failure reason")) { BValueNode* vn = dict->getValue("failure reason"); error = vn->data().toString(); delete n; failures++; failed(error); return false; } if (dict->getData("warning message")) { BValueNode* vn = dict->getValue("warning message"); warning = vn->data().toString(); } else warning.clear(); BValueNode* vn = dict->getValue("interval"); // if no interval is specified, use 5 minutes if (vn) interval = vn->data().toInt(); else interval = 5 * 60; vn = dict->getValue("incomplete"); if (vn) leechers = vn->data().toInt(); vn = dict->getValue("complete"); if (vn) seeders = vn->data().toInt(); BListNode* ln = dict->getList("peers"); if (!ln) { // no list, it might however be a compact response vn = dict->getValue("peers"); if (vn && vn->data().getType() == Value::STRING) { QByteArray arr = vn->data().toByteArray(); for (int i = 0;i < arr.size();i += 6) { Uint8 buf[6]; for (int j = 0;j < 6;j++) buf[j] = arr[i + j]; Uint32 ip = ReadUint32(buf, 0); addPeer(net::Address(ip, ReadUint16(buf, 4)), false); } } } else { for (Uint32 i = 0;i < ln->getNumChildren();i++) { BDictNode* dict = dynamic_cast<BDictNode*>(ln->getChild(i)); if (!dict) continue; BValueNode* ip_node = dict->getValue("ip"); BValueNode* port_node = dict->getValue("port"); if (!ip_node || !port_node) continue; net::Address addr(ip_node->data().toString(), port_node->data().toInt()); addPeer(addr, false); } } // Check for IPv6 compact peers vn = dict->getValue("peers6"); if (vn && vn->data().getType() == Value::STRING) { QByteArray arr = vn->data().toByteArray(); for (int i = 0;i < arr.size();i += 18) { Q_IPV6ADDR ip; memcpy(ip.c, arr.data() + i, 16); quint16 port = ReadUint16((const Uint8*)arr.data() + i, 16); addPeer(net::Address(ip, port), false); } } delete n; return true; }
static nsresult ParseType2Msg(const void *inBuf, uint32_t inLen, Type2Msg *msg) { // make sure inBuf is long enough to contain a meaningful type2 msg. // // 0 NTLMSSP Signature // 8 NTLM Message Type // 12 Target Name // 20 Flags // 24 Challenge // 32 targetInfo // 48 start of optional data blocks // if (inLen < NTLM_TYPE2_HEADER_LEN) return NS_ERROR_UNEXPECTED; const uint8_t *cursor = reinterpret_cast<const uint8_t*>(inBuf); // verify NTLMSSP signature if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0) return NS_ERROR_UNEXPECTED; cursor += sizeof(NTLM_SIGNATURE); // verify Type-2 marker if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_TYPE2_MARKER)) != 0) return NS_ERROR_UNEXPECTED; cursor += sizeof(NTLM_TYPE2_MARKER); // Read target name security buffer: ... // ... read target length. uint32_t targetLen = ReadUint16(cursor); // ... skip next 16-bit "allocated space" value. ReadUint16(cursor); // ... read offset from inBuf. uint32_t offset = ReadUint32(cursor); mozilla::CheckedInt<uint32_t> targetEnd = offset; targetEnd += targetLen; // Check the offset / length combo is in range of the input buffer, including // integer overflow checking. if (MOZ_LIKELY(targetEnd.isValid() && targetEnd.value() <= inLen)) { msg->targetLen = targetLen; msg->target = reinterpret_cast<const uint8_t*>(inBuf) + offset; } else { // Do not error out, for (conservative) backward compatibility. msg->targetLen = 0; msg->target = nullptr; } // read flags msg->flags = ReadUint32(cursor); // read challenge memcpy(msg->challenge, cursor, sizeof(msg->challenge)); cursor += sizeof(msg->challenge); LOG(("NTLM type 2 message:\n")); LogBuf("target", reinterpret_cast<const uint8_t*> (msg->target), msg->targetLen); LogBuf("flags", reinterpret_cast<const uint8_t*> (&msg->flags), 4); LogFlags(msg->flags); LogBuf("challenge", msg->challenge, sizeof(msg->challenge)); // Read (and skip) the reserved field ReadUint32(cursor); ReadUint32(cursor); // Read target name security buffer: ... // ... read target length. uint32_t targetInfoLen = ReadUint16(cursor); // ... skip next 16-bit "allocated space" value. ReadUint16(cursor); // ... read offset from inBuf. offset = ReadUint32(cursor); mozilla::CheckedInt<uint32_t> targetInfoEnd = offset; targetInfoEnd += targetInfoLen; // Check the offset / length combo is in range of the input buffer, including // integer overflow checking. if (MOZ_LIKELY(targetInfoEnd.isValid() && targetInfoEnd.value() <= inLen)) { msg->targetInfoLen = targetInfoLen; msg->targetInfo = reinterpret_cast<const uint8_t*>(inBuf) + offset; } else { NS_ERROR("failed to get NTLMv2 target info"); return NS_ERROR_UNEXPECTED; } return NS_OK; }
/** * * Loads a chunk from the old savegame * */ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) { byte *base_ptr = (byte*)base; for (const OldChunks *chunk = chunks; chunk->type != OC_END; chunk++) { if (((chunk->type & OC_TTD) && _savegame_type == SGT_TTO) || ((chunk->type & OC_TTO) && _savegame_type != SGT_TTO)) { /* TTD(P)-only chunk, but TTO savegame || TTO-only chunk, but TTD/TTDP savegame */ continue; } byte *ptr = (byte*)chunk->ptr; if (chunk->type & OC_DEREFERENCE_POINTER) ptr = *(byte**)ptr; for (uint i = 0; i < chunk->amount; i++) { /* Handle simple types */ if (GetOldChunkType(chunk->type) != 0) { switch (GetOldChunkType(chunk->type)) { /* Just read the byte and forget about it */ case OC_NULL: ReadByte(ls); break; case OC_CHUNK: /* Call function, with 'i' as parameter to tell which item we * are going to read */ if (!chunk->proc(ls, i)) return false; break; case OC_ASSERT: DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value); if (ls->total_read != chunk->offset + _bump_assert_value) throw std::exception(); default: break; } } else { uint64 res = 0; /* Reading from the file: bits 16 to 23 have the FILE type */ switch (GetOldChunkFileType(chunk->type)) { case OC_FILE_I8: res = (int8)ReadByte(ls); break; case OC_FILE_U8: res = ReadByte(ls); break; case OC_FILE_I16: res = (int16)ReadUint16(ls); break; case OC_FILE_U16: res = ReadUint16(ls); break; case OC_FILE_I32: res = (int32)ReadUint32(ls); break; case OC_FILE_U32: res = ReadUint32(ls); break; default: NOT_REACHED(); } /* When both pointers are NULL, we are just skipping data */ if (base_ptr == NULL && chunk->ptr == NULL) continue; /* Writing to the var: bits 8 to 15 have the VAR type */ if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset; /* Write the data */ switch (GetOldChunkVarType(chunk->type)) { case OC_VAR_I8: *(int8 *)ptr = GB(res, 0, 8); break; case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break; case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break; case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break; case OC_VAR_I32:*(int32 *)ptr = res; break; case OC_VAR_U32:*(uint32*)ptr = res; break; case OC_VAR_I64:*(int64 *)ptr = res; break; case OC_VAR_U64:*(uint64*)ptr = res; break; default: NOT_REACHED(); } /* Increase pointer base for arrays when looping */ if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type); } } } return true; }
/** Process Exif directory @param dib Input FIBITMAP @param tiffp Pointer to the TIFF header @param offset 0th IFD offset @param length Length of the datafile @param msb_order Endianess order of the datafile @return */ static BOOL jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) { WORD de, nde; std::stack<WORD> destack; // directory entries stack std::stack<BYTE*> ifdstack; // IFD stack std::stack<TagLib::MDMODEL> modelstack; // metadata model stack // Keep a list of already visited IFD to avoid stack overflows // when recursive/cyclic directory structures exist. // This kind of recursive Exif file was encountered with Kodak images coming from // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W std::map<DWORD, int> visitedIFD; #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry)) // set the metadata model to Exif TagLib::MDMODEL md_model = TagLib::EXIF_MAIN; // set the pointer to the first IFD and follow it were it leads. BYTE *ifdp = (BYTE*)tiffp + offset; de = 0; do { // if there is anything on the stack then pop it off if(!destack.empty()) { ifdp = ifdstack.top(); ifdstack.pop(); de = destack.top(); destack.pop(); md_model = modelstack.top(); modelstack.pop(); } // remember that we've visited this directory so that we don't visit it again later DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de ); if(visitedIFD.find(visited) != visitedIFD.end()) { continue; } else { visitedIFD[visited] = 1; // processed } // determine how many entries there are in the current IFD nde = ReadUint16(msb_order, ifdp); for(; de < nde; de++) { char *pde = NULL; // pointer to the directory entry char *pval = NULL; // pointer to the tag value // create a tag FITAG *tag = FreeImage_CreateTag(); if(!tag) return FALSE; // point to the directory entry pde = (char*) DIR_ENTRY_ADDR(ifdp, de); // get the tag ID FreeImage_SetTagID(tag, ReadUint16(msb_order, pde)); // get the tag format WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2); if((tag_type - 1) >= EXIF_NUM_FORMATS) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // break out of the for loop break; } FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type); // get number of components FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4)); // get the size of the tag value in bytes FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * FreeImage_TagDataWidth((WORD)FreeImage_GetTagType(tag))); if(FreeImage_GetTagLength(tag) <= 4) { // 4 bytes or less and value is in the dir entry itself pval = pde + 8; } else { // if its bigger than 4 bytes, the directory entry contains an offset // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data DWORD offset_value = ReadUint32(msb_order, pde + 8); if(offset_value > length) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // jump to next entry continue; } // now check if offset + tag length exceeds buffer if(offset_value > length - FreeImage_GetTagLength(tag)) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // jump to next entry continue; } pval = (char*)(tiffp + offset_value); } // check for a IFD offset BOOL isIFDOffset = FALSE; switch(FreeImage_GetTagID(tag)) { case TAG_EXIF_OFFSET: case TAG_GPS_OFFSET: case TAG_INTEROP_OFFSET: case TAG_MAKER_NOTE: isIFDOffset = TRUE; break; } if(isIFDOffset) { DWORD sub_offset = 0; TagLib::MDMODEL next_mdmodel = md_model; BYTE *next_ifd = ifdp; // get offset and metadata model if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) { processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel); next_ifd = (BYTE*)pval + sub_offset; } else { processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel); next_ifd = (BYTE*)tiffp + sub_offset; } if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) { // push our current directory state onto the stack ifdstack.push(ifdp); // bump to the next entry de++; destack.push(de); // push our current metadata model modelstack.push(md_model); // push new state onto of stack to cause a jump ifdstack.push(next_ifd); destack.push(0); // select a new metadata model modelstack.push(next_mdmodel); // delete the tag as it won't be stored nor deleted in the for() loop FreeImage_DeleteTag(tag); break; // break out of the for loop } else { // unsupported camera model, canon maker tag or or something unknown // process as a standard tag processExifTag(dib, tag, pval, msb_order, md_model); } } else { // process as a standard tag processExifTag(dib, tag, pval, msb_order, md_model); } // delete the tag FreeImage_DeleteTag(tag); } // for(nde) // additional thumbnail data is skipped } while (!destack.empty()); return TRUE; }
/** Process a standard Exif tag */ static void processExifTag(FIBITMAP *dib, FITAG *tag, char *pval, BOOL msb_order, TagLib::MDMODEL md_model) { char defaultKey[16]; int n; DWORD i; // allocate a buffer to store the tag value BYTE *exif_value = (BYTE*)malloc(FreeImage_GetTagLength(tag) * sizeof(BYTE)); memset(exif_value, 0, FreeImage_GetTagLength(tag) * sizeof(BYTE)); // get the tag value switch(FreeImage_GetTagType(tag)) { case FIDT_SHORT: { WORD *value = (WORD*)&exif_value[0]; for(i = 0; i < FreeImage_GetTagCount(tag); i++) { value[i] = ReadUint16(msb_order, pval + i * sizeof(WORD)); } FreeImage_SetTagValue(tag, value); break; } case FIDT_SSHORT: { short *value = (short*)&exif_value[0]; for(i = 0; i < FreeImage_GetTagCount(tag); i++) { value[i] = ReadInt16(msb_order, pval + i * sizeof(short)); } FreeImage_SetTagValue(tag, value); break; } case FIDT_LONG: { DWORD *value = (DWORD*)&exif_value[0]; for(i = 0; i < FreeImage_GetTagCount(tag); i++) { value[i] = ReadUint32(msb_order, pval + i * sizeof(DWORD)); } FreeImage_SetTagValue(tag, value); break; } case FIDT_SLONG: { LONG *value = (LONG*)&exif_value[0]; for(i = 0; i < FreeImage_GetTagCount(tag); i++) { value[i] = ReadInt32(msb_order, pval + i * sizeof(LONG)); } FreeImage_SetTagValue(tag, value); break; } case FIDT_RATIONAL: { n = sizeof(DWORD); DWORD *value = (DWORD*)&exif_value[0]; for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { // read a sequence of (numerator, denominator) value[i] = ReadUint32(msb_order, n*i + (char*)pval); } FreeImage_SetTagValue(tag, value); break; } case FIDT_SRATIONAL: { n = sizeof(LONG); LONG *value = (LONG*)&exif_value[0]; for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { // read a sequence of (numerator, denominator) value[i] = ReadInt32(msb_order, n*i + (char*)pval); } FreeImage_SetTagValue(tag, value); break; } case FIDT_BYTE: case FIDT_ASCII: case FIDT_SBYTE: case FIDT_UNDEFINED: case FIDT_FLOAT: case FIDT_DOUBLE: default: FreeImage_SetTagValue(tag, pval); break; } if(md_model == TagLib::EXIF_MAKERNOTE_CANON) { // A single Canon tag can have multiple values within processCanonMakerNoteTag(dib, tag); } else { TagLib& s = TagLib::instance(); WORD tag_id = FreeImage_GetTagID(tag); // get the tag key and description const char *key = s.getTagFieldName(md_model, tag_id, defaultKey); FreeImage_SetTagKey(tag, key); const char *description = s.getTagDescription(md_model, tag_id); FreeImage_SetTagDescription(tag, description); // store the tag if(key) { FreeImage_SetMetadata(s.getFreeImageModel(md_model), dib, key, tag); } } // free the temporary buffer free(exif_value); }
// // @param pInput 输入流 //============================================================ TResult FUiControl::OnUnserialize(IDataInput* pInput){ MO_CHECK(pInput, return ENull); // 读取属性 _flags = pInput->ReadInt32(); _name.Unserialize(pInput); _label.UnserializeAutomatic(pInput); // 读取位置 _optionEnable = TestFlag(EControlFlag_Enable); _optionVisible = TestFlag(EControlFlag_Visible); _dockCd = (EControlDock)pInput->ReadUint8(); _location.x = pInput->ReadInt16(); _location.y = pInput->ReadInt16(); _size.width = pInput->ReadUint16(); _size.height = pInput->ReadUint16(); // 读取边距 if(TestFlag(EControlFlag_Margin)){ _margin.Unserialize8(pInput); } if(TestFlag(EControlFlag_Padding)){ _padding.Unserialize8(pInput); } // 读取边框 if(TestFlag(EControlFlag_BorderOuter)){ _borderOuter.Unserialize(pInput); } if(TestFlag(EControlFlag_BorderInner)){ _borderInner.Unserialize(pInput); }
void nsSOCKSSocketInfo::ReadNetPort(PRNetAddr *addr) { addr->inet.port = ReadUint16(); }
/** Process Exif directory @param dib Input FIBITMAP @param tiffp Pointer to the TIFF header @param offset 0th IFD offset @param length Length of the datafile @param msb_order Endianess order of the datafile @return */ static BOOL jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, unsigned long offset, unsigned int length, BOOL msb_order) { WORD de, nde; std::stack<WORD> destack; // directory entries stack std::stack<const BYTE*> ifdstack; // IFD stack std::stack<TagLib::MDMODEL> modelstack; // metadata model stack // Keep a list of already visited IFD to avoid stack overflows // when recursive/cyclic directory structures exist. // This kind of recursive Exif file was encountered with Kodak images coming from // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W std::map<DWORD, int> visitedIFD; /* "An Image File Directory (IFD) consists of a 2-byte count of the number of directory entries (i.e. the number of fields), followed by a sequence of 12-byte field entries, followed by a 4-byte offset of the next IFD (or 0 if none)." The "next IFD" (1st IFD) is the thumbnail. */ #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry)) // set the metadata model to Exif TagLib::MDMODEL md_model = TagLib::EXIF_MAIN; // set the pointer to the first IFD (0th IFD) and follow it were it leads. const BYTE *ifd0th = (BYTE*)tiffp + offset; const BYTE *ifdp = ifd0th; de = 0; do { // if there is anything on the stack then pop it off if(!destack.empty()) { ifdp = ifdstack.top(); ifdstack.pop(); de = destack.top(); destack.pop(); md_model = modelstack.top(); modelstack.pop(); } // remember that we've visited this directory and entry so that we don't visit it again later DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de ); if(visitedIFD.find(visited) != visitedIFD.end()) { continue; } else { visitedIFD[visited] = 1; // processed } // determine how many entries there are in the current IFD nde = ReadUint16(msb_order, ifdp); for(; de < nde; de++) { char *pde = NULL; // pointer to the directory entry char *pval = NULL; // pointer to the tag value // create a tag FITAG *tag = FreeImage_CreateTag(); if(!tag) return FALSE; // point to the directory entry pde = (char*) DIR_ENTRY_ADDR(ifdp, de); // get the tag ID FreeImage_SetTagID(tag, ReadUint16(msb_order, pde)); // get the tag type WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2); if((tag_type - 1) >= EXIF_NUM_FORMATS) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // break out of the for loop break; } FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type); // get number of components FreeImage_SetTagCount(tag, ReadUint32(msb_order, pde + 4)); // check that tag length (size of the tag value in bytes) will fit in a DWORD unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag)); if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) { FreeImage_DeleteTag(tag); // jump to next entry continue; } FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * tag_data_width); if(FreeImage_GetTagLength(tag) <= 4) { // 4 bytes or less and value is in the dir entry itself pval = pde + 8; } else { // if its bigger than 4 bytes, the directory entry contains an offset // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data DWORD offset_value = ReadUint32(msb_order, pde + 8); if(offset_value > length) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // jump to next entry continue; } // now check that length does not exceed the buffer size if(FreeImage_GetTagLength(tag) > length - offset_value) { // a problem occured : delete the tag (not free'd after) FreeImage_DeleteTag(tag); // jump to next entry continue; } pval = (char*)(tiffp + offset_value); } // check for a IFD offset BOOL isIFDOffset = FALSE; switch(FreeImage_GetTagID(tag)) { case TAG_EXIF_OFFSET: case TAG_GPS_OFFSET: case TAG_INTEROP_OFFSET: case TAG_MAKER_NOTE: isIFDOffset = TRUE; break; } if(isIFDOffset) { DWORD sub_offset = 0; TagLib::MDMODEL next_mdmodel = md_model; const BYTE *next_ifd = ifdp; // get offset and metadata model if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) { processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel); next_ifd = (BYTE*)pval + sub_offset; } else { processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel); next_ifd = (BYTE*)tiffp + sub_offset; } if((sub_offset < (DWORD) length) && (next_mdmodel != TagLib::UNKNOWN)) { // push our current directory state onto the stack ifdstack.push(ifdp); // bump to the next entry de++; destack.push(de); // push our current metadata model modelstack.push(md_model); // push new state onto of stack to cause a jump ifdstack.push(next_ifd); destack.push(0); // select a new metadata model modelstack.push(next_mdmodel); // delete the tag as it won't be stored nor deleted in the for() loop FreeImage_DeleteTag(tag); break; // break out of the for loop } else { // unsupported camera model, canon maker tag or something unknown // process as a standard tag processExifTag(dib, tag, pval, msb_order, md_model); } } else { // process as a standard tag processExifTag(dib, tag, pval, msb_order, md_model); } // delete the tag FreeImage_DeleteTag(tag); } // for(nde) // additional thumbnail data is skipped } while (!destack.empty()); // // --- handle thumbnail data --- // const WORD entriesCount0th = ReadUint16(msb_order, ifd0th); DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th)); if((next_offset == 0) || (next_offset >= length)) { return TRUE; //< no thumbnail } const BYTE* const ifd1st = (BYTE*)tiffp + next_offset; const WORD entriesCount1st = ReadUint16(msb_order, ifd1st); unsigned thCompression = 0; unsigned thOffset = 0; unsigned thSize = 0; for(int e = 0; e < entriesCount1st; e++) { // point to the directory entry const BYTE* base = DIR_ENTRY_ADDR(ifd1st, e); // check for buffer overflow const size_t remaining = (size_t)base + 12 - (size_t)tiffp; if(remaining >= length) { // bad IFD1 directory, ignore it return FALSE; } // get the tag ID WORD tag = ReadUint16(msb_order, base); // get the tag type WORD type = ReadUint16(msb_order, base + sizeof(WORD)); // get number of components DWORD count = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD)); // get the tag value DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD)); switch(tag) { case TAG_COMPRESSION: // Tiff Compression Tag (should be COMPRESSION_OJPEG (6), but is not always respected) thCompression = offset; break; case TAG_JPEG_INTERCHANGE_FORMAT: // Tiff JPEGInterchangeFormat Tag thOffset = offset; break; case TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: // Tiff JPEGInterchangeFormatLength Tag thSize = offset; break; // ### X and Y Resolution ignored, orientation ignored case TAG_X_RESOLUTION: // XResolution case TAG_Y_RESOLUTION: // YResolution case TAG_RESOLUTION_UNIT: // ResolutionUnit case TAG_ORIENTATION: // Orientation break; default: break; } } if(/*thCompression != 6 ||*/ thOffset == 0 || thSize == 0) { return TRUE; } if(thOffset + thSize > length) { return TRUE; } // load the thumbnail const BYTE *thLocation = tiffp + thOffset; FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(thLocation), thSize); FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem); FreeImage_CloseMemory(hmem); // store the thumbnail FreeImage_SetThumbnail(dib, thumbnail); // then delete it FreeImage_Unload(thumbnail); return TRUE; }