diff --git a/headers/build/os/app/Message.h b/headers/build/os/app/Message.h index 231c526c9d..9ec0a35582 100644 --- a/headers/build/os/app/Message.h +++ b/headers/build/os/app/Message.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007, Haiku Inc. All Rights Reserved. + * Copyright 2005-2009, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -106,9 +106,13 @@ class BMessage { status_t AddString(const char *name, const char *aString); status_t AddString(const char *name, const BString &aString); status_t AddInt8(const char *name, int8 value); + status_t AddUInt8(const char *name, uint8 value); status_t AddInt16(const char *name, int16 value); + status_t AddUInt16(const char *name, uint16 value); status_t AddInt32(const char *name, int32 value); + status_t AddUInt32(const char *name, uint32 value); status_t AddInt64(const char *name, int64 value); + status_t AddUInt64(const char *name, uint64 value); status_t AddBool(const char *name, bool aBoolean); status_t AddFloat(const char *name, float aFloat); status_t AddDouble(const char *name, double aDouble); @@ -138,12 +142,20 @@ class BMessage { status_t FindString(const char *name, int32 index, BString *string) const; status_t FindInt8(const char *name, int8 *value) const; status_t FindInt8(const char *name, int32 index, int8 *value) const; + status_t FindUInt8(const char *name, uint8 *value) const; + status_t FindUInt8(const char *name, int32 index, uint8 *value) const; status_t FindInt16(const char *name, int16 *value) const; status_t FindInt16(const char *name, int32 index, int16 *value) const; + status_t FindUInt16(const char *name, uint16 *value) const; + status_t FindUInt16(const char *name, int32 index, uint16 *value) const; status_t FindInt32(const char *name, int32 *value) const; status_t FindInt32(const char *name, int32 index, int32 *value) const; + status_t FindUInt32(const char *name, uint32 *value) const; + status_t FindUInt32(const char *name, int32 index, uint32 *value) const; status_t FindInt64(const char *name, int64 *value) const; status_t FindInt64(const char *name, int32 index, int64 *value) const; + status_t FindUInt64(const char *name, uint64 *value) const; + status_t FindUInt64(const char *name, int32 index, uint64 *value) const; status_t FindBool(const char *name, bool *value) const; status_t FindBool(const char *name, int32 index, bool *value) const; status_t FindFloat(const char *name, float *value) const; @@ -176,12 +188,20 @@ class BMessage { status_t ReplaceString(const char *name, int32 index, const BString &aString); status_t ReplaceInt8(const char *name, int8 value); status_t ReplaceInt8(const char *name, int32 index, int8 value); + status_t ReplaceUInt8(const char *name, uint8 value); + status_t ReplaceUInt8(const char *name, int32 index, uint8 value); status_t ReplaceInt16(const char *name, int16 value); status_t ReplaceInt16(const char *name, int32 index, int16 value); + status_t ReplaceUInt16(const char *name, uint16 value); + status_t ReplaceUInt16(const char *name, int32 index, uint16 value); status_t ReplaceInt32(const char *name, int32 value); status_t ReplaceInt32(const char *name, int32 index, int32 value); + status_t ReplaceUInt32(const char *name, uint32 value); + status_t ReplaceUInt32(const char *name, int32 index, uint32 value); status_t ReplaceInt64(const char *name, int64 value); status_t ReplaceInt64(const char *name, int32 index, int64 value); + status_t ReplaceUInt64(const char *name, uint64 value); + status_t ReplaceUInt64(const char *name, int32 index, uint64 value); status_t ReplaceBool(const char *name, bool aBoolean); status_t ReplaceBool(const char *name, int32 index, bool aBoolean); status_t ReplaceFloat(const char *name, float aFloat); @@ -203,6 +223,10 @@ class BMessage { status_t ReplaceData(const char *name, type_code type, int32 index, const void *data, ssize_t numBytes); + // Comparing data - Haiku experimental API + bool HasSameData(const BMessage &other, + bool ignoreFieldOrder = true, bool deep = false) const; + void *operator new(size_t size); void *operator new(size_t, void *pointer); void operator delete(void *pointer, size_t size); @@ -212,9 +236,13 @@ class BMessage { bool HasPoint(const char *, int32 n = 0) const; bool HasString(const char *, int32 n = 0) const; bool HasInt8(const char *, int32 n = 0) const; + bool HasUInt8(const char *, int32 n = 0) const; bool HasInt16(const char *, int32 n = 0) const; + bool HasUInt16(const char *, int32 n = 0) const; bool HasInt32(const char *, int32 n = 0) const; + bool HasUInt32(const char *, int32 n = 0) const; bool HasInt64(const char *, int32 n = 0) const; + bool HasUInt64(const char *, int32 n = 0) const; bool HasBool(const char *, int32 n = 0) const; bool HasFloat(const char *, int32 n = 0) const; bool HasDouble(const char *, int32 n = 0) const; @@ -244,11 +272,13 @@ class BMessage { friend class Private; friend class BMessageQueue; - status_t _InitCommon(); + status_t _InitCommon(bool initHeader); status_t _InitHeader(); status_t _Clear(); - status_t _ResizeData(int32 offset, int32 change); + status_t _ValidateMessage(); + + status_t _ResizeData(uint32 offset, int32 change); uint32 _HashName(const char* name) const; status_t _FindField(const char* name, type_code type, @@ -257,26 +287,29 @@ class BMessage { bool isFixedSize, field_header** _result); status_t _RemoveField(field_header* field); - ssize_t _NativeFlattenedSize() const; - status_t _NativeFlatten(char *buffer, ssize_t size) const; - status_t _NativeFlatten(BDataIO *stream, ssize_t *size = NULL) const; void _PrintToStream(const char* indent) const; private: message_header* fHeader; field_header* fFields; uint8* fData; - area_id fClonedArea; + + uint32 fFieldsAvailable; + size_t fDataAvailable; mutable BMessage* fOriginal; BMessage* fQueueLink; // fQueueLink is used by BMessageQueue to build a linked list + uint32 fReserved[9]; + // deprecated BMessage(BMessage *message); - static void _StaticCacheCleanup(); + virtual void _ReservedMessage1(); + virtual void _ReservedMessage2(); + virtual void _ReservedMessage3(); static BBlockCache* sMsgCache; }; diff --git a/headers/build/os/app/Messenger.h b/headers/build/os/app/Messenger.h index 2c63ab48ad..73c592616d 100644 --- a/headers/build/os/app/Messenger.h +++ b/headers/build/os/app/Messenger.h @@ -1,54 +1,24 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Messenger.h -// Author: Ingo Weinhold (bonefish@users.sf.net) -// Description: BMessenger delivers messages to local or remote targets. -//------------------------------------------------------------------------------ - +/* + * Copyright 2001-2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ingo Weinhold (bonefish@users.sf.net) + */ #ifndef _MESSENGER_H #define _MESSENGER_H -// Standard Includes ----------------------------------------------------------- -// System Includes ------------------------------------------------------------- -#include #include #include #include -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - class BHandler; class BLooper; -// BMessenger class ------------------------------------------------------------ + class BMessenger { -public: +public: BMessenger(); BMessenger(const BMessenger &from); ~BMessenger(); @@ -67,22 +37,18 @@ public: private: friend class Private; - - void SetTo(team_id team, port_id port, int32 token, bool preferred); + + void _SetTo(team_id team, port_id port, int32 token); private: port_id fPort; int32 fHandlerToken; team_id fTeam; - int32 extra0; - int32 extra1; - bool fPreferredTarget; - bool extra2; - bool extra3; - bool extra4; + + int32 _reserved[3]; }; -_IMPEXP_BE bool operator<(const BMessenger &a, const BMessenger &b); -_IMPEXP_BE bool operator!=(const BMessenger &a, const BMessenger &b); +bool operator<(const BMessenger &a, const BMessenger &b); +bool operator!=(const BMessenger &a, const BMessenger &b); #endif // _MESSENGER_H diff --git a/headers/build/private/app/MessagePrivate.h b/headers/build/private/app/MessagePrivate.h index bafba3af2d..7fe1227728 100644 --- a/headers/build/private/app/MessagePrivate.h +++ b/headers/build/private/app/MessagePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007, Haiku Inc. All rights reserved. + * Copyright 2005-2009, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -9,13 +9,14 @@ #define _MESSAGE_PRIVATE_H_ #include +#include +#include #include -#define MESSAGE_BODY_HASH_TABLE_SIZE 10 +#define MESSAGE_BODY_HASH_TABLE_SIZE 5 #define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10 #define MAX_FIELD_PREALLOCATION 50 -#define MAX_ITEM_PREALLOCATION B_PAGE_SIZE static const int32 kPortMessageCode = 'pjpp'; @@ -28,8 +29,8 @@ enum { MESSAGE_FLAG_IS_REPLY = 0x0008, MESSAGE_FLAG_WAS_DELIVERED = 0x0010, MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020, - MESSAGE_FLAG_WAS_DROPPED = 0x0080, - MESSAGE_FLAG_PASS_BY_AREA = 0x0100 + MESSAGE_FLAG_WAS_DROPPED = 0x0040, + MESSAGE_FLAG_PASS_BY_AREA = 0x0080 }; @@ -40,15 +41,14 @@ enum { struct BMessage::field_header { - uint32 flags; + uint16 flags; + uint16 name_length; type_code type; - int32 name_length; - int32 count; - ssize_t data_size; - ssize_t allocated; - int32 offset; + uint32 count; + uint32 data_size; + uint32 offset; int32 next_field; -}; +} _PACKED; struct BMessage::message_header { @@ -56,17 +56,9 @@ struct BMessage::message_header { uint32 what; uint32 flags; - ssize_t fields_size; - ssize_t data_size; - ssize_t fields_available; - ssize_t data_available; - - uint32 fields_checksum; - uint32 data_checksum; - int32 target; int32 current_specifier; - area_id shared_area; + area_id message_area; // reply info port_id reply_port; @@ -74,8 +66,9 @@ struct BMessage::message_header { team_id reply_team; // body info - int32 field_count; - int32 hash_table_size; + uint32 data_size; + uint32 field_count; + uint32 hash_table_size; int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE]; /* The hash table does contain indexes into the field list and @@ -84,18 +77,20 @@ struct BMessage::message_header { The hash table must be reevaluated when we remove a field though. */ -}; +} _PACKED; class BMessage::Private { public: Private(BMessage *msg) - : fMessage(msg) + : + fMessage(msg) { } Private(BMessage &msg) - : fMessage(&msg) + : + fMessage(&msg) { } @@ -105,6 +100,23 @@ class BMessage::Private { fMessage->fHeader->target = token; } + void + SetReply(BMessenger messenger) + { + BMessenger::Private messengerPrivate(messenger); + fMessage->fHeader->reply_port = messengerPrivate.Port(); + fMessage->fHeader->reply_target = messengerPrivate.Token(); + fMessage->fHeader->reply_team = messengerPrivate.Team(); + } + + void + SetReply(team_id team, port_id port, int32 target) + { + fMessage->fHeader->reply_port = port; + fMessage->fHeader->reply_target = target; + fMessage->fHeader->reply_team = team; + } + int32 GetTarget() { @@ -156,32 +168,6 @@ class BMessage::Private { return fMessage->fData; } - ssize_t - NativeFlattenedSize() const - { - return fMessage->_NativeFlattenedSize(); - } - - status_t - NativeFlatten(char *buffer, ssize_t size) const - { - return fMessage->_NativeFlatten(buffer, size); - } - - status_t - NativeFlatten(BDataIO *stream, ssize_t *size) const - { - return fMessage->_NativeFlatten(stream, size); - } - - // static methods - - static void - StaticCacheCleanup() - { - BMessage::_StaticCacheCleanup(); - } - private: BMessage* fMessage; }; diff --git a/headers/build/private/app/MessengerPrivate.h b/headers/build/private/app/MessengerPrivate.h index 1f8ec386f8..abb5f5332c 100644 --- a/headers/build/private/app/MessengerPrivate.h +++ b/headers/build/private/app/MessengerPrivate.h @@ -1,25 +1,31 @@ +/* + * Copyright 2003-2005, Haiku. + * Distributed under the terms of the MIT License. + */ #ifndef MESSENGER_PRIVATE_H #define MESSENGER_PRIVATE_H -#include -class BMessenger::Private -{ +#include +#include + + +class BMessenger::Private { public: - Private(BMessenger* msnger) : fMessenger(msnger) {;} - Private(BMessenger& msnger) : fMessenger(&msnger) {;} + Private(BMessenger* messenger) : fMessenger(messenger) {} + Private(BMessenger& messenger) : fMessenger(&messenger) {} port_id Port() { return fMessenger->fPort; } - int32 Token() + int32 Token() { return fMessenger->fHandlerToken; } team_id Team() { return fMessenger->fTeam; } - bool IsPreferredTarget() - { return fMessenger->fPreferredTarget; } + bool IsPreferredTarget() + { return fMessenger->fHandlerToken == B_PREFERRED_TOKEN; } - void SetTo(team_id team, port_id port, int32 token, bool preferred) - { fMessenger->SetTo(team, port, token, preferred); } + void SetTo(team_id team, port_id port, int32 token) + { fMessenger->_SetTo(team, port, token); } private: BMessenger* fMessenger; diff --git a/src/build/libbe/app/Jamfile b/src/build/libbe/app/Jamfile deleted file mode 100644 index c582c2b85e..0000000000 --- a/src/build/libbe/app/Jamfile +++ /dev/null @@ -1,17 +0,0 @@ -SubDir HAIKU_TOP src build libbe app ; - -UseHeaders [ FDirName $(HAIKU_TOP) headers build private app ] : true ; -UseHeaders [ FDirName $(HAIKU_TOP) headers build private shared ] : true ; - -USES_BE_API on app_kit.o = true ; - -BuildPlatformMergeObjectPIC app_kit.o : - Application.cpp - AppMisc.cpp - Message.cpp - MessageAdapter.cpp - Messenger.cpp - MessageUtils.cpp - TypeConstants.cpp -; - diff --git a/src/build/libbe/app/Message.cpp b/src/build/libbe/app/Message.cpp index e3d0c8deb2..c5de753763 100644 --- a/src/build/libbe/app/Message.cpp +++ b/src/build/libbe/app/Message.cpp @@ -1,20 +1,22 @@ /* - * Copyright 2005-2008, Haiku Inc. All rights reserved. + * Copyright 2005-2009, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Michael Lotz */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include #include +#include #include #include #include @@ -24,50 +26,107 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + +#include "tracing_config.h" + // kernel tracing configuration + +//#define VERBOSE_DEBUG_OUTPUT +#ifdef VERBOSE_DEBUG_OUTPUT +#define DEBUG_FUNCTION_ENTER \ + debug_printf("msg thread: %ld; this: %p; header: %p; fields: %p;" \ + " data: %p; what: 0x%08lx '%.4s'; line: %d; func: %s\n", \ + find_thread(NULL), this, fHeader, fFields, fData, what, (char *)&what, \ + __LINE__, __PRETTY_FUNCTION__); + +#define DEBUG_FUNCTION_ENTER2 \ + debug_printf("msg thread: %ld; line: %d: func: %s\n", find_thread(NULL), \ + __LINE__, __PRETTY_FUNCTION__); +#else +#define DEBUG_FUNCTION_ENTER /* nothing */ +#define DEBUG_FUNCTION_ENTER2 /* nothing */ +#endif + +#if BMESSAGE_TRACING +# define KTRACE(format...) ktrace_printf(format) +#else +# define KTRACE(format...) +#endif const char *B_SPECIFIER_ENTRY = "specifiers"; const char *B_PROPERTY_ENTRY = "property"; const char *B_PROPERTY_NAME_ENTRY = "name"; +extern "C" { + // private os function to set the owning team of an area + status_t _kern_transfer_area(area_id area, void **_address, + uint32 addressSpec, team_id target); +} + BBlockCache *BMessage::sMsgCache = NULL; +template +static void +print_to_stream_type(uint8 *pointer) +{ + Type *item = (Type *)pointer; + item->PrintToStream(); +} + + +template +static void +print_type(const char *format, uint8 *pointer) +{ + Type *item = (Type *)pointer; + printf(format, *item, *item); +} + + +// #pragma mark - + + BMessage::BMessage() { - _InitCommon(); + DEBUG_FUNCTION_ENTER; + _InitCommon(true); } BMessage::BMessage(BMessage *other) { - _InitCommon(); + DEBUG_FUNCTION_ENTER; + _InitCommon(false); *this = *other; } BMessage::BMessage(uint32 _what) { - _InitCommon(); + DEBUG_FUNCTION_ENTER; + _InitCommon(true); fHeader->what = what = _what; } BMessage::BMessage(const BMessage &other) { - _InitCommon(); + DEBUG_FUNCTION_ENTER; + _InitCommon(false); *this = other; } BMessage::~BMessage() { + DEBUG_FUNCTION_ENTER; _Clear(); } @@ -75,32 +134,50 @@ BMessage::~BMessage() BMessage & BMessage::operator=(const BMessage &other) { + DEBUG_FUNCTION_ENTER; + + if (this == &other) + return *this; + _Clear(); fHeader = (message_header *)malloc(sizeof(message_header)); + if (fHeader == NULL) + return *this; + memcpy(fHeader, other.fHeader, sizeof(message_header)); // Clear some header flags inherited from the original message that don't // apply to the clone. fHeader->flags &= ~(MESSAGE_FLAG_REPLY_REQUIRED | MESSAGE_FLAG_REPLY_DONE | MESSAGE_FLAG_IS_REPLY | MESSAGE_FLAG_WAS_DELIVERED - | MESSAGE_FLAG_WAS_DROPPED | MESSAGE_FLAG_PASS_BY_AREA); + | MESSAGE_FLAG_PASS_BY_AREA); // Note, that BeOS R5 seems to keep the reply info. - if (fHeader->fields_size > 0) { - fFields = (field_header *)malloc(fHeader->fields_size); - memcpy(fFields, other.fFields, fHeader->fields_size); + if (fHeader->field_count > 0) { + size_t fieldsSize = fHeader->field_count * sizeof(field_header); + fFields = (field_header *)malloc(fieldsSize); + if (fFields == NULL) { + fHeader->field_count = 0; + fHeader->data_size = 0; + } else + memcpy(fFields, other.fFields, fieldsSize); } if (fHeader->data_size > 0) { fData = (uint8 *)malloc(fHeader->data_size); - memcpy(fData, other.fData, fHeader->data_size); + if (fData == NULL) { + fHeader->field_count = 0; + free(fFields); + fFields = NULL; + } else + memcpy(fData, other.fData, fHeader->data_size); } - fHeader->shared_area = -1; - fHeader->fields_available = 0; - fHeader->data_available = 0; fHeader->what = what = other.what; + fHeader->message_area = -1; + fFieldsAvailable = 0; + fDataAvailable = 0; return *this; } @@ -109,16 +186,18 @@ BMessage::operator=(const BMessage &other) void * BMessage::operator new(size_t size) { + DEBUG_FUNCTION_ENTER2; if (!sMsgCache) sMsgCache = new BBlockCache(10, sizeof(BMessage), B_OBJECT_CACHE); - - return sMsgCache->Get(size); + void *pointer = sMsgCache->Get(size); + return pointer; } void * BMessage::operator new(size_t, void *pointer) { + DEBUG_FUNCTION_ENTER2; return pointer; } @@ -126,37 +205,111 @@ BMessage::operator new(size_t, void *pointer) void BMessage::operator delete(void *pointer, size_t size) { + DEBUG_FUNCTION_ENTER2; sMsgCache->Save(pointer, size); } -status_t -BMessage::_InitCommon() +bool +BMessage::HasSameData(const BMessage &other, bool ignoreFieldOrder, + bool deep) const { + if (this == &other) + return true; + + if (fHeader->field_count != other.fHeader->field_count) + return false; + + for (uint32 i = 0; i < fHeader->field_count; i++) { + field_header *field = &fFields[i]; + field_header *otherField = NULL; + + const char *name = (const char *)fData + field->offset; + if (ignoreFieldOrder) { + if (other._FindField(name, B_ANY_TYPE, &otherField) != B_OK) + return false; + } else { + otherField = &other.fFields[i]; + if (otherField->name_length != field->name_length) + return false; + + const char *otherName = (const char *)other.fData + + otherField->offset; + if (strncmp(name, otherName, field->name_length) != 0) + return false; + } + + if (otherField->type != field->type || otherField->count != field->count) + return false; + + uint8 *data = fData + field->offset + field->name_length; + uint8 *otherData = other.fData + otherField->offset + + otherField->name_length; + + bool needsMemCompare = true; + if (deep && field->type == B_MESSAGE_TYPE) { + BMessage message, otherMessage; + if (message.Unflatten((const char *)data) == B_OK + && otherMessage.Unflatten((const char *)otherData) == B_OK) { + if (!message.HasSameData(ignoreFieldOrder, deep)) + return false; + needsMemCompare = false; + } + } + + if (needsMemCompare) { + if (otherField->data_size != field->data_size) + return false; + if (memcmp(data, otherData, field->data_size) != 0) + return false; + } + } + + return true; +} + + +status_t +BMessage::_InitCommon(bool initHeader) +{ + DEBUG_FUNCTION_ENTER; what = 0; fHeader = NULL; fFields = NULL; fData = NULL; + fFieldsAvailable = 0; + fDataAvailable = 0; + fOriginal = NULL; fQueueLink = NULL; - return _InitHeader(); + if (initHeader) + return _InitHeader(); + + fHeader = NULL; + return B_OK; } status_t BMessage::_InitHeader() { - fHeader = (message_header *)malloc(sizeof(message_header)); + DEBUG_FUNCTION_ENTER; + if (fHeader == NULL) { + fHeader = (message_header *)malloc(sizeof(message_header)); + if (fHeader == NULL) + return B_NO_MEMORY; + } + memset(fHeader, 0, sizeof(message_header) - sizeof(fHeader->hash_table)); fHeader->format = MESSAGE_FORMAT_HAIKU; fHeader->flags = MESSAGE_FLAG_VALID; fHeader->what = what; fHeader->current_specifier = -1; - fHeader->shared_area = -1; + fHeader->message_area = -1; fHeader->target = B_NULL_TOKEN; fHeader->reply_target = B_NULL_TOKEN; @@ -173,13 +326,20 @@ BMessage::_InitHeader() status_t BMessage::_Clear() { - free(fHeader); - fHeader = NULL; + DEBUG_FUNCTION_ENTER; + if (fHeader != NULL) { + free(fHeader); + fHeader = NULL; + } + free(fFields); fFields = NULL; free(fData); fData = NULL; + fFieldsAvailable = 0; + fDataAvailable = 0; + delete fOriginal; fOriginal = NULL; @@ -191,10 +351,11 @@ status_t BMessage::GetInfo(type_code typeRequested, int32 index, char **nameFound, type_code *typeFound, int32 *countFound) const { - if (typeRequested == B_ANY_TYPE) { - if (index >= fHeader->field_count) - return B_BAD_INDEX; + DEBUG_FUNCTION_ENTER; + if (index < 0 || (uint32)index >= fHeader->field_count) + return B_BAD_INDEX; + if (typeRequested == B_ANY_TYPE) { if (nameFound) *nameFound = (char *)fData + fFields[index].offset; if (typeFound) @@ -206,7 +367,7 @@ BMessage::GetInfo(type_code typeRequested, int32 index, char **nameFound, int32 counter = -1; field_header *field = fFields; - for (int32 i = 0; i < fHeader->field_count; i++, field++) { + for (uint32 i = 0; i < fHeader->field_count; i++, field++) { if (field->type == typeRequested) counter++; @@ -232,12 +393,13 @@ status_t BMessage::GetInfo(const char *name, type_code *typeFound, int32 *countFound) const { + DEBUG_FUNCTION_ENTER; if (countFound) *countFound = 0; field_header *field = NULL; status_t result = _FindField(name, B_ANY_TYPE, &field); - if (result < B_OK || !field) + if (result < B_OK || field == NULL) return result; if (typeFound) @@ -253,15 +415,16 @@ status_t BMessage::GetInfo(const char *name, type_code *typeFound, bool *fixedSize) const { + DEBUG_FUNCTION_ENTER; field_header *field = NULL; status_t result = _FindField(name, B_ANY_TYPE, &field); - if (result < B_OK || !field) + if (result < B_OK || field == NULL) return result; if (typeFound) *typeFound = field->type; if (fixedSize) - *fixedSize = field->flags & FIELD_FLAG_FIXED_SIZE; + *fixedSize = (field->flags & FIELD_FLAG_FIXED_SIZE) != 0; return B_OK; } @@ -270,12 +433,13 @@ BMessage::GetInfo(const char *name, type_code *typeFound, bool *fixedSize) int32 BMessage::CountNames(type_code type) const { + DEBUG_FUNCTION_ENTER; if (type == B_ANY_TYPE) return fHeader->field_count; int32 count = 0; field_header *field = fFields; - for (int32 i = 0; i < fHeader->field_count; i++, field++) { + for (uint32 i = 0; i < fHeader->field_count; i++, field++) { if (field->type == type) count++; } @@ -287,6 +451,7 @@ BMessage::CountNames(type_code type) const bool BMessage::IsEmpty() const { + DEBUG_FUNCTION_ENTER; return fHeader->field_count == 0; } @@ -294,6 +459,7 @@ BMessage::IsEmpty() const bool BMessage::IsSystem() const { + DEBUG_FUNCTION_ENTER; char a = char(what >> 24); char b = char(what >> 16); char c = char(what >> 8); @@ -315,25 +481,8 @@ BMessage::IsSystem() const bool BMessage::IsReply() const { - return fHeader->flags & MESSAGE_FLAG_IS_REPLY; -} - - -template static uint8 * -print_to_stream_type(uint8* pointer) -{ - Type *item = (Type *)pointer; - item->PrintToStream(); - return (uint8 *)(item+1); -} - - -template static uint8 * -print_type(const char* format, uint8* pointer) -{ - Type *item = (Type *)pointer; - printf(format, *item, *item); - return (uint8 *)(item+1); + DEBUG_FUNCTION_ENTER; + return (fHeader->flags & MESSAGE_FLAG_IS_REPLY) != 0; } @@ -348,91 +497,112 @@ BMessage::PrintToStream() const void BMessage::_PrintToStream(const char* indent) const { + DEBUG_FUNCTION_ENTER; + int32 value = B_BENDIAN_TO_HOST_INT32(what); printf("BMessage("); - if (isprint(*(char *)&value)) { + if (isprint(*(char *)&value)) printf("'%.4s'", (char *)&value); - } else - printf("0x%" B_PRIx32, what); + else + printf("0x%lx", what); printf(") {\n"); + if (fHeader == NULL || fFields == NULL || fData == NULL) + return; + field_header *field = fFields; - for (int32 i = 0; i < fHeader->field_count; i++, field++) { + for (uint32 i = 0; i < fHeader->field_count; i++, field++) { value = B_BENDIAN_TO_HOST_INT32(field->type); ssize_t size = 0; - if ((field->flags & FIELD_FLAG_FIXED_SIZE) && field->count > 0) + if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0 && field->count > 0) size = field->data_size / field->count; uint8 *pointer = fData + field->offset + field->name_length; - for (int32 j = 0; j < field->count; j++) { + for (uint32 j = 0; j < field->count; j++) { if (field->count == 1) { printf("%s %s = ", indent, (char *)(fData + field->offset)); } else { - printf("%s %s[%" B_PRId32 "] = ", indent, + printf("%s %s[%ld] = ", indent, (char *)(fData + field->offset), j); } switch (field->type) { case B_RECT_TYPE: - pointer = print_to_stream_type(pointer); + print_to_stream_type(pointer); break; case B_POINT_TYPE: - pointer = print_to_stream_type(pointer); + print_to_stream_type(pointer); break; - case B_STRING_TYPE: { - ssize_t size = *(ssize_t *)pointer; - pointer += sizeof(ssize_t); + case B_STRING_TYPE: + { + size = *(uint32 *)pointer; + pointer += sizeof(uint32); printf("string(\"%s\", %ld bytes)\n", (char *)pointer, - (long)size); - pointer += size; + size); break; } case B_INT8_TYPE: - pointer = print_type("int8(0x%hx or %d or \'%.1s\')\n", pointer); + print_type("int8(0x%hx or %d or '%.1s')\n", pointer); + break; + + case B_UINT8_TYPE: + print_type("uint8(0x%hx or %u or '%.1s')\n", + pointer); break; case B_INT16_TYPE: - pointer = print_type("int16 (0x%x or %d)\n", pointer); + print_type("int16(0x%x or %d)\n", pointer); + break; + + case B_UINT16_TYPE: + print_type("uint16(0x%x or %u\n", pointer); break; case B_INT32_TYPE: - pointer = print_type("int32(0x%lx or %ld)\n", pointer); + print_type("int32(0x%lx or %ld)\n", pointer); + break; + + case B_UINT32_TYPE: + print_type("uint32(0x%lx or %lu\n", pointer); break; case B_INT64_TYPE: - pointer = print_type("int64(0x%Lx or %Ld)\n", pointer); + print_type("int64(0x%Lx or %Ld)\n", pointer); + break; + + case B_UINT64_TYPE: + print_type("uint64(0x%Lx or %Ld\n", pointer); break; case B_BOOL_TYPE: - printf("bool(%s)\n", *((bool *)pointer)!= 0 ? "true" : "false"); - pointer += sizeof(bool); + printf("bool(%s)\n", *((bool *)pointer) != 0 + ? "true" : "false"); break; case B_FLOAT_TYPE: - pointer = print_type("float(%.4f)\n", pointer); + print_type("float(%.4f)\n", pointer); break; case B_DOUBLE_TYPE: - pointer = print_type("double(%.8f)\n", pointer); + print_type("double(%.8f)\n", pointer); break; - case B_REF_TYPE: { - ssize_t size = *(ssize_t *)pointer; - pointer += sizeof(ssize_t); + case B_REF_TYPE: + { + size = *(uint32 *)pointer; + pointer += sizeof(uint32); entry_ref ref; BPrivate::entry_ref_unflatten(&ref, (char *)pointer, size); - printf("entry_ref(device=%ld, directory=%" B_PRIdINO - ", name=\"%s\", ", (long)ref.device, ref.directory, - ref.name); + printf("entry_ref(device=%ld, directory=%lld, " + "name=\"%s\", ", ref.device, ref.directory, ref.name); BPath path(&ref); printf("path=\"%s\")\n", path.Path()); - pointer += size; break; } @@ -442,24 +612,28 @@ BMessage::_PrintToStream(const char* indent) const sprintf(buffer, "%s ", indent); BMessage message; - const ssize_t size = *(const ssize_t *)pointer; - pointer += sizeof(ssize_t); - if (message.Unflatten((const char *)pointer) != B_OK) { - fprintf(stderr, "couldn't unflatten item %" B_PRId32 - "\n", i); + size = *(uint32 *)pointer; + pointer += sizeof(uint32); + status_t result = message.Unflatten((const char *)pointer); + if (result != B_OK) { + printf("failed unflatten: %s\n", strerror(result)); break; } + message._PrintToStream(buffer); printf("%s }\n", indent); - pointer += size; break; } default: + { printf("(type = '%.4s')(size = %ld)\n", (char *)&value, - (long)size); + size); break; + } } + + pointer += size; } } } @@ -468,7 +642,8 @@ BMessage::_PrintToStream(const char* indent) const status_t BMessage::Rename(const char *oldEntry, const char *newEntry) { - if (!oldEntry || !newEntry) + DEBUG_FUNCTION_ENTER; + if (oldEntry == NULL || newEntry == NULL) return B_BAD_VALUE; uint32 hash = _HashName(oldEntry) % fHeader->hash_table_size; @@ -511,21 +686,31 @@ BMessage::Rename(const char *oldEntry, const char *newEntry) bool BMessage::WasDelivered() const { - return fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED; + DEBUG_FUNCTION_ENTER; + return (fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED) != 0; } bool BMessage::IsSourceWaiting() const { - return (fHeader->flags & MESSAGE_FLAG_REPLY_REQUIRED) - && !(fHeader->flags & MESSAGE_FLAG_REPLY_DONE); + DEBUG_FUNCTION_ENTER; + return (fHeader->flags & MESSAGE_FLAG_REPLY_REQUIRED) != 0 + && (fHeader->flags & MESSAGE_FLAG_REPLY_DONE) == 0; } BMessenger BMessage::ReturnAddress() const { + DEBUG_FUNCTION_ENTER; + if ((fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED) != 0) { + BMessenger messenger; + BMessenger::Private(messenger).SetTo(fHeader->reply_team, + fHeader->reply_port, fHeader->reply_target); + return messenger; + } + return BMessenger(); } @@ -533,8 +718,9 @@ BMessage::ReturnAddress() const const BMessage * BMessage::Previous() const { + DEBUG_FUNCTION_ENTER; /* ToDo: test if the "_previous_" field is used in R5 */ - if (!fOriginal) { + if (fOriginal == NULL) { fOriginal = new BMessage(); if (FindMessage("_previous_", fOriginal) != B_OK) { @@ -550,13 +736,15 @@ BMessage::Previous() const bool BMessage::WasDropped() const { - return fHeader->flags & MESSAGE_FLAG_WAS_DROPPED; + DEBUG_FUNCTION_ENTER; + return (fHeader->flags & MESSAGE_FLAG_WAS_DROPPED) != 0; } BPoint BMessage::DropPoint(BPoint *offset) const { + DEBUG_FUNCTION_ENTER; if (offset) *offset = FindPoint("_drop_offset_"); @@ -567,40 +755,20 @@ BMessage::DropPoint(BPoint *offset) const ssize_t BMessage::FlattenedSize() const { - return BPrivate::MessageAdapter::FlattenedSize(MESSAGE_FORMAT_R5, this); + DEBUG_FUNCTION_ENTER; + return sizeof(message_header) + fHeader->field_count * sizeof(field_header) + + fHeader->data_size; } status_t BMessage::Flatten(char *buffer, ssize_t size) const { - return BPrivate::MessageAdapter::Flatten(MESSAGE_FORMAT_R5, this, buffer, - &size); -} - - -status_t -BMessage::Flatten(BDataIO *stream, ssize_t *size) const -{ - return BPrivate::MessageAdapter::Flatten(MESSAGE_FORMAT_R5, this, stream, - size); -} - - -ssize_t -BMessage::_NativeFlattenedSize() const -{ - return sizeof(message_header) + fHeader->fields_size + fHeader->data_size; -} - - -status_t -BMessage::_NativeFlatten(char *buffer, ssize_t size) const -{ - if (!buffer) + DEBUG_FUNCTION_ENTER; + if (buffer == NULL || size < 0) return B_BAD_VALUE; - if (!fHeader) + if (fHeader == NULL) return B_NO_INIT; /* we have to sync the what code as it is a public member */ @@ -610,25 +778,27 @@ BMessage::_NativeFlatten(char *buffer, ssize_t size) const buffer += sizeof(message_header); size -= sizeof(message_header); - memcpy(buffer, fFields, min_c(fHeader->fields_size, size)); - buffer += fHeader->fields_size; - size -= fHeader->fields_size; + size_t fieldsSize = fHeader->field_count * sizeof(field_header); + memcpy(buffer, fFields, min_c(fieldsSize, (size_t)size)); + buffer += fieldsSize; + size -= fieldsSize; - memcpy(buffer, fData, min_c(fHeader->data_size, size)); - if (size >= fHeader->data_size) - return B_OK; + memcpy(buffer, fData, min_c(fHeader->data_size, (size_t)size)); + if ((size_t)size < fHeader->data_size) + return B_BUFFER_OVERFLOW; - return B_NO_MEMORY; + return B_OK; } status_t -BMessage::_NativeFlatten(BDataIO *stream, ssize_t *size) const +BMessage::Flatten(BDataIO *stream, ssize_t *size) const { - if (!stream) + DEBUG_FUNCTION_ENTER; + if (stream == NULL) return B_BAD_VALUE; - if (!fHeader) + if (fHeader == NULL) return B_NO_INIT; /* we have to sync the what code as it is a public member */ @@ -636,20 +806,21 @@ BMessage::_NativeFlatten(BDataIO *stream, ssize_t *size) const ssize_t result1 = stream->Write(fHeader, sizeof(message_header)); if (result1 != sizeof(message_header)) - return (result1 >= 0 ? B_ERROR : result1); + return result1 < 0 ? result1 : B_ERROR; ssize_t result2 = 0; - if (fHeader->fields_size > 0) { - result2 = stream->Write(fFields, fHeader->fields_size); - if (result2 != fHeader->fields_size) - return (result2 >= 0 ? B_ERROR : result2); + if (fHeader->field_count > 0) { + ssize_t fieldsSize = fHeader->field_count * sizeof(field_header); + result2 = stream->Write(fFields, fieldsSize); + if (result2 != fieldsSize) + return result2 < 0 ? result2 : B_ERROR; } ssize_t result3 = 0; if (fHeader->data_size > 0) { result3 = stream->Write(fData, fHeader->data_size); - if (result3 != fHeader->data_size) - return (result3 >= 0 ? B_ERROR : result3); + if (result3 != (ssize_t)fHeader->data_size) + return result3 < 0 ? result3 : B_ERROR; } if (size) @@ -659,10 +830,36 @@ BMessage::_NativeFlatten(BDataIO *stream, ssize_t *size) const } +status_t +BMessage::_ValidateMessage() +{ + if (fHeader->field_count == 0) + return B_OK; + + if (fFields == NULL) + return B_NO_INIT; + + for (uint32 i = 0; i < fHeader->field_count; i++) { + field_header *field = &fFields[i]; + if ((field->next_field >= 0 + && (uint32)field->next_field > fHeader->field_count) + || (field->offset + field->name_length + field->data_size + > fHeader->data_size)) { + // the message is corrupt + MakeEmpty(); + return B_BAD_VALUE; + } + } + + return B_OK; +} + + status_t BMessage::Unflatten(const char *flatBuffer) { - if (!flatBuffer) + DEBUG_FUNCTION_ENTER; + if (flatBuffer == NULL) return B_BAD_VALUE; uint32 format = *(uint32 *)flatBuffer; @@ -674,51 +871,62 @@ BMessage::Unflatten(const char *flatBuffer) _Clear(); fHeader = (message_header *)malloc(sizeof(message_header)); - if (!fHeader) + if (fHeader == NULL) return B_NO_MEMORY; memcpy(fHeader, flatBuffer, sizeof(message_header)); flatBuffer += sizeof(message_header); if (fHeader->format != MESSAGE_FORMAT_HAIKU - || !(fHeader->flags & MESSAGE_FLAG_VALID)) { - free(fHeader); - fHeader = NULL; + || (fHeader->flags & MESSAGE_FLAG_VALID) == 0) { _InitHeader(); return B_BAD_VALUE; } - fHeader->fields_available = 0; - fHeader->data_available = 0; what = fHeader->what; - fHeader->shared_area = -1; + if ((fHeader->flags & MESSAGE_FLAG_PASS_BY_AREA) != 0 + && fHeader->message_area >= 0) { +// status_t result = _Reference(); +// if (result != B_OK) +// return result; + } else { + fHeader->message_area = -1; - if (fHeader->fields_size > 0) { - fFields = (field_header *)malloc(fHeader->fields_size); - if (!fFields) - return B_NO_MEMORY; + if (fHeader->field_count > 0) { + size_t fieldsSize = fHeader->field_count * sizeof(field_header); + fFields = (field_header *)malloc(fieldsSize); + if (fFields == NULL) { + _InitHeader(); + return B_NO_MEMORY; + } - memcpy(fFields, flatBuffer, fHeader->fields_size); - flatBuffer += fHeader->fields_size; + memcpy(fFields, flatBuffer, fieldsSize); + flatBuffer += fieldsSize; + } + + if (fHeader->data_size > 0) { + fData = (uint8 *)malloc(fHeader->data_size); + if (fData == NULL) { + free(fFields); + fFields = NULL; + _InitHeader(); + return B_NO_MEMORY; + } + + memcpy(fData, flatBuffer, fHeader->data_size); + } } - if (fHeader->data_size > 0) { - fData = (uint8 *)malloc(fHeader->data_size); - if (!fData) - return B_NO_MEMORY; - - memcpy(fData, flatBuffer, fHeader->data_size); - } - - return B_OK; + return _ValidateMessage(); } status_t BMessage::Unflatten(BDataIO *stream) { - if (!stream) + DEBUG_FUNCTION_ENTER; + if (stream == NULL) return B_BAD_VALUE; uint32 format = 0; @@ -731,57 +939,58 @@ BMessage::Unflatten(BDataIO *stream) _Clear(); fHeader = (message_header *)malloc(sizeof(message_header)); - if (!fHeader) + if (fHeader == NULL) return B_NO_MEMORY; fHeader->format = format; uint8 *header = (uint8 *)fHeader; ssize_t result = stream->Read(header + sizeof(uint32), sizeof(message_header) - sizeof(uint32)); - result -= sizeof(message_header) - sizeof(uint32); - - if (result != B_OK || fHeader->format != MESSAGE_FORMAT_HAIKU - || !(fHeader->flags & MESSAGE_FLAG_VALID)) { - free(fHeader); - fHeader = NULL; + if (result != sizeof(message_header) - sizeof(uint32) + || (fHeader->flags & MESSAGE_FLAG_VALID) == 0) { _InitHeader(); - return B_BAD_VALUE; + return result < 0 ? result : B_BAD_VALUE; } - fHeader->fields_available = 0; - fHeader->data_available = 0; what = fHeader->what; - fHeader->shared_area = -1; + fHeader->message_area = -1; - if (result == B_OK && fHeader->fields_size > 0) { - fFields = (field_header *)malloc(fHeader->fields_size); - if (!fFields) + if (fHeader->field_count > 0) { + ssize_t fieldsSize = fHeader->field_count * sizeof(field_header); + fFields = (field_header *)malloc(fieldsSize); + if (fFields == NULL) { + _InitHeader(); return B_NO_MEMORY; + } - result = stream->Read(fFields, fHeader->fields_size); - result -= fHeader->fields_size; + result = stream->Read(fFields, fieldsSize); + if (result != fieldsSize) + return result < 0 ? result : B_BAD_VALUE; } - if (result == B_OK && fHeader->data_size > 0) { + if (fHeader->data_size > 0) { fData = (uint8 *)malloc(fHeader->data_size); - if (!fData) + if (fData == NULL) { + free(fFields); + fFields = NULL; + _InitHeader(); return B_NO_MEMORY; + } result = stream->Read(fData, fHeader->data_size); - result -= fHeader->data_size; + if (result != (ssize_t)fHeader->data_size) + return result < 0 ? result : B_BAD_VALUE; } - if (result < B_OK) - return B_BAD_VALUE; - - return B_OK; + return _ValidateMessage(); } status_t BMessage::AddSpecifier(const char *property) { + DEBUG_FUNCTION_ENTER; BMessage message(B_DIRECT_SPECIFIER); status_t result = message.AddString(B_PROPERTY_ENTRY, property); if (result < B_OK) @@ -794,6 +1003,7 @@ BMessage::AddSpecifier(const char *property) status_t BMessage::AddSpecifier(const char *property, int32 index) { + DEBUG_FUNCTION_ENTER; BMessage message(B_INDEX_SPECIFIER); status_t result = message.AddString(B_PROPERTY_ENTRY, property); if (result < B_OK) @@ -810,6 +1020,7 @@ BMessage::AddSpecifier(const char *property, int32 index) status_t BMessage::AddSpecifier(const char *property, int32 index, int32 range) { + DEBUG_FUNCTION_ENTER; if (range < 0) return B_BAD_VALUE; @@ -833,6 +1044,7 @@ BMessage::AddSpecifier(const char *property, int32 index, int32 range) status_t BMessage::AddSpecifier(const char *property, const char *name) { + DEBUG_FUNCTION_ENTER; BMessage message(B_NAME_SPECIFIER); status_t result = message.AddString(B_PROPERTY_ENTRY, property); if (result < B_OK) @@ -849,6 +1061,7 @@ BMessage::AddSpecifier(const char *property, const char *name) status_t BMessage::AddSpecifier(const BMessage *specifier) { + DEBUG_FUNCTION_ENTER; status_t result = AddMessage(B_SPECIFIER_ENTRY, specifier); if (result < B_OK) return result; @@ -862,6 +1075,7 @@ BMessage::AddSpecifier(const BMessage *specifier) status_t BMessage::SetCurrentSpecifier(int32 index) { + DEBUG_FUNCTION_ENTER; if (index < 0) return B_BAD_INDEX; @@ -880,14 +1094,16 @@ BMessage::SetCurrentSpecifier(int32 index) status_t -BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *what, +BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *_what, const char **property) const { - if (index) + DEBUG_FUNCTION_ENTER; + + if (index != NULL) *index = fHeader->current_specifier; if (fHeader->current_specifier < 0 - || !(fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED)) + || (fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED) == 0) return B_BAD_SCRIPT_SYNTAX; if (specifier) { @@ -895,8 +1111,8 @@ BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *what, specifier) < B_OK) return B_BAD_SCRIPT_SYNTAX; - if (what) - *what = specifier->what; + if (_what != NULL) + *_what = specifier->what; if (property) { if (specifier->FindString(B_PROPERTY_ENTRY, property) < B_OK) @@ -911,15 +1127,17 @@ BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *what, bool BMessage::HasSpecifiers() const { - return fHeader->flags & MESSAGE_FLAG_HAS_SPECIFIERS; + DEBUG_FUNCTION_ENTER; + return (fHeader->flags & MESSAGE_FLAG_HAS_SPECIFIERS) != 0; } status_t BMessage::PopSpecifier() { + DEBUG_FUNCTION_ENTER; if (fHeader->current_specifier < 0 || - !(fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED)) + (fHeader->flags & MESSAGE_FLAG_WAS_DELIVERED) == 0) return B_BAD_VALUE; if (fHeader->current_specifier >= 0) @@ -930,7 +1148,7 @@ BMessage::PopSpecifier() status_t -BMessage::_ResizeData(int32 offset, int32 change) +BMessage::_ResizeData(uint32 offset, int32 change) { if (change == 0) return B_OK; @@ -938,30 +1156,30 @@ BMessage::_ResizeData(int32 offset, int32 change) /* optimize for the most usual case: appending data */ if (offset < fHeader->data_size) { field_header *field = fFields; - for (int32 i = 0; i < fHeader->field_count; i++, field++) { + for (uint32 i = 0; i < fHeader->field_count; i++, field++) { if (field->offset >= offset) field->offset += change; } } if (change > 0) { - if (fHeader->data_available >= change) { + if (fDataAvailable >= (uint32)change) { if (offset < fHeader->data_size) { memmove(fData + offset + change, fData + offset, fHeader->data_size - offset); } - fHeader->data_available -= change; + fDataAvailable -= change; fHeader->data_size += change; return B_OK; } - ssize_t size = fHeader->data_size * 2; + size_t size = fHeader->data_size * 2; size = min_c(size, fHeader->data_size + MAX_DATA_PREALLOCATION); size = max_c(size, fHeader->data_size + change); uint8 *newData = (uint8 *)realloc(fData, size); - if (size > 0 && !newData) + if (size > 0 && newData == NULL) return B_NO_MEMORY; fData = newData; @@ -971,26 +1189,27 @@ BMessage::_ResizeData(int32 offset, int32 change) } fHeader->data_size += change; - fHeader->data_available = size - fHeader->data_size; + fDataAvailable = size - fHeader->data_size; } else { ssize_t length = fHeader->data_size - offset + change; if (length > 0) memmove(fData + offset, fData + offset - change, length); + // change is negative fHeader->data_size += change; - fHeader->data_available -= change; + fDataAvailable -= change; - if (fHeader->data_available > MAX_DATA_PREALLOCATION) { + if (fDataAvailable > MAX_DATA_PREALLOCATION) { ssize_t available = MAX_DATA_PREALLOCATION / 2; ssize_t size = fHeader->data_size + available; uint8 *newData = (uint8 *)realloc(fData, size); - if (size > 0 && !newData) { + if (size > 0 && newData == NULL) { // this is strange, but not really fatal return B_OK; } fData = newData; - fHeader->data_available = available; + fDataAvailable = available; } } @@ -1017,10 +1236,10 @@ BMessage::_HashName(const char *name) const status_t BMessage::_FindField(const char *name, type_code type, field_header **result) const { - if (!name) + if (name == NULL) return B_BAD_VALUE; - if (!fHeader || !fFields || !fData) + if (fHeader == NULL || fFields == NULL || fData == NULL) return B_NAME_NOT_FOUND; uint32 hash = _HashName(name) % fHeader->hash_table_size; @@ -1028,6 +1247,8 @@ BMessage::_FindField(const char *name, type_code type, field_header **result) co while (nextField >= 0) { field_header *field = &fFields[nextField]; + if ((field->flags & FIELD_FLAG_VALID) == 0) + break; if (strncmp((const char *)(fData + field->offset), name, field->name_length) == 0) { @@ -1049,20 +1270,20 @@ status_t BMessage::_AddField(const char *name, type_code type, bool isFixedSize, field_header **result) { - if (!fHeader) + if (fHeader == NULL) return B_ERROR; - if (fHeader->fields_available <= 0) { - int32 count = fHeader->field_count * 2 + 1; + if (fFieldsAvailable <= 0) { + uint32 count = fHeader->field_count * 2 + 1; count = min_c(count, fHeader->field_count + MAX_FIELD_PREALLOCATION); field_header *newFields = (field_header *)realloc(fFields, count * sizeof(field_header)); - if (count > 0 && !newFields) + if (count > 0 && newFields == NULL) return B_NO_MEMORY; fFields = newFields; - fHeader->fields_available = count - fHeader->field_count; + fFieldsAvailable = count - fHeader->field_count; } uint32 hash = _HashName(name) % fHeader->hash_table_size; @@ -1075,7 +1296,6 @@ BMessage::_AddField(const char *name, type_code type, bool isFixedSize, field->type = type; field->count = 0; field->data_size = 0; - field->allocated = 0; field->next_field = -1; field->offset = fHeader->data_size; field->name_length = strlen(name) + 1; @@ -1088,8 +1308,7 @@ BMessage::_AddField(const char *name, type_code type, bool isFixedSize, if (isFixedSize) field->flags |= FIELD_FLAG_FIXED_SIZE; - fHeader->fields_available--; - fHeader->fields_size += sizeof(field_header); + fFieldsAvailable--; fHeader->field_count++; *result = field; return B_OK; @@ -1110,7 +1329,7 @@ BMessage::_RemoveField(field_header *field) nextField--; int32 *value = fHeader->hash_table; - for (int32 i = 0; i < fHeader->hash_table_size; i++, value++) { + for (uint32 i = 0; i < fHeader->hash_table_size; i++, value++) { if (*value > index) *value -= 1; else if (*value == index) @@ -1118,30 +1337,29 @@ BMessage::_RemoveField(field_header *field) } field_header *other = fFields; - for (int32 i = 0; i < fHeader->field_count; i++, other++) { + for (uint32 i = 0; i < fHeader->field_count; i++, other++) { if (other->next_field > index) other->next_field--; else if (other->next_field == index) other->next_field = nextField; } - ssize_t size = fHeader->fields_size - (index + 1) * sizeof(field_header); + size_t size = (fHeader->field_count - index - 1) * sizeof(field_header); memmove(fFields + index, fFields + index + 1, size); - fHeader->fields_size -= sizeof(field_header); fHeader->field_count--; - fHeader->fields_available++; + fFieldsAvailable++; - if (fHeader->fields_available > MAX_FIELD_PREALLOCATION) { + if (fFieldsAvailable > MAX_FIELD_PREALLOCATION) { ssize_t available = MAX_FIELD_PREALLOCATION / 2; - size = fHeader->fields_size + available * sizeof(field_header); + size = (fHeader->field_count + available) * sizeof(field_header); field_header *newFields = (field_header *)realloc(fFields, size); - if (size > 0 && !newFields) { + if (size > 0 && newFields == NULL) { // this is strange, but not really fatal return B_OK; } fFields = newFields; - fHeader->fields_available = available; + fFieldsAvailable = available; } return B_OK; @@ -1152,7 +1370,11 @@ status_t BMessage::AddData(const char *name, type_code type, const void *data, ssize_t numBytes, bool isFixedSize, int32 count) { - if (numBytes <= 0 || !data) + // Note that the "count" argument is only a hint at how many items + // the caller expects to add to this field. Since we do no item pre- + // allocation, we ignore this argument. + DEBUG_FUNCTION_ENTER; + if (numBytes <= 0 || data == NULL) return B_BAD_VALUE; field_header *field = NULL; @@ -1163,11 +1385,11 @@ BMessage::AddData(const char *name, type_code type, const void *data, if (result < B_OK) return result; - if (!field) + if (field == NULL) return B_ERROR; uint32 offset = field->offset + field->name_length + field->data_size; - if (field->flags & FIELD_FLAG_FIXED_SIZE) { + if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0) { if (field->count) { ssize_t size = field->data_size / field->count; if (size != numBytes) @@ -1184,7 +1406,7 @@ BMessage::AddData(const char *name, type_code type, const void *data, memcpy(fData + offset, data, numBytes); field->data_size += numBytes; } else { - int32 change = numBytes + sizeof(numBytes); + int32 change = numBytes + sizeof(uint32); result = _ResizeData(offset, change); if (result < B_OK) { if (field->count == 0) @@ -1192,8 +1414,9 @@ BMessage::AddData(const char *name, type_code type, const void *data, return result; } - memcpy(fData + offset, &numBytes, sizeof(numBytes)); - memcpy(fData + offset + sizeof(numBytes), data, numBytes); + uint32 size = (uint32)numBytes; + memcpy(fData + offset, &size, sizeof(uint32)); + memcpy(fData + offset + sizeof(uint32), data, size); field->data_size += change; } @@ -1205,8 +1428,9 @@ BMessage::AddData(const char *name, type_code type, const void *data, status_t BMessage::RemoveData(const char *name, int32 index) { + DEBUG_FUNCTION_ENTER; if (index < 0) - return B_BAD_VALUE; + return B_BAD_INDEX; field_header *field = NULL; status_t result = _FindField(name, B_ANY_TYPE, &field); @@ -1214,17 +1438,17 @@ BMessage::RemoveData(const char *name, int32 index) if (result < B_OK) return result; - if (!field) + if (field == NULL) return B_ERROR; - if (index >= field->count) + if ((uint32)index >= field->count) return B_BAD_INDEX; if (field->count == 1) return _RemoveField(field); uint32 offset = field->offset + field->name_length; - if (field->flags & FIELD_FLAG_FIXED_SIZE) { + if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0) { ssize_t size = field->data_size / field->count; result = _ResizeData(offset + index * size, -size); if (result < B_OK) @@ -1233,13 +1457,12 @@ BMessage::RemoveData(const char *name, int32 index) field->data_size -= size; } else { uint8 *pointer = fData + offset; - for (int32 i = 0; i < index; i++) { - offset += *(ssize_t *)pointer + sizeof(ssize_t); + offset += *(uint32 *)pointer + sizeof(uint32); pointer = fData + offset; } - ssize_t currentSize = *(ssize_t *)pointer + sizeof(ssize_t); + size_t currentSize = *(uint32 *)pointer + sizeof(uint32); result = _ResizeData(offset, -currentSize); if (result < B_OK) return result; @@ -1255,13 +1478,14 @@ BMessage::RemoveData(const char *name, int32 index) status_t BMessage::RemoveName(const char *name) { + DEBUG_FUNCTION_ENTER; field_header *field = NULL; status_t result = _FindField(name, B_ANY_TYPE, &field); if (result < B_OK) return result; - if (!field) + if (field == NULL) return B_ERROR; return _RemoveField(field); @@ -1271,6 +1495,7 @@ BMessage::RemoveName(const char *name) status_t BMessage::MakeEmpty() { + DEBUG_FUNCTION_ENTER; _Clear(); _InitHeader(); return B_OK; @@ -1281,7 +1506,8 @@ status_t BMessage::FindData(const char *name, type_code type, int32 index, const void **data, ssize_t *numBytes) const { - if (!data || !numBytes) + DEBUG_FUNCTION_ENTER; + if (data == NULL) return B_BAD_VALUE; *data = NULL; @@ -1291,23 +1517,25 @@ BMessage::FindData(const char *name, type_code type, int32 index, if (result < B_OK) return result; - if (!field) + if (field == NULL) return B_ERROR; - if (index >= field->count) + if (index < 0 || (uint32)index >= field->count) return B_BAD_INDEX; - if (field->flags & FIELD_FLAG_FIXED_SIZE) { - *numBytes = field->data_size / field->count; - *data = fData + field->offset + field->name_length + index * *numBytes; + if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0) { + size_t bytes = field->data_size / field->count; + *data = fData + field->offset + field->name_length + index * bytes; + if (numBytes != NULL) + *numBytes = bytes; } else { uint8 *pointer = fData + field->offset + field->name_length; - for (int32 i = 0; i < index; i++) - pointer += *(ssize_t *)pointer + sizeof(ssize_t); + pointer += *(uint32 *)pointer + sizeof(uint32); - *numBytes = *(ssize_t *)pointer; - *data = pointer + sizeof(ssize_t); + *data = pointer + sizeof(uint32); + if (numBytes != NULL) + *numBytes = *(uint32 *)pointer; } return B_OK; @@ -1318,7 +1546,8 @@ status_t BMessage::ReplaceData(const char *name, type_code type, int32 index, const void *data, ssize_t numBytes) { - if (numBytes <= 0 || !data) + DEBUG_FUNCTION_ENTER; + if (numBytes <= 0 || data == NULL) return B_BAD_VALUE; field_header *field = NULL; @@ -1327,13 +1556,13 @@ BMessage::ReplaceData(const char *name, type_code type, int32 index, if (result < B_OK) return result; - if (!field) + if (field == NULL) return B_ERROR; - if (index >= field->count) + if (index < 0 || (uint32)index >= field->count) return B_BAD_INDEX; - if (field->flags & FIELD_FLAG_FIXED_SIZE) { + if ((field->flags & FIELD_FLAG_FIXED_SIZE) != 0) { ssize_t size = field->data_size / field->count; if (size != numBytes) return B_BAD_VALUE; @@ -1345,18 +1574,19 @@ BMessage::ReplaceData(const char *name, type_code type, int32 index, uint8 *pointer = fData + offset; for (int32 i = 0; i < index; i++) { - offset += *(ssize_t *)pointer + sizeof(ssize_t); + offset += *(uint32 *)pointer + sizeof(uint32); pointer = fData + offset; } - ssize_t currentSize = *(ssize_t *)pointer; + size_t currentSize = *(uint32 *)pointer; int32 change = numBytes - currentSize; result = _ResizeData(offset, change); if (result < B_OK) return result; - memcpy(fData + offset, &numBytes, sizeof(numBytes)); - memcpy(fData + offset + sizeof(numBytes), data, numBytes); + uint32 newSize = (uint32)numBytes; + memcpy(fData + offset, &newSize, sizeof(uint32)); + memcpy(fData + offset + sizeof(uint32), data, newSize); field->data_size += change; } @@ -1367,28 +1597,26 @@ BMessage::ReplaceData(const char *name, type_code type, int32 index, bool BMessage::HasData(const char *name, type_code type, int32 index) const { + DEBUG_FUNCTION_ENTER; field_header *field = NULL; status_t result = _FindField(name, type, &field); if (result < B_OK) return false; - if (!field) + if (field == NULL) return false; - if (index >= field->count) + if (index < 0 || (uint32)index >= field->count) return false; return true; } -void -BMessage::_StaticCacheCleanup() -{ - delete sMsgCache; - sMsgCache = NULL; -} +void BMessage::_ReservedMessage1(void) {}; +void BMessage::_ReservedMessage2(void) {}; +void BMessage::_ReservedMessage3(void) {}; /* Relay functions from here on (Add... -> AddData, Find... -> FindData) */ @@ -1453,9 +1681,13 @@ BMessage::Has##typeName(const char *name, int32 index) const \ DEFINE_FUNCTIONS(BPoint, Point, B_POINT_TYPE); DEFINE_FUNCTIONS(BRect, Rect, B_RECT_TYPE); DEFINE_FUNCTIONS(int8, Int8, B_INT8_TYPE); +DEFINE_FUNCTIONS(uint8, UInt8, B_UINT8_TYPE); DEFINE_FUNCTIONS(int16, Int16, B_INT16_TYPE); +DEFINE_FUNCTIONS(uint16, UInt16, B_UINT16_TYPE); DEFINE_FUNCTIONS(int32, Int32, B_INT32_TYPE); +DEFINE_FUNCTIONS(uint32, UInt32, B_UINT32_TYPE); DEFINE_FUNCTIONS(int64, Int64, B_INT64_TYPE); +DEFINE_FUNCTIONS(uint64, UInt64, B_UINT64_TYPE); DEFINE_FUNCTIONS(bool, Bool, B_BOOL_TYPE); DEFINE_FUNCTIONS(float, Float, B_FLOAT_TYPE); DEFINE_FUNCTIONS(double, Double, B_DOUBLE_TYPE); @@ -1545,17 +1777,31 @@ BMessage::AddRef(const char *name, const entry_ref *ref) status_t BMessage::AddMessage(const char *name, const BMessage *message) { - /* ToDo: This and the following functions waste time by allocating and - copying an extra buffer. Functions can be added that return a direct - pointer into the message. */ + if (message == NULL) + return B_BAD_VALUE; + // TODO: This and the following functions waste time by allocating and + // copying an extra buffer. Functions can be added that return a direct + // pointer into the message. + + char stackBuffer[16384]; ssize_t size = message->FlattenedSize(); - char buffer[size]; + + char* buffer; + if (size > (ssize_t)sizeof(stackBuffer)) { + buffer = (char *)malloc(size); + if (buffer == NULL) + return B_NO_MEMORY; + } else + buffer = stackBuffer; status_t error = message->Flatten(buffer, size); if (error >= B_OK) - error = AddData(name, B_MESSAGE_TYPE, &buffer, size, false); + error = AddData(name, B_MESSAGE_TYPE, buffer, size, false); + + if (buffer != stackBuffer) + free(buffer); return error; } @@ -1564,13 +1810,27 @@ BMessage::AddMessage(const char *name, const BMessage *message) status_t BMessage::AddFlat(const char *name, BFlattenable *object, int32 count) { + if (object == NULL) + return B_BAD_VALUE; + + char stackBuffer[16384]; ssize_t size = object->FlattenedSize(); - char buffer[size]; + + char* buffer; + if (size > (ssize_t)sizeof(stackBuffer)) { + buffer = (char *)malloc(size); + if (buffer == NULL) + return B_NO_MEMORY; + } else + buffer = stackBuffer; status_t error = object->Flatten(buffer, size); if (error >= B_OK) - error = AddData(name, object->TypeCode(), &buffer, size, false); + error = AddData(name, object->TypeCode(), buffer, size, false); + + if (buffer != stackBuffer) + free(buffer); return error; } @@ -1601,6 +1861,9 @@ BMessage::FindString(const char *name, BString *string) const status_t BMessage::FindString(const char *name, int32 index, BString *string) const { + if (string == NULL) + return B_BAD_VALUE; + const char *cstr; status_t error = FindString(name, index, &cstr); if (error < B_OK) @@ -1621,6 +1884,9 @@ BMessage::FindPointer(const char *name, void **pointer) const status_t BMessage::FindPointer(const char *name, int32 index, void **pointer) const { + if (pointer == NULL) + return B_BAD_VALUE; + void **data = NULL; ssize_t size = 0; status_t error = FindData(name, B_POINTER_TYPE, index, @@ -1646,6 +1912,9 @@ status_t BMessage::FindMessenger(const char *name, int32 index, BMessenger *messenger) const { + if (messenger == NULL) + return B_BAD_VALUE; + void *data = NULL; ssize_t size = 0; status_t error = FindData(name, B_MESSENGER_TYPE, index, @@ -1670,6 +1939,9 @@ BMessage::FindRef(const char *name, entry_ref *ref) const status_t BMessage::FindRef(const char *name, int32 index, entry_ref *ref) const { + if (ref == NULL) + return B_BAD_VALUE; + void *data = NULL; ssize_t size = 0; status_t error = FindData(name, B_REF_TYPE, index, @@ -1694,6 +1966,9 @@ BMessage::FindMessage(const char *name, BMessage *message) const status_t BMessage::FindMessage(const char *name, int32 index, BMessage *message) const { + if (message == NULL) + return B_BAD_VALUE; + void *data = NULL; ssize_t size = 0; status_t error = FindData(name, B_MESSAGE_TYPE, index, @@ -1718,6 +1993,9 @@ BMessage::FindFlat(const char *name, BFlattenable *object) const status_t BMessage::FindFlat(const char *name, int32 index, BFlattenable *object) const { + if (object == NULL) + return B_BAD_VALUE; + void *data = NULL; ssize_t numBytes = 0; status_t error = FindData(name, object->TypeCode(), index, @@ -1741,6 +2019,9 @@ BMessage::FindData(const char *name, type_code type, const void **data, status_t BMessage::ReplaceString(const char *name, const char *string) { + if (string == NULL) + return B_BAD_VALUE; + return ReplaceData(name, B_STRING_TYPE, 0, string, strlen(string) + 1); } @@ -1748,6 +2029,9 @@ BMessage::ReplaceString(const char *name, const char *string) status_t BMessage::ReplaceString(const char *name, int32 index, const char *string) { + if (string == NULL) + return B_BAD_VALUE; + return ReplaceData(name, B_STRING_TYPE, index, string, strlen(string) + 1); } @@ -1830,6 +2114,9 @@ BMessage::ReplaceMessage(const char *name, const BMessage *message) status_t BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *message) { + if (message == NULL) + return B_BAD_VALUE; + ssize_t size = message->FlattenedSize(); char buffer[size]; @@ -1852,6 +2139,9 @@ BMessage::ReplaceFlat(const char *name, BFlattenable *object) status_t BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object) { + if (object == NULL) + return B_BAD_VALUE; + ssize_t size = object->FlattenedSize(); char buffer[size]; diff --git a/src/build/libbe/app/MessageAdapter.cpp b/src/build/libbe/app/MessageAdapter.cpp index b8e032fa9a..ce69e4ab6d 100644 --- a/src/build/libbe/app/MessageAdapter.cpp +++ b/src/build/libbe/app/MessageAdapter.cpp @@ -6,12 +6,12 @@ * Axel Dörfler, axeld@pinc-software.de * Michael Lotz */ -#include - #include #include #include +#include + namespace BPrivate { @@ -41,7 +41,7 @@ enum { struct r5_message_header { uint32 magic; uint32 checksum; - ssize_t flattened_size; + int32 flattened_size; int32 what; uint8 flags; } _PACKED; @@ -49,7 +49,7 @@ struct r5_message_header { struct dano_section_header { uint32 code; - ssize_t size; + int32 size; uint8 data[0]; } _PACKED; @@ -69,7 +69,7 @@ typedef struct offset_table_s { struct dano_single_item { type_code type; - ssize_t item_size; + int32 item_size; uint8 name_length; char name[0]; } _PACKED; @@ -77,7 +77,7 @@ struct dano_single_item { struct dano_fixed_size_array { type_code type; - ssize_t size_per_item; + int32 size_per_item; uint8 name_length; char name[0]; } _PACKED; @@ -250,7 +250,7 @@ MessageAdapter::_R5FlattenedSize(const BMessage *from) uint8 *data = messagePrivate.GetMessageData(); BMessage::field_header *field = messagePrivate.GetMessageFields(); - for (int32 i = 0; i < header->field_count; i++, field++) { + for (uint32 i = 0; i < header->field_count; i++, field++) { // flags and type flattenedSize += 1 + sizeof(type_code); @@ -277,7 +277,7 @@ MessageAdapter::_R5FlattenedSize(const BMessage *from) else { uint8 *source = data + field->offset + field->name_length; - for (int32 i = 0; i < field->count; i++) { + for (uint32 i = 0; i < field->count; i++) { ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t); flattenedSize += pad_to_8(itemSize); source += itemSize; @@ -344,11 +344,11 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from, r5header->flags = flags; // store the header size - used for the checksum later - ssize_t headerSize = (addr_t)pointer - (addr_t)buffer; + ssize_t headerSize = (uint32)pointer - (uint32)buffer; // collect and add the data BMessage::field_header *field = messagePrivate.GetMessageFields(); - for (int32 i = 0; i < header->field_count; i++, field++) { + for (uint32 i = 0; i < header->field_count; i++, field++) { flags = R5_FIELD_FLAG_VALID; if (field->count == 1) @@ -400,10 +400,12 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from, pointer += field->data_size; } else { uint8 *previous = pointer; - for (int32 i = 0; i < field->count; i++) { + for (uint32 i = 0; i < field->count; i++) { ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t); memcpy(pointer, source, itemSize); - pointer += pad_to_8(itemSize); + ssize_t paddedSize = pad_to_8(itemSize); + memset(pointer + itemSize, 0, paddedSize - itemSize); + pointer += paddedSize; source += itemSize; } @@ -420,7 +422,7 @@ MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from, pointer++; // calculate the flattened size from the pointers - r5header->flattened_size = (addr_t)pointer - (addr_t)buffer; + r5header->flattened_size = (uint32)pointer - (uint32)buffer; r5header->checksum = CalculateChecksum((uint8 *)(buffer + 8), headerSize - 8); @@ -451,13 +453,13 @@ MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into, header->what = into->what = r5header.what; if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_TARGET) - reader(header->target); + reader(&header->target, sizeof(header->target)); if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_REPLY) { // reply info - reader(header->reply_port); - reader(header->reply_target); - reader(header->reply_team); + reader(&header->reply_port, sizeof(header->reply_port)); + reader(&header->reply_target, sizeof(header->reply_target)); + reader(&header->reply_team, sizeof(header->reply_team)); // big flags uint8 bigFlag; @@ -530,25 +532,13 @@ MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into, if (fixedSize) itemSize = dataSize / itemCount; - if (fixedSize) { + if (format == MESSAGE_FORMAT_R5) { for (int32 i = 0; i < itemCount; i++) { - // ToDo: what if we are swapped? need B_INT32_TYPEs and the - // like be swapped here? - result = into->AddData(nameBuffer, type, pointer, itemSize, - fixedSize, itemCount); - - if (result < B_OK) { - free(buffer); - return result; + if (!fixedSize) { + itemSize = *(ssize_t *)pointer; + pointer += sizeof(ssize_t); } - pointer += itemSize; - } - } else if (format == MESSAGE_FORMAT_R5_SWAPPED) { - for (int32 i = 0; i < itemCount; i++) { - itemSize = __swap_int32(*(ssize_t *)pointer); - pointer += sizeof(ssize_t); - result = into->AddData(nameBuffer, type, pointer, itemSize, fixedSize, itemCount); @@ -557,13 +547,19 @@ MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into, return result; } - pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t); + if (fixedSize) + pointer += itemSize; + else + pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t); } } else { for (int32 i = 0; i < itemCount; i++) { - itemSize = *(ssize_t *)pointer; - pointer += sizeof(ssize_t); + if (!fixedSize) { + itemSize = __swap_int32(*(ssize_t *)pointer); + pointer += sizeof(ssize_t); + } + swap_data(type, pointer, itemSize, B_SWAP_ALWAYS); result = into->AddData(nameBuffer, type, pointer, itemSize, fixedSize, itemCount); @@ -572,7 +568,10 @@ MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into, return result; } - pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t); + if (fixedSize) + pointer += itemSize; + else + pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t); } } @@ -618,15 +617,18 @@ MessageAdapter::_UnflattenDanoMessage(uint32 format, BMessage *into, ssize_t fieldSize = sectionHeader.size - sizeof(dano_section_header); uint8 *fieldBuffer = NULL; - if (fieldSize > 0) { + if (fieldSize <= 0) { // there may be no data. we shouldn't fail because of that - fieldBuffer = (uint8 *)malloc(fieldSize); - if (fieldBuffer == NULL) - throw (status_t)B_NO_MEMORY; - - reader(fieldBuffer, fieldSize); + offset += sectionHeader.size; + continue; } + fieldBuffer = (uint8 *)malloc(fieldSize); + if (fieldBuffer == NULL) + throw (status_t)B_NO_MEMORY; + + reader(fieldBuffer, fieldSize); + switch (sectionHeader.code) { case SECTION_OFFSET_TABLE: case SECTION_TARGET_INFORMATION: diff --git a/src/build/libbe/app/MessageUtils.cpp b/src/build/libbe/app/MessageUtils.cpp index 2638f539ae..771dc4210b 100644 --- a/src/build/libbe/app/MessageUtils.cpp +++ b/src/build/libbe/app/MessageUtils.cpp @@ -44,14 +44,21 @@ CalculateChecksum(const uint8 *buffer, int32 size) status_t entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref) { + if (*size < sizeof(ref->device) + sizeof(ref->directory)) + return B_BUFFER_OVERFLOW; + memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device)); buffer += sizeof(ref->device); memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory)); buffer += sizeof (ref->directory); + *size -= sizeof(ref->device) + sizeof(ref->directory); size_t nameLength = 0; if (ref->name) { nameLength = strlen(ref->name) + 1; + if (*size < nameLength) + return B_BUFFER_OVERFLOW; + memcpy((void *)buffer, (const void *)ref->name, nameLength); } @@ -73,8 +80,8 @@ entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size) memcpy((void *)&ref->directory, (const void *)buffer, sizeof(ref->directory)); buffer += sizeof(ref->directory); - if (ref->device != ~(dev_t)0 && size > sizeof(ref->device) - + sizeof(ref->directory)) { + if (ref->device != -1 && size > sizeof(ref->device) + + sizeof(ref->directory)) { ref->set_name(buffer); if (ref->name == NULL) { *ref = entry_ref(); diff --git a/src/build/libbe/app/Messenger.cpp b/src/build/libbe/app/Messenger.cpp index e10ce0a1be..97aae4e54c 100644 --- a/src/build/libbe/app/Messenger.cpp +++ b/src/build/libbe/app/Messenger.cpp @@ -1,46 +1,41 @@ /* - * Copyright 2001-2008, Haiku Inc. All rights reserved. + * Copyright 2001-2007, Haiku. * Distributed under the terms of the MIT License. * * Authors: - * Ingo Weinhold, bonefish@users.sf.net + * Ingo Weinhold (bonefish@users.sf.net) */ -/*! - \class BMessenger - Delivers messages to local or remote targets. -*/ +#include +#include +#include "TokenSpace.h" + +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +// debugging +//#define DBG(x) x #define DBG(x) #define OUT printf -using BPrivate::gDefaultTokens; -using BPrivate::gLooperList; -using BPrivate::BLooperList; -using BPrivate::BObjectLocker; - -// #pragma mark - +enum { + NOT_IMPLEMENTED = B_ERROR, +}; /*! \brief Creates an unitialized BMessenger. @@ -49,8 +44,7 @@ BMessenger::BMessenger() : fPort(-1), fHandlerToken(B_NULL_TOKEN), - fTeam(-1), - fPreferredTarget(false) + fTeam(-1) { } @@ -60,12 +54,11 @@ BMessenger::BMessenger() \param from The messenger to be copied. */ -BMessenger::BMessenger(const BMessenger &from) +BMessenger::BMessenger(const BMessenger& from) : fPort(from.fPort), fHandlerToken(from.fHandlerToken), - fTeam(from.fTeam), - fPreferredTarget(from.fPreferredTarget) + fTeam(from.fTeam) { } @@ -77,6 +70,9 @@ BMessenger::~BMessenger() } +// #pragma mark - Operators and misc + + /*! \brief Makes this BMessenger a copy of the supplied one. \param from the messenger to be copied. @@ -89,7 +85,6 @@ BMessenger::operator=(const BMessenger &from) fPort = from.fPort; fHandlerToken = from.fHandlerToken; fTeam = from.fTeam; - fPreferredTarget = from.fPreferredTarget; } return *this; } @@ -107,8 +102,7 @@ BMessenger::operator==(const BMessenger &other) const { // Note: The fTeam fields are not compared. return fPort == other.fPort - && fHandlerToken == other.fHandlerToken - && fPreferredTarget == other.fPreferredTarget; + && fHandlerToken == other.fHandlerToken; } @@ -123,7 +117,6 @@ bool BMessenger::IsValid() const { return fPort >= 0; - // for the build version, we don't actually check the port } @@ -138,23 +131,23 @@ BMessenger::Team() const } +// #pragma mark - Private or reserved + + /*! \brief Sets the messenger's team, target looper port and handler token. - If \a preferred is \c true, \a token is ignored. + To target the preferred handler, use B_PREFERRED_TOKEN as token. \param team The target's team. \param port The target looper port. \param token The target handler token. - \param preferred \c true to rather use the looper's preferred handler - instead of the one specified by \a token. */ void -BMessenger::SetTo(team_id team, port_id port, int32 token, bool preferred) +BMessenger::_SetTo(team_id team, port_id port, int32 token) { fTeam = team; fPort = port; - fHandlerToken = preferred ? B_PREFERRED_TOKEN : token; - fPreferredTarget = preferred; + fHandlerToken = token; } @@ -179,12 +172,12 @@ operator<(const BMessenger &_a, const BMessenger &_b) // 2. fHandlerToken // 3. fPreferredTarget // fTeam is insignificant - return a.Port() < b.Port() - || (a.Port() == b.Port() - && (a.Token() < b.Token() - || (a.Token() == b.Token() - && !a.IsPreferredTarget() - && b.IsPreferredTarget()))); + return (a.Port() < b.Port() + || (a.Port() == b.Port() + && (a.Token() < b.Token() + || (a.Token() == b.Token() + && !a.IsPreferredTarget() + && b.IsPreferredTarget())))); } @@ -200,3 +193,4 @@ operator!=(const BMessenger &a, const BMessenger &b) { return !(a == b); } + diff --git a/src/build/libbe/support/ByteOrder.cpp b/src/build/libbe/support/ByteOrder.cpp index f4aa583f08..b8ae678b0b 100644 --- a/src/build/libbe/support/ByteOrder.cpp +++ b/src/build/libbe/support/ByteOrder.cpp @@ -1,4 +1,4 @@ -/* +/* ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the Haiku License. */ @@ -114,8 +114,7 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) messengerPrivate.SetTo( __swap_int32(messengerPrivate.Team()), __swap_int32(messengerPrivate.Port()), - __swap_int32(messengerPrivate.Token()), - messengerPrivate.IsPreferredTarget()); + __swap_int32(messengerPrivate.Token())); messenger++; } break;