package kit: some fixes for multi-version support

* Use enums/constants/functions instead of preprocessor macros.
* Missing include in PackageInfoAttributeValue.h.
* PackageReaderImpl::Init(): Check version before header size and
  return B_MISMATCHED_VALUES instead of B_BAD_DATA, if the version
  doesn't match. This allows callers to determine the condition and
  try a reader for a different version. A more flexible interface for
  that case would be nice, but since we want to support the old package
  version only temporarily, the current solution should be good enough.
This commit is contained in:
Ingo Weinhold
2013-05-25 01:12:21 +02:00
parent 7e7232aca8
commit 171fd58c4b
14 changed files with 87 additions and 31 deletions
+4 -2
View File
@@ -73,11 +73,13 @@ enum {
// maximum number of bytes of data to be encoded inline; more will be allocated // maximum number of bytes of data to be encoded inline; more will be allocated
// on the heap // on the heap
#define B_HPKG_MAX_INLINE_DATA_SIZE 8 enum {
B_HPKG_MAX_INLINE_DATA_SIZE = 8
};
// name of file containing package information (in package's root folder) // name of file containing package information (in package's root folder)
#define B_HPKG_PACKAGE_INFO_FILE_NAME ".PackageInfo" extern const char* const B_HPKG_PACKAGE_INFO_FILE_NAME;
// package attribute IDs // package attribute IDs
@@ -8,6 +8,8 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include <string.h>
#include <package/PackageArchitecture.h> #include <package/PackageArchitecture.h>
#include <package/PackageInfoAttributes.h> #include <package/PackageInfoAttributes.h>
#include <package/PackageResolvableOperator.h> #include <package/PackageResolvableOperator.h>
+35 -11
View File
@@ -64,17 +64,41 @@ struct hpkg_repo_header {
// attribute tag arithmetics // attribute tag arithmetics
// (using 6 bits for id, 3 for type, 1 for hasChildren and 2 for encoding) // (using 6 bits for id, 3 for type, 1 for hasChildren and 2 for encoding)
#define HPKG_ATTRIBUTE_TAG_COMPOSE(id, type, encoding, hasChildren) \ static inline uint16
(((uint16(encoding) << 10) | (uint16((hasChildren) ? 1 : 0) << 9) \ compose_attribute_tag(uint16 id, uint16 type, uint16 encoding, bool hasChildren)
| (uint16(type) << 6) | (uint16(id))) + 1) {
#define HPKG_ATTRIBUTE_TAG_ENCODING(tag) \ return ((encoding << 10) | (uint16(hasChildren ? 1 : 0) << 9) | (type << 6)
((uint16((tag) - 1) >> 10) & 0x3) | id)
#define HPKG_ATTRIBUTE_TAG_HAS_CHILDREN(tag) \ + 1;
(((uint16((tag) - 1) >> 9) & 0x1) != 0) }
#define HPKG_ATTRIBUTE_TAG_TYPE(tag) \
((uint16((tag) - 1) >> 6) & 0x7)
#define HPKG_ATTRIBUTE_TAG_ID(tag) \ static inline uint16
(uint16((tag) - 1) & 0x3f) attribute_tag_encoding(uint16 tag)
{
return ((tag - 1) >> 10) & 0x3;
}
static inline bool
attribute_tag_has_children(uint16 tag)
{
return (((tag - 1) >> 9) & 0x1) != 0;
}
static inline uint16
attribute_tag_type(uint16 tag)
{
return ((tag - 1) >> 6) & 0x7;
}
static inline uint16
attribute_tag_id(uint16 tag)
{
return (tag - 1) & 0x3f;
}
} // namespace BPrivate } // namespace BPrivate
@@ -77,6 +77,7 @@ HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES =
DataReader.cpp DataReader.cpp
ErrorOutput.cpp ErrorOutput.cpp
FDDataReader.cpp FDDataReader.cpp
HPKGDefs.cpp
PackageContentHandler.cpp PackageContentHandler.cpp
PackageData.cpp PackageData.cpp
PackageDataReader.cpp PackageDataReader.cpp
@@ -956,8 +956,10 @@ Volume::_AddPackageContent(Package* package, bool notify)
for (PackageNodeList::Iterator it = package->Nodes().GetIterator(); for (PackageNodeList::Iterator it = package->Nodes().GetIterator();
PackageNode* node = it.Next();) { PackageNode* node = it.Next();) {
// skip over ".PackageInfo" file, it isn't part of the package content // skip over ".PackageInfo" file, it isn't part of the package content
if (strcmp(node->Name(), B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) if (strcmp(node->Name(),
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
continue; continue;
}
error = _AddPackageContentRootNode(package, node, notify); error = _AddPackageContentRootNode(package, node, notify);
if (error != B_OK) { if (error != B_OK) {
_RemovePackageContent(package, node, notify); _RemovePackageContent(package, node, notify);
@@ -981,8 +983,10 @@ Volume::_RemovePackageContent(Package* package, PackageNode* endNode,
PackageNode* nextNode = package->Nodes().GetNext(node); PackageNode* nextNode = package->Nodes().GetNext(node);
// skip over ".PackageInfo" file, it isn't part of the package content // skip over ".PackageInfo" file, it isn't part of the package content
if (strcmp(node->Name(), B_HPKG_PACKAGE_INFO_FILE_NAME) != 0) if (strcmp(node->Name(),
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) != 0) {
_RemovePackageContentRootNode(package, node, NULL, notify); _RemovePackageContentRootNode(package, node, NULL, notify);
}
node = nextNode; node = nextNode;
} }
+2 -1
View File
@@ -36,7 +36,8 @@ add_current_directory_entries(BPackageWriter& packageWriter,
// skip the .PackageInfo, if requested // skip the .PackageInfo, if requested
if (skipPackageInfo if (skipPackageInfo
&& strcmp(entry->d_name, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) { && strcmp(entry->d_name,
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
continue; continue;
} }
+2 -2
View File
@@ -150,8 +150,8 @@ command_create(int argc, const char* const* argv)
} }
// add the .PackageInfo // add the .PackageInfo
result = packageWriter.AddEntry(B_HPKG_PACKAGE_INFO_FILE_NAME, result = packageWriter.AddEntry(
packageInfoFD); BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME, packageInfoFD);
if (result != B_OK) if (result != B_OK)
return 1; return 1;
+1
View File
@@ -28,6 +28,7 @@ HPKG_SOURCES =
DataReader.cpp DataReader.cpp
ErrorOutput.cpp ErrorOutput.cpp
FDDataReader.cpp FDDataReader.cpp
HPKGDefs.cpp
PackageContentHandler.cpp PackageContentHandler.cpp
PackageData.cpp PackageData.cpp
PackageDataReader.cpp PackageDataReader.cpp
+1
View File
@@ -19,6 +19,7 @@ HPKG_SOURCES =
DataReader.cpp DataReader.cpp
ErrorOutput.cpp ErrorOutput.cpp
FDDataReader.cpp FDDataReader.cpp
HPKGDefs.cpp
PackageContentHandler.cpp PackageContentHandler.cpp
PackageData.cpp PackageData.cpp
PackageDataReader.cpp PackageDataReader.cpp
+20
View File
@@ -0,0 +1,20 @@
/*
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <package/hpkg/HPKGDefs.h>
namespace BPackageKit {
namespace BHPKG {
const char* const B_HPKG_PACKAGE_INFO_FILE_NAME = ".PackageInfo";
} // namespace BHPKG
} // namespace BPackageKit
+7 -7
View File
@@ -433,6 +433,13 @@ PackageReaderImpl::Init(int fd, bool keepFD)
return B_BAD_DATA; return B_BAD_DATA;
} }
// version
if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
ErrorOutput()->PrintError("Error: Invalid/unsupported package file "
"version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
return B_MISMATCHED_VALUES;
}
// header size // header size
fHeapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size); fHeapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
if ((size_t)fHeapOffset < sizeof(hpkg_header)) { if ((size_t)fHeapOffset < sizeof(hpkg_header)) {
@@ -441,13 +448,6 @@ PackageReaderImpl::Init(int fd, bool keepFD)
return B_BAD_DATA; return B_BAD_DATA;
} }
// version
if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
ErrorOutput()->PrintError("Error: Invalid/unsupported package file "
"version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
return B_BAD_DATA;
}
// total size // total size
fTotalSize = B_BENDIAN_TO_HOST_INT64(header.total_size); fTotalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
if (fTotalSize != (uint64)st.st_size) { if (fTotalSize != (uint64)st.st_size) {
+1 -1
View File
@@ -1442,7 +1442,7 @@ PackageWriterImpl::_WriteAttributeChildren(Attribute* attribute)
while (Attribute* child = it.Next()) { while (Attribute* child = it.Next()) {
// write tag // write tag
uint8 encoding = child->value.ApplicableEncoding(); uint8 encoding = child->value.ApplicableEncoding();
WriteUnsignedLEB128(HPKG_ATTRIBUTE_TAG_COMPOSE(child->id, WriteUnsignedLEB128(compose_attribute_tag(child->id,
child->value.type, encoding, !child->children.IsEmpty())); child->value.type, encoding, !child->children.IsEmpty()));
// write value // write value
+4 -4
View File
@@ -799,7 +799,7 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
if (tag != 0) { if (tag != 0) {
// get the type // get the type
uint16 type = HPKG_ATTRIBUTE_TAG_TYPE(tag); uint16 type = attribute_tag_type(tag);
if (type >= B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT) { if (type >= B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid %s section: attribute " fErrorOutput->PrintError("Error: Invalid %s section: attribute "
"type %d not supported!\n", fCurrentSection->name, type); "type %d not supported!\n", fCurrentSection->name, type);
@@ -807,12 +807,12 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
} }
// get the value // get the value
error = ReadAttributeValue(type, HPKG_ATTRIBUTE_TAG_ENCODING(tag), error = ReadAttributeValue(type, attribute_tag_encoding(tag),
_value); _value);
if (error != B_OK) if (error != B_OK)
return error; return error;
_id = HPKG_ATTRIBUTE_TAG_ID(tag); _id = attribute_tag_id(tag);
if (_id >= B_HPKG_ATTRIBUTE_ID_ENUM_COUNT) { if (_id >= B_HPKG_ATTRIBUTE_ID_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid %s section: " fErrorOutput->PrintError("Error: Invalid %s section: "
"attribute id %d not supported!\n", fCurrentSection->name, _id); "attribute id %d not supported!\n", fCurrentSection->name, _id);
@@ -821,7 +821,7 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
} }
if (_hasChildren != NULL) if (_hasChildren != NULL)
*_hasChildren = HPKG_ATTRIBUTE_TAG_HAS_CHILDREN(tag); *_hasChildren = attribute_tag_has_children(tag);
if (_tag != NULL) if (_tag != NULL)
*_tag = tag; *_tag = tag;
+1 -1
View File
@@ -782,7 +782,7 @@ WriterImplBase::_WritePackageAttributes(
uint8 encoding = attribute->ApplicableEncoding(); uint8 encoding = attribute->ApplicableEncoding();
// write tag // write tag
WriteUnsignedLEB128(HPKG_ATTRIBUTE_TAG_COMPOSE( WriteUnsignedLEB128(compose_attribute_tag(
attribute->id, attribute->type, encoding, attribute->id, attribute->type, encoding,
!attribute->children.IsEmpty())); !attribute->children.IsEmpty()));