From 7bc5a06be607c250e4644a3270f47ac6e882aa4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 30 Aug 2007 01:03:33 +0000 Subject: [PATCH] * BShelf::_AddReplicant() did not recognize zombies if their object was not inherited from BView. * BShelf::_AddReplicant() did not honour the fAllowZombies flag correctly; if it wasn't allowed, no error message was given. * Both of these changes fixes the crashing of the Deskbar as described in bug #555. * instantiate_object() now also fires a message to the syslog if the object's image could not been loaded. Some cleanup, no longer resets errno. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22117 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Shelf.cpp | 26 +++++++--- src/kits/support/Archivable.cpp | 89 ++++++++++++--------------------- 2 files changed, 51 insertions(+), 64 deletions(-) diff --git a/src/kits/interface/Shelf.cpp b/src/kits/interface/Shelf.cpp index f9748fc863..1abb4601c7 100644 --- a/src/kits/interface/Shelf.cpp +++ b/src/kits/interface/Shelf.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006, Haiku. + * Copyright 2001-2007, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -1088,7 +1088,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID) // Check shelf types if needed if (fTypeEnforced) { const char *shelfType = NULL; - if (data->FindString("shelf_type", &shelfType) == B_OK && shelfType != NULL) { + if (data->FindString("shelf_type", &shelfType) == B_OK + && shelfType != NULL) { if (Name() && strcmp(shelfType, Name()) != 0) { printf("Replicant was rejected by BShelf: The BShelf's type and the Replicant's type don't match."); return send_reply(data, B_ERROR, uniqueID); @@ -1142,10 +1143,14 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID) // Instantiate the object, if this fails we have a zombie image_id image; BArchivable *archivable = _InstantiateObject(data, &image); - if (archivable) { - BView *view = dynamic_cast(archivable); - BPoint point; + BView *view = dynamic_cast(archivable); + if (archivable != NULL && view == NULL) { + printf("Replicant was rejected: it's not a view!"); + return send_reply(data, B_ERROR, uniqueID); + } + if (view != NULL) { + BPoint point; if (location) point = *location; else @@ -1215,7 +1220,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID) view->MoveTo(point + adjust); // if it's a sibling or a child, we need to add the dragger - if (relation == BDragger::TARGET_IS_SIBLING || relation == BDragger::TARGET_IS_CHILD) + if (relation == BDragger::TARGET_IS_SIBLING + || relation == BDragger::TARGET_IS_CHILD) fContainerView->AddChild(dragger); replicant->AddFilter(new ReplicantViewFilter(this, replicant)); @@ -1246,13 +1252,17 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID) fContainerView->AddChild(zombie); } + } else if (!fAllowZombies) { + // There was no view, and we're not allowed to have any zombies + // in the house + return send_reply(data, B_ERROR, uniqueID); } data->RemoveName("_drop_point_"); data->RemoveName("_drop_offset_"); - replicant_data *item = new replicant_data(data, replicant, dragger, relation, - uniqueID, image); + replicant_data *item = new replicant_data(data, replicant, dragger, + relation, uniqueID, image); item->error = B_OK; item->zombie_view = zombie; diff --git a/src/kits/support/Archivable.cpp b/src/kits/support/Archivable.cpp index bba722f5fe..3e82b1eceb 100644 --- a/src/kits/support/Archivable.cpp +++ b/src/kits/support/Archivable.cpp @@ -1,13 +1,14 @@ /* - * Copyright (c) 2001-2006, Haiku, Inc. + * Copyright (c) 2001-2007, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Erik Jaesler (erik@cgsoftware.com) */ -/** Description: BArchivable mix-in class defines the archiving - protocol. Also some global archiving functions.*/ +/*! BArchivable mix-in class defines the archiving protocol. + Also some global archiving functions. +*/ #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include @@ -26,8 +28,6 @@ #include #include #include -#include -#include using std::string; @@ -37,35 +37,15 @@ const char* B_CLASS_FIELD = "class"; const char* B_ADD_ON_FIELD = "add_on"; const int32 FUNC_NAME_LEN = 1024; -// TODO: consider moving these -// to a separate module, and making them more full-featured (e.g., taking -// NS::ClassName::Function(Param p) instead of just NS::ClassName) +// TODO: consider moving these to a separate module, and making them more +// full-featured (e.g., taking NS::ClassName::Function(Param p) instead +// of just NS::ClassName) static void Demangle(const char *name, BString &out); static void Mangle(const char *name, BString &out); static instantiation_func FindFuncInImage(BString& funcName, image_id id, - status_t& err); + status_t& err); static bool CheckSig(const char* sig, image_info& info); -/* -// TODO: Where do these get triggered from? -Log entries graciously coughed up by the Be implementation: - Nov 28 01:40:45 instantiate_object failed: NULL BMessage argument - Nov 28 01:40:45 instantiate_object failed: Failed to find an entrydefining the class name (Name not found). - Nov 28 01:40:45 instantiate_object failed: No signature specified in archive, looking for class "TInvalidClassName". - Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found) - Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b) - Nov 28 01:40:45 instantiate_object failed: Failed to find exported Instantiate static function for class TInvalidClassName. - Nov 28 01:40:45 instantiate_object failed: Invalid argument (80000005) - Nov 28 01:40:45 instantiate_object failed: No signature specified in archive, looking for class "TRemoteTestObject". - Nov 28 01:40:45 instantiate_object - couldn't get mime sig for /boot/home/src/projects/OpenBeOS/app_kit/test/lib/support/BArchivable/./BArchivableSystemTester - Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found) - Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b) - Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found) - Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b) - Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found) - Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b) -*/ - BArchivable::BArchivable() { @@ -142,12 +122,9 @@ BuildFuncName(const char* className, BString& funcName) BArchivable* instantiate_object(BMessage* archive, image_id* id) { - errno = B_OK; - // Check our params - if (id) { + if (id) *id = B_BAD_VALUE; - } if (!archive) { // TODO: extended error handling @@ -162,7 +139,7 @@ instantiate_object(BMessage* archive, image_id* id) if (err) { // TODO: extended error handling syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry " - "defining the class name (%s).", strerror(err)); + "defining the class name (%s).", strerror(err)); return NULL; } @@ -172,68 +149,68 @@ instantiate_object(BMessage* archive, image_id* id) instantiation_func iFunc = find_instantiation_func(name, sig); - // if find_instantiation_func() can't locate Class::Instantiate() - // and a signature was specified + // if find_instantiation_func() can't locate Class::Instantiate() + // and a signature was specified if (!iFunc && hasSig) { - // use BRoster::FindApp() to locate an app or add-on with the symbol + // use BRoster::FindApp() to locate an app or add-on with the symbol BRoster Roster; entry_ref ref; err = Roster.FindApp(sig, &ref); + // if an entry_ref is obtained BEntry entry; - - // if an entry_ref is obtained if (!err) err = entry.SetTo(&ref); if (err) { syslog(LOG_ERR, "instantiate_object failed: Error finding app " - "with signature \"%s\" (%s)", sig, strerror(err)); + "with signature \"%s\" (%s)", sig, strerror(err)); } if (!err) { BPath path; err = entry.GetPath(&path); if (!err) { - // load the app/add-on - image_id theImage = load_add_on(path.Path()); - if (theImage < 0) { + // load the app/add-on + image_id addOn = load_add_on(path.Path()); + if (addOn < 0) { // TODO: extended error handling + syslog(LOG_ERR, "instantiate_object failed: Could not load " + "add-on %s: %s.", path.Path(), strerror(addOn)); return NULL; } - + // Save the image_id - if (id) { - *id = theImage; - } - + if (id) + *id = addOn; + BString funcName; BuildFuncName(name, funcName); - iFunc = FindFuncInImage(funcName, theImage, err); - if (!iFunc) - { + + iFunc = FindFuncInImage(funcName, addOn, err); + if (!iFunc) { syslog(LOG_ERR, "instantiate_object failed: Failed to find exported " - "Instantiate static function for class %s.", name); + "Instantiate static function for class %s.", name); } } } } else if (!iFunc) { syslog(LOG_ERR, "instantiate_object failed: No signature specified " - "in archive, looking for class \"%s\".", name); + "in archive, looking for class \"%s\".", name); errno = B_BAD_VALUE; } if (err) { // TODO: extended error handling syslog(LOG_ERR, "instantiate_object failed: %s (%x)", - strerror(err), err); + strerror(err), err); errno = err; return NULL; } - // if Class::Instantiate(BMessage*) was found + // if Class::Instantiate(BMessage*) was found if (iFunc) { - // use to create and return an object instance + // use to create and return an object instance return iFunc(archive); }