status_t PackageReaderImpl::ReadAttributeValue(uint8 type, uint8 encoding, AttributeValue& _value) { switch (type) { case B_HPKG_ATTRIBUTE_TYPE_RAW: { uint64 size; status_t error = ReadUnsignedLEB128(size); if (error != B_OK) return error; if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP) { uint64 offset; error = ReadUnsignedLEB128(offset); if (error != B_OK) return error; if (offset > fHeapSize || size > fHeapSize - offset) { ErrorOutput()->PrintError("Error: Invalid %s section: " "invalid data reference\n", CurrentSection()->name); return B_BAD_DATA; } _value.SetToData(size, offset); } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) { if (size > B_HPKG_MAX_INLINE_DATA_SIZE) { ErrorOutput()->PrintError("Error: Invalid %s section: " "inline data too long\n", CurrentSection()->name); return B_BAD_DATA; } const void* buffer; error = _GetTOCBuffer(size, buffer); if (error != B_OK) return error; _value.SetToData(size, buffer); } else { ErrorOutput()->PrintError("Error: Invalid %s section: invalid " "raw encoding (%u)\n", CurrentSection()->name, encoding); return B_BAD_DATA; } return B_OK; } default: return inherited::ReadAttributeValue(type, encoding, _value); } }
status_t PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding, AttributeValue& _value) { switch (type) { case B_HPKG_ATTRIBUTE_TYPE_INT: case B_HPKG_ATTRIBUTE_TYPE_UINT: { uint64 intValue; status_t error; switch (encoding) { case B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT: { uint8 value; error = _Read(value); intValue = value; break; } case B_HPKG_ATTRIBUTE_ENCODING_INT_16_BIT: { uint16 value; error = _Read(value); intValue = B_BENDIAN_TO_HOST_INT16(value); break; } case B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT: { uint32 value; error = _Read(value); intValue = B_BENDIAN_TO_HOST_INT32(value); break; } case B_HPKG_ATTRIBUTE_ENCODING_INT_64_BIT: { uint64 value; error = _Read(value); intValue = B_BENDIAN_TO_HOST_INT64(value); break; } default: { fErrorOutput->PrintError("Error: Invalid TOC section: " "invalid encoding %d for int value type %d\n", encoding, type); return B_BAD_VALUE; } } if (error != B_OK) return error; if (type == B_HPKG_ATTRIBUTE_TYPE_INT) _value.SetTo((int64)intValue); else _value.SetTo(intValue); return B_OK; } case B_HPKG_ATTRIBUTE_TYPE_STRING: { if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE) { uint64 index; status_t error = _ReadUnsignedLEB128(index); if (error != B_OK) return error; if (index > fTOCStringsCount) { fErrorOutput->PrintError("Error: Invalid TOC section: " "string reference out of bounds\n"); return B_BAD_DATA; } _value.SetTo(fStrings[index]); } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE) { const char* string; status_t error = _ReadString(string); if (error != B_OK) return error; _value.SetTo(string); } else { fErrorOutput->PrintError("Error: Invalid TOC section: invalid " "string encoding (%u)\n", encoding); return B_BAD_DATA; } return B_OK; } case B_HPKG_ATTRIBUTE_TYPE_RAW: { uint64 size; status_t error = _ReadUnsignedLEB128(size); if (error != B_OK) return error; if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP) { uint64 offset; error = _ReadUnsignedLEB128(offset); if (error != B_OK) return error; if (offset > fHeapSize || size > fHeapSize - offset) { fErrorOutput->PrintError("Error: Invalid TOC section: " "invalid data reference\n"); return B_BAD_DATA; } _value.SetToData(size, fHeapOffset + offset); } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) { if (size > B_HPKG_MAX_INLINE_DATA_SIZE) { fErrorOutput->PrintError("Error: Invalid TOC section: " "inline data too long\n"); return B_BAD_DATA; } const void* buffer; error = _GetTOCBuffer(size, buffer); if (error != B_OK) return error; _value.SetToData(size, buffer); } else { fErrorOutput->PrintError("Error: Invalid TOC section: invalid " "raw encoding (%u)\n", encoding); return B_BAD_DATA; } return B_OK; } default: fErrorOutput->PrintError("Error: Invalid TOC section: invalid " "value type: %d\n", type); return B_BAD_DATA; } }