* Added interface ErrorOutput and implementation StandardErrorOutput and used

them in the PackageReader instead of fprintf().
* Got rid of unconditional printf().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34084 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-11-17 11:33:50 +00:00
parent 96c4511a25
commit 6dccfe1317
10 changed files with 224 additions and 102 deletions
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "ErrorOutput.h"
#include <stdio.h>
ErrorOutput::~ErrorOutput()
{
}
void
ErrorOutput::PrintError(const char* format, ...)
{
va_list args;
va_start(args, format);
PrintErrorVarArgs(format, args);
va_end(args);
}
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ERROR_OUTPUT_H
#define ERROR_OUTPUT_H
#include <stdarg.h>
#include <SupportDefs.h>
class ErrorOutput {
public:
virtual ~ErrorOutput();
virtual void PrintErrorVarArgs(const char* format,
va_list args) = 0;
void PrintError(const char* format, ...);
};
#endif // ERROR_OUTPUT_H
+2
View File
@@ -16,6 +16,7 @@ BinCommand package :
command_list.cpp command_list.cpp
DataOutput.cpp DataOutput.cpp
DataReader.cpp DataReader.cpp
ErrorOutput.cpp
package.cpp package.cpp
PackageData.cpp PackageData.cpp
PackageDataReader.cpp PackageDataReader.cpp
@@ -23,6 +24,7 @@ BinCommand package :
PackageEntryAttribute.cpp PackageEntryAttribute.cpp
PackageReader.cpp PackageReader.cpp
PackageWriter.cpp PackageWriter.cpp
StandardErrorOutput.cpp
Strings.cpp Strings.cpp
# compression # compression
+126 -98
View File
@@ -22,12 +22,17 @@
#include <haiku_package.h> #include <haiku_package.h>
#include "DataOutput.h" #include "DataOutput.h"
#include "ErrorOutput.h"
#include "PackageData.h" #include "PackageData.h"
#include "PackageEntry.h" #include "PackageEntry.h"
#include "PackageEntryAttribute.h" #include "PackageEntryAttribute.h"
#include "ZlibDecompressor.h" #include "ZlibDecompressor.h"
//#define TRACE(format...) printf(format)
#define TRACE(format...) do {} while (false)
// maximum TOC size we support reading // maximum TOC size we support reading
static const size_t kMaxTOCSize = 64 * 1024 * 1024; static const size_t kMaxTOCSize = 64 * 1024 * 1024;
@@ -128,6 +133,7 @@ struct PackageReader::AttributeTypeReference {
struct PackageReader::AttributeHandlerContext { struct PackageReader::AttributeHandlerContext {
ErrorOutput* errorOutput;
union { union {
PackageContentHandler* packageContentHandler; PackageContentHandler* packageContentHandler;
LowLevelPackageContentHandler* lowLevelPackageContentHandler; LowLevelPackageContentHandler* lowLevelPackageContentHandler;
@@ -138,16 +144,19 @@ struct PackageReader::AttributeHandlerContext {
uint64 heapSize; uint64 heapSize;
AttributeHandlerContext(PackageContentHandler* packageContentHandler) AttributeHandlerContext(ErrorOutput* errorOutput,
PackageContentHandler* packageContentHandler)
: :
errorOutput(errorOutput),
packageContentHandler(packageContentHandler), packageContentHandler(packageContentHandler),
hasLowLevelHandler(false) hasLowLevelHandler(false)
{ {
} }
AttributeHandlerContext( AttributeHandlerContext(ErrorOutput* errorOutput,
LowLevelPackageContentHandler* lowLevelPackageContentHandler) LowLevelPackageContentHandler* lowLevelPackageContentHandler)
: :
errorOutput(errorOutput),
lowLevelPackageContentHandler(lowLevelPackageContentHandler), lowLevelPackageContentHandler(lowLevelPackageContentHandler),
hasLowLevelHandler(true) hasLowLevelHandler(true)
{ {
@@ -179,7 +188,7 @@ struct PackageReader::AttributeHandler
AttributeType* type, int8 typeIndex, const AttributeValue& value, AttributeType* type, int8 typeIndex, const AttributeValue& value,
AttributeHandler** _handler) AttributeHandler** _handler)
{ {
printf("%*signored attribute \"%s\" (%u)\n", fLevel * 2, "", type->name, type->type); TRACE("%*signored attribute \"%s\" (%u)\n", fLevel * 2, "", type->name, type->type);
return B_OK; return B_OK;
} }
@@ -249,8 +258,9 @@ struct PackageReader::DataAttributeHandler : AttributeHandler {
case B_HPKG_COMPRESSION_ZLIB: case B_HPKG_COMPRESSION_ZLIB:
break; break;
default: default:
fprintf(stderr, "Error: Invalid compression type for " context->errorOutput->PrintError("Error: Invalid "
"data (%llu)\n", value.unsignedInt); "compression type for data (%llu)\n",
value.unsignedInt);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -320,28 +330,30 @@ private:
struct PackageReader::EntryAttributeHandler : AttributeHandler { struct PackageReader::EntryAttributeHandler : AttributeHandler {
EntryAttributeHandler(PackageEntry* parentEntry, const char* name) EntryAttributeHandler(AttributeHandlerContext* context,
PackageEntry* parentEntry, const char* name)
: :
fEntry(parentEntry, name), fEntry(parentEntry, name),
fNotified(false) fNotified(false)
{ {
_SetFileType(B_HPKG_DEFAULT_FILE_TYPE); _SetFileType(context, B_HPKG_DEFAULT_FILE_TYPE);
} }
static status_t Create(PackageEntry* parentEntry, const char* name, static status_t Create(AttributeHandlerContext* context,
PackageEntry* parentEntry, const char* name,
AttributeHandler*& _handler) AttributeHandler*& _handler)
{ {
// check name // check name
if (name[0] == '\0' || strcmp(name, ".") == 0 if (name[0] == '\0' || strcmp(name, ".") == 0
|| strcmp(name, "..") == 0 || strchr(name, '/') != NULL) { || strcmp(name, "..") == 0 || strchr(name, '/') != NULL) {
fprintf(stderr, "Error: Invalid package: Invalid entry name: " context->errorOutput->PrintError("Error: Invalid package: Invalid "
"\"%s\"\n", name); "entry name: \"%s\"\n", name);
return B_BAD_DATA; return B_BAD_DATA;
} }
// create handler // create handler
EntryAttributeHandler* handler = new(std::nothrow) EntryAttributeHandler* handler = new(std::nothrow)
EntryAttributeHandler(parentEntry, name); EntryAttributeHandler(context, parentEntry, name);
if (handler == NULL) if (handler == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -360,16 +372,16 @@ struct PackageReader::EntryAttributeHandler : AttributeHandler {
if (error != B_OK) if (error != B_OK)
return error; return error;
//printf("%*sentry \"%s\"\n", fLevel * 2, "", value.string); //TRACE("%*sentry \"%s\"\n", fLevel * 2, "", value.string);
if (_handler != NULL) { if (_handler != NULL) {
return EntryAttributeHandler::Create(&fEntry, value.string, return EntryAttributeHandler::Create(context, &fEntry,
*_handler); value.string, *_handler);
} }
return B_OK; return B_OK;
} }
case ATTRIBUTE_INDEX_FILE_TYPE: case ATTRIBUTE_INDEX_FILE_TYPE:
return _SetFileType(value.unsignedInt); return _SetFileType(context, value.unsignedInt);
case ATTRIBUTE_INDEX_FILE_PERMISSIONS: case ATTRIBUTE_INDEX_FILE_PERMISSIONS:
fEntry.SetPermissions(value.unsignedInt); fEntry.SetPermissions(value.unsignedInt);
@@ -469,7 +481,7 @@ private:
return context->packageContentHandler->HandleEntry(&fEntry); return context->packageContentHandler->HandleEntry(&fEntry);
} }
status_t _SetFileType(uint64 fileType) status_t _SetFileType(AttributeHandlerContext* context, uint64 fileType)
{ {
switch (fileType) { switch (fileType) {
case B_HPKG_FILE_TYPE_FILE: case B_HPKG_FILE_TYPE_FILE:
@@ -485,8 +497,8 @@ private:
fEntry.SetPermissions(B_HPKG_DEFAULT_SYMLINK_PERMISSIONS); fEntry.SetPermissions(B_HPKG_DEFAULT_SYMLINK_PERMISSIONS);
break; break;
default: default:
fprintf(stderr, "Error: Invalid file type for package " context->errorOutput->PrintError("Error: Invalid file type for "
"entry (%llu)\n", fileType); "package entry (%llu)\n", fileType);
return B_BAD_DATA; return B_BAD_DATA;
} }
return B_OK; return B_OK;
@@ -504,10 +516,10 @@ struct PackageReader::RootAttributeHandler : AttributeHandler {
AttributeHandler** _handler) AttributeHandler** _handler)
{ {
if (typeIndex == ATTRIBUTE_INDEX_DIRECTORY_ENTRY) { if (typeIndex == ATTRIBUTE_INDEX_DIRECTORY_ENTRY) {
//printf("%*sentry \"%s\"\n", fLevel * 2, "", value.string); //TRACE("%*sentry \"%s\"\n", fLevel * 2, "", value.string);
if (_handler != NULL) { if (_handler != NULL) {
return EntryAttributeHandler::Create(NULL, value.string, return EntryAttributeHandler::Create(context, NULL,
*_handler); value.string, *_handler);
} }
return B_OK; return B_OK;
} }
@@ -604,9 +616,11 @@ PackageReader::_PopAttributeHandler()
} }
PackageReader::PackageReader() PackageReader::PackageReader(ErrorOutput* errorOutput)
: :
fErrorOutput(errorOutput),
fFD(-1), fFD(-1),
fOwnsFD(false),
fTOCSection(NULL), fTOCSection(NULL),
fAttributeTypes(NULL), fAttributeTypes(NULL),
fStrings(NULL), fStrings(NULL),
@@ -618,7 +632,7 @@ PackageReader::PackageReader()
PackageReader::~PackageReader() PackageReader::~PackageReader()
{ {
if (fFD >= 0) if (fOwnsFD && fFD >= 0)
close(fFD); close(fFD);
delete[] fScratchBuffer; delete[] fScratchBuffer;
@@ -632,18 +646,28 @@ status_t
PackageReader::Init(const char* fileName) PackageReader::Init(const char* fileName)
{ {
// open file // open file
fFD = open(fileName, O_RDONLY); int fd = open(fileName, O_RDONLY);
if (fFD < 0) { if (fd < 0) {
fprintf(stderr, "Error: Failed to open package file \"%s\": %s\n", fErrorOutput->PrintError("Error: Failed to open package file \"%s\": "
fileName, strerror(errno)); "%s\n", fileName, strerror(errno));
return errno; return errno;
} }
return Init(fd, true);
}
status_t
PackageReader::Init(int fd, bool keepFD)
{
fFD = fd;
fOwnsFD = keepFD;
// stat it // stat it
struct stat st; struct stat st;
if (fstat(fFD, &st) < 0) { if (fstat(fFD, &st) < 0) {
fprintf(stderr, "Error: Failed to access package file \"%s\": %s\n", fErrorOutput->PrintError("Error: Failed to access package file: %s\n",
fileName, strerror(errno)); strerror(errno));
return errno; return errno;
} }
@@ -657,33 +681,32 @@ PackageReader::Init(const char* fileName)
// magic // magic
if (B_BENDIAN_TO_HOST_INT32(header.magic) != B_HPKG_MAGIC) { if (B_BENDIAN_TO_HOST_INT32(header.magic) != B_HPKG_MAGIC) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: Invalid "
"Invalid magic\n", fileName); "magic\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
// 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)) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: Invalid header "
"Invalid header size (%llu)\n", fileName, fHeapOffset); "size (%llu)\n", fHeapOffset);
return B_BAD_DATA; return B_BAD_DATA;
} }
// version // version
if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) { if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
fprintf(stderr, "Error: Can't read package file \"%s\": " fErrorOutput->PrintError("Error: Invalid/unsupported package file "
"Invalid/unsupported version (%d)\n", fileName, "version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
B_BENDIAN_TO_HOST_INT16(header.version));
return B_BAD_DATA; 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) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: Total size in "
"Total size in header (%llu) doesn't agree with total file size " "header (%llu) doesn't agree with total file size (%lld)\n",
"(%lld)\n", fileName, fTotalSize, st.st_size); fTotalSize, st.st_size);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -698,8 +721,8 @@ PackageReader::Init(const char* fileName)
if (const char* errorString = _CheckCompression( if (const char* errorString = _CheckCompression(
fPackageAttributesCompression, fPackageAttributesCompressedLength, fPackageAttributesCompression, fPackageAttributesCompressedLength,
fPackageAttributesUncompressedLength)) { fPackageAttributesUncompressedLength)) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: package "
"package attributes section: %s\n", fileName, errorString); "attributes section: %s\n", errorString);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -712,8 +735,8 @@ PackageReader::Init(const char* fileName)
if (const char* errorString = _CheckCompression(fTOCCompression, if (const char* errorString = _CheckCompression(fTOCCompression,
fTOCCompressedLength, fTOCUncompressedLength)) { fTOCCompressedLength, fTOCUncompressedLength)) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: TOC section: "
"TOC section: %s\n", fileName, errorString); "%s\n", errorString);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -729,8 +752,8 @@ PackageReader::Init(const char* fileName)
|| fTOCStringsLength > fTOCUncompressedLength - fTOCAttributeTypesLength || fTOCStringsLength > fTOCUncompressedLength - fTOCAttributeTypesLength
|| fTOCAttributeTypesCount > fTOCAttributeTypesLength || fTOCAttributeTypesCount > fTOCAttributeTypesLength
|| fTOCStringsCount > fTOCStringsLength) { || fTOCStringsCount > fTOCStringsLength) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: Invalid TOC "
"Invalid TOC subsections description\n", fileName); "subsections description\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -741,9 +764,8 @@ PackageReader::Init(const char* fileName)
|| fHeapOffset || fHeapOffset
> fTotalSize - fPackageAttributesCompressedLength > fTotalSize - fPackageAttributesCompressedLength
- fTOCCompressedLength) { - fTOCCompressedLength) {
fprintf(stderr, "Error: File \"%s\" is not a valid package file: " fErrorOutput->PrintError("Error: Invalid package file: The sum of the "
"The sum of the sections sizes is greater than the package size\n", "sections sizes is greater than the package size\n");
fileName);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -753,8 +775,8 @@ PackageReader::Init(const char* fileName)
// TOC size sanity check // TOC size sanity check
if (fTOCUncompressedLength > kMaxTOCSize) { if (fTOCUncompressedLength > kMaxTOCSize) {
fprintf(stderr, "Error: Package file \"%s\" has a TOC section size of " fErrorOutput->PrintError("Error: Package file TOC section size "
"%llu bytes. This is beyond the reader's sanity limit\n", fileName, "is %llu bytes. This is beyond the reader's sanity limit\n",
fTOCUncompressedLength); fTOCUncompressedLength);
return B_UNSUPPORTED; return B_UNSUPPORTED;
} }
@@ -762,7 +784,7 @@ PackageReader::Init(const char* fileName)
// allocate a scratch buffer // allocate a scratch buffer
fScratchBuffer = new(std::nothrow) uint8[kScratchBufferSize]; fScratchBuffer = new(std::nothrow) uint8[kScratchBufferSize];
if (fScratchBuffer == NULL) { if (fScratchBuffer == NULL) {
fprintf(stderr, "Error: Out of memory!\n"); fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY; return B_NO_MEMORY;
} }
fScratchBufferSize = kScratchBufferSize; fScratchBufferSize = kScratchBufferSize;
@@ -770,7 +792,7 @@ PackageReader::Init(const char* fileName)
// read in the complete TOC // read in the complete TOC
fTOCSection = new(std::nothrow) uint8[fTOCUncompressedLength]; fTOCSection = new(std::nothrow) uint8[fTOCUncompressedLength];
if (fTOCSection == NULL) { if (fTOCSection == NULL) {
fprintf(stderr, "Error: Out of memory!\n"); fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY; return B_NO_MEMORY;
} }
@@ -801,7 +823,7 @@ PackageReader::Init(const char* fileName)
status_t status_t
PackageReader::ParseContent(PackageContentHandler* contentHandler) PackageReader::ParseContent(PackageContentHandler* contentHandler)
{ {
AttributeHandlerContext context(contentHandler); AttributeHandlerContext context(fErrorOutput, contentHandler);
RootAttributeHandler rootAttributeHandler; RootAttributeHandler rootAttributeHandler;
return _ParseContent(&context, &rootAttributeHandler); return _ParseContent(&context, &rootAttributeHandler);
} }
@@ -810,7 +832,7 @@ PackageReader::ParseContent(PackageContentHandler* contentHandler)
status_t status_t
PackageReader::ParseContent(LowLevelPackageContentHandler* contentHandler) PackageReader::ParseContent(LowLevelPackageContentHandler* contentHandler)
{ {
AttributeHandlerContext context(contentHandler); AttributeHandlerContext context(fErrorOutput, contentHandler);
PackageAttributeHandler rootAttributeHandler; PackageAttributeHandler rootAttributeHandler;
return _ParseContent(&context, &rootAttributeHandler); return _ParseContent(&context, &rootAttributeHandler);
} }
@@ -848,7 +870,7 @@ PackageReader::_ParseTOCAttributeTypes()
fAttributeTypes = new(std::nothrow) AttributeTypeReference[ fAttributeTypes = new(std::nothrow) AttributeTypeReference[
fTOCAttributeTypesCount]; fTOCAttributeTypesCount];
if (fAttributeTypes == NULL) { if (fAttributeTypes == NULL) {
fprintf(stderr, "Error: Out of memory!\n"); fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY; return B_NO_MEMORY;
} }
@@ -858,7 +880,8 @@ PackageReader::_ParseTOCAttributeTypes()
uint32 index = 0; uint32 index = 0;
while (true) { while (true) {
if (position >= sectionEnd) { if (position >= sectionEnd) {
fprintf(stderr, "Error: Malformed TOC attribute types section\n"); fErrorOutput->PrintError("Error: Malformed TOC attribute types "
"section\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -866,15 +889,15 @@ PackageReader::_ParseTOCAttributeTypes()
if (type->type == 0) { if (type->type == 0) {
if (position + 1 != sectionEnd) { if (position + 1 != sectionEnd) {
fprintf(stderr, "Error: Excess bytes in TOC attribute types " fErrorOutput->PrintError("Error: Excess bytes in TOC attribute "
"section\n"); "types section\n");
printf("position: %p, sectionEnd: %p\n", position, sectionEnd); TRACE("position: %p, sectionEnd: %p\n", position, sectionEnd);
return B_BAD_DATA; return B_BAD_DATA;
} }
if (index != fTOCAttributeTypesCount) { if (index != fTOCAttributeTypesCount) {
fprintf(stderr, "Error: Invalid TOC attribute types section: " fErrorOutput->PrintError("Error: Invalid TOC attribute types "
"Less types than specified in the header\n"); "section: Less types than specified in the header\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -882,8 +905,8 @@ printf("position: %p, sectionEnd: %p\n", position, sectionEnd);
} }
if (index >= fTOCAttributeTypesCount) { if (index >= fTOCAttributeTypesCount) {
fprintf(stderr, "Error: Invalid TOC attribute types section: " fErrorOutput->PrintError("Error: Invalid TOC attribute types "
"More types than specified in the header\n"); "section: More types than specified in the header\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -893,7 +916,7 @@ printf("position: %p, sectionEnd: %p\n", position, sectionEnd);
fAttributeTypes[index].type = type; fAttributeTypes[index].type = type;
fAttributeTypes[index].standardIndex = _GetStandardIndex(type); fAttributeTypes[index].standardIndex = _GetStandardIndex(type);
index++; index++;
printf("type: %u, \"%s\"\n", type->type, type->name); TRACE("type: %u, \"%s\"\n", type->type, type->name);
} }
} }
@@ -904,7 +927,7 @@ PackageReader::_ParseTOCStrings()
// allocate table // allocate table
fStrings = new(std::nothrow) char*[fTOCStringsCount]; fStrings = new(std::nothrow) char*[fTOCStringsCount];
if (fStrings == NULL) { if (fStrings == NULL) {
fprintf(stderr, "Error: Out of memory!\n"); fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY; return B_NO_MEMORY;
} }
@@ -914,7 +937,7 @@ PackageReader::_ParseTOCStrings()
uint32 index = 0; uint32 index = 0;
while (true) { while (true) {
if (position >= sectionEnd) { if (position >= sectionEnd) {
fprintf(stderr, "Error: Malformed TOC strings section\n"); fErrorOutput->PrintError("Error: Malformed TOC strings section\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -922,13 +945,14 @@ PackageReader::_ParseTOCStrings()
if (stringLength == 0) { if (stringLength == 0) {
if (position + 1 != sectionEnd) { if (position + 1 != sectionEnd) {
fprintf(stderr, "Error: Excess bytes in TOC strings section\n"); fErrorOutput->PrintError("Error: Excess bytes in TOC strings "
printf("position: %p, sectionEnd: %p\n", position, sectionEnd); "section\n");
TRACE("position: %p, sectionEnd: %p\n", position, sectionEnd);
return B_BAD_DATA; return B_BAD_DATA;
} }
if (index != fTOCStringsCount) { if (index != fTOCStringsCount) {
fprintf(stderr, "Error: Invalid TOC strings section: " fErrorOutput->PrintError("Error: Invalid TOC strings section: "
"Less strings than specified in the header\n"); "Less strings than specified in the header\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -937,13 +961,13 @@ printf("position: %p, sectionEnd: %p\n", position, sectionEnd);
} }
if (index >= fTOCStringsCount) { if (index >= fTOCStringsCount) {
fprintf(stderr, "Error: Invalid TOC strings section: " fErrorOutput->PrintError("Error: Invalid TOC strings section: "
"More strings than specified in the header\n"); "More strings than specified in the header\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
fStrings[index++] = position; fStrings[index++] = position;
printf("string: \"%s\"\n", position); TRACE("string: \"%s\"\n", position);
position += stringLength + 1; position += stringLength + 1;
} }
} }
@@ -969,8 +993,8 @@ PackageReader::_ParseContent(AttributeHandlerContext* context,
status_t error = _ParseAttributeTree(context); status_t error = _ParseAttributeTree(context);
if (error == B_OK) { if (error == B_OK) {
if (fCurrentTOCOffset < fTOCUncompressedLength) { if (fCurrentTOCOffset < fTOCUncompressedLength) {
fprintf(stderr, "Error: %llu excess byte(s) in TOC section\n", fErrorOutput->PrintError("Error: %llu excess byte(s) in TOC "
fTOCUncompressedLength - fCurrentTOCOffset); "section\n", fTOCUncompressedLength - fCurrentTOCOffset);
error = B_BAD_DATA; error = B_BAD_DATA;
} }
} }
@@ -1015,7 +1039,7 @@ PackageReader::_ParseAttributeTree(AttributeHandlerContext* context)
// get the type // get the type
uint64 typeIndex = B_HPKG_ATTRIBUTE_TAG_INDEX(tag); uint64 typeIndex = B_HPKG_ATTRIBUTE_TAG_INDEX(tag);
if (typeIndex >= fTOCAttributeTypesCount) { if (typeIndex >= fTOCAttributeTypesCount) {
fprintf(stderr, "Error: Invalid TOC section: " fErrorOutput->PrintError("Error: Invalid TOC section: "
"Invalid attribute type index\n"); "Invalid attribute type index\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1042,7 +1066,7 @@ PackageReader::_ParseAttributeTree(AttributeHandlerContext* context)
if (childHandler == NULL) { if (childHandler == NULL) {
childHandler = new(std::nothrow) IgnoreAttributeHandler; childHandler = new(std::nothrow) IgnoreAttributeHandler;
if (childHandler == NULL) { if (childHandler == NULL) {
fprintf(stderr, "Error: Out of memory!\n"); fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY; return B_NO_MEMORY;
} }
} }
@@ -1097,9 +1121,10 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
} }
default: default:
{ {
fprintf(stderr, "Error: Invalid TOC section: invalid " fErrorOutput->PrintError("Error: Invalid TOC section: "
"encoding %d for int value type %d\n", encoding, type); "invalid encoding %d for int value type %d\n", encoding,
throw status_t(B_BAD_VALUE); type);
return B_BAD_VALUE;
} }
} }
@@ -1123,8 +1148,8 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
return error; return error;
if (index > fTOCStringsCount) { if (index > fTOCStringsCount) {
fprintf(stderr, "Error: Invalid TOC section: string " fErrorOutput->PrintError("Error: Invalid TOC section: "
"reference out of bounds\n"); "string reference out of bounds\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1137,8 +1162,8 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
_value.SetTo(string); _value.SetTo(string);
} else { } else {
fprintf(stderr, "Error: Invalid TOC section: invalid string " fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
"encoding (%u)\n", encoding); "string encoding (%u)\n", encoding);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1159,16 +1184,16 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
return error; return error;
if (offset > fHeapSize || size > fHeapSize - offset) { if (offset > fHeapSize || size > fHeapSize - offset) {
fprintf(stderr, "Error: Invalid TOC section: invalid data " fErrorOutput->PrintError("Error: Invalid TOC section: "
"reference\n"); "invalid data reference\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
_value.SetToData(size, fHeapOffset + offset); _value.SetToData(size, fHeapOffset + offset);
} else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) { } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) {
if (size > B_HPKG_MAX_INLINE_DATA_SIZE) { if (size > B_HPKG_MAX_INLINE_DATA_SIZE) {
fprintf(stderr, "Error: Invalid TOC section: inline data " fErrorOutput->PrintError("Error: Invalid TOC section: "
"too long\n"); "inline data too long\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1178,8 +1203,8 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
return error; return error;
_value.SetToData(size, buffer); _value.SetToData(size, buffer);
} else { } else {
fprintf(stderr, "Error: Invalid TOC section: invalid raw " fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
"encoding (%u)\n", encoding); "raw encoding (%u)\n", encoding);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1187,8 +1212,8 @@ PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
} }
default: default:
fprintf(stderr, "Error: Invalid TOC section: invalid value type: " fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
"%d\n", type); "value type: %d\n", type);
return B_BAD_DATA; return B_BAD_DATA;
} }
} }
@@ -1224,7 +1249,8 @@ PackageReader::_ReadString(const char*& _string, size_t* _stringLength)
fTOCUncompressedLength - fCurrentTOCOffset); fTOCUncompressedLength - fCurrentTOCOffset);
if (stringLength == fTOCUncompressedLength - fCurrentTOCOffset) { if (stringLength == fTOCUncompressedLength - fCurrentTOCOffset) {
fprintf(stderr, "_ReadString(): string extends beyond TOC end\n"); fErrorOutput->PrintError("_ReadString(): string extends beyond TOC "
"end\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1241,7 +1267,8 @@ status_t
PackageReader::_GetTOCBuffer(size_t size, const void*& _buffer) PackageReader::_GetTOCBuffer(size_t size, const void*& _buffer)
{ {
if (size > fTOCUncompressedLength - fCurrentTOCOffset) { if (size > fTOCUncompressedLength - fCurrentTOCOffset) {
fprintf(stderr, "_GetTOCBuffer(%lu): read beyond TOC end\n", size); fErrorOutput->PrintError("_GetTOCBuffer(%lu): read beyond TOC end\n",
size);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1255,7 +1282,8 @@ status_t
PackageReader::_ReadTOCBuffer(void* buffer, size_t size) PackageReader::_ReadTOCBuffer(void* buffer, size_t size)
{ {
if (size > fTOCUncompressedLength - fCurrentTOCOffset) { if (size > fTOCUncompressedLength - fCurrentTOCOffset) {
fprintf(stderr, "_ReadTOCBuffer(%lu): read beyond TOC end\n", size); fErrorOutput->PrintError("_ReadTOCBuffer(%lu): read beyond TOC end\n",
size);
return B_BAD_DATA; return B_BAD_DATA;
} }
@@ -1270,13 +1298,13 @@ PackageReader::_ReadBuffer(off_t offset, void* buffer, size_t size)
{ {
ssize_t bytesRead = pread(fFD, buffer, size, offset); ssize_t bytesRead = pread(fFD, buffer, size, offset);
if (bytesRead < 0) { if (bytesRead < 0) {
fprintf(stderr, "_ReadBuffer(%p, %lu) failed to read data: %s\n", fErrorOutput->PrintError("_ReadBuffer(%p, %lu) failed to read data: "
buffer, size, strerror(errno)); "%s\n", buffer, size, strerror(errno));
return errno; return errno;
} }
if ((size_t)bytesRead != size) { if ((size_t)bytesRead != size) {
fprintf(stderr, "_ReadBuffer(%p, %lu) failed to read all data\n", fErrorOutput->PrintError("_ReadBuffer(%p, %lu) failed to read all "
buffer, size); "data\n", buffer, size);
return B_ERROR; return B_ERROR;
} }
@@ -1323,7 +1351,7 @@ PackageReader::_ReadCompressedBuffer(off_t offset, void* buffer,
// verify that all data have been read // verify that all data have been read
if (bufferOutput.BytesWritten() != uncompressedSize) { if (bufferOutput.BytesWritten() != uncompressedSize) {
fprintf(stderr, "Error: Missing bytes in uncompressed " fErrorOutput->PrintError("Error: Missing bytes in uncompressed "
"buffer!\n"); "buffer!\n");
return B_BAD_DATA; return B_BAD_DATA;
} }
+5 -1
View File
@@ -13,6 +13,7 @@
#include "PackageAttributeValue.h" #include "PackageAttributeValue.h"
class ErrorOutput;
class PackageEntry; class PackageEntry;
class PackageEntryAttribute; class PackageEntryAttribute;
@@ -47,10 +48,11 @@ public:
class PackageReader { class PackageReader {
public: public:
PackageReader(); PackageReader(ErrorOutput* errorOutput);
~PackageReader(); ~PackageReader();
status_t Init(const char* fileName); status_t Init(const char* fileName);
status_t Init(int fd, bool keepFD);
status_t ParseContent( status_t ParseContent(
PackageContentHandler* contentHandler); PackageContentHandler* contentHandler);
status_t ParseContent( status_t ParseContent(
@@ -119,7 +121,9 @@ private:
inline AttributeHandler* _PopAttributeHandler(); inline AttributeHandler* _PopAttributeHandler();
private: private:
ErrorOutput* fErrorOutput;
int fFD; int fFD;
bool fOwnsFD;
uint64 fTotalSize; uint64 fTotalSize;
uint64 fHeapOffset; uint64 fHeapOffset;
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "StandardErrorOutput.h"
#include <stdio.h>
void
StandardErrorOutput::PrintErrorVarArgs(const char* format, va_list args)
{
vfprintf(stderr, format, args);
}
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef STANDARD_ERROR_OUTPUT_H
#define STANDARD_ERROR_OUTPUT_H
#include "ErrorOutput.h"
class StandardErrorOutput : public ErrorOutput {
virtual void PrintErrorVarArgs(const char* format,
va_list args);
};
#endif // STANDARD_ERROR_OUTPUT_H
+3 -1
View File
@@ -17,6 +17,7 @@
#include "PackageEntry.h" #include "PackageEntry.h"
#include "PackageEntryAttribute.h" #include "PackageEntryAttribute.h"
#include "PackageReader.h" #include "PackageReader.h"
#include "StandardErrorOutput.h"
struct PackageContentDumpHandler : LowLevelPackageContentHandler { struct PackageContentDumpHandler : LowLevelPackageContentHandler {
@@ -135,7 +136,8 @@ command_dump(int argc, const char* const* argv)
const char* packageFileName = argv[optind++]; const char* packageFileName = argv[optind++];
// open package // open package
PackageReader packageReader; StandardErrorOutput errorOutput;
PackageReader packageReader(&errorOutput);
status_t error = packageReader.Init(packageFileName); status_t error = packageReader.Init(packageFileName);
printf("Init(): %s\n", strerror(error)); printf("Init(): %s\n", strerror(error));
if (error != B_OK) if (error != B_OK)
+3 -1
View File
@@ -29,6 +29,7 @@
#include "PackageEntry.h" #include "PackageEntry.h"
#include "PackageEntryAttribute.h" #include "PackageEntryAttribute.h"
#include "PackageReader.h" #include "PackageReader.h"
#include "StandardErrorOutput.h"
struct PackageContentExtractHandler : PackageContentHandler { struct PackageContentExtractHandler : PackageContentHandler {
@@ -328,7 +329,8 @@ command_extract(int argc, const char* const* argv)
const char* packageFileName = argv[optind++]; const char* packageFileName = argv[optind++];
// open package // open package
PackageReader packageReader; StandardErrorOutput errorOutput;
PackageReader packageReader(&errorOutput);
status_t error = packageReader.Init(packageFileName); status_t error = packageReader.Init(packageFileName);
printf("Init(): %s\n", strerror(error)); printf("Init(): %s\n", strerror(error));
if (error != B_OK) if (error != B_OK)
+3 -1
View File
@@ -17,6 +17,7 @@
#include "PackageEntry.h" #include "PackageEntry.h"
#include "PackageEntryAttribute.h" #include "PackageEntryAttribute.h"
#include "PackageReader.h" #include "PackageReader.h"
#include "StandardErrorOutput.h"
struct PackageContentListHandler : PackageContentHandler { struct PackageContentListHandler : PackageContentHandler {
@@ -163,7 +164,8 @@ command_list(int argc, const char* const* argv)
const char* packageFileName = argv[optind++]; const char* packageFileName = argv[optind++];
// open package // open package
PackageReader packageReader; StandardErrorOutput errorOutput;
PackageReader packageReader(&errorOutput);
status_t error = packageReader.Init(packageFileName); status_t error = packageReader.Init(packageFileName);
printf("Init(): %s\n", strerror(error)); printf("Init(): %s\n", strerror(error));
if (error != B_OK) if (error != B_OK)