From 13bbfe422b13d808b182a3abf187800d4d80e631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 26 Apr 2008 14:28:16 +0000 Subject: [PATCH] * validate_instantiation() also needs to add the BPrivate namespace in case it couldn't find the class on first try. This fixes the problems mentioned by Shinta as part of bug #2086. * Got rid of GetNumber() - there is a POSIX function strtoul() for exactly this purpose. * demangle_class_name() can now fail. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25179 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/support/Archivable.cpp | 86 +++++++++++++++------------------ 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/kits/support/Archivable.cpp b/src/kits/support/Archivable.cpp index 78d2ffa8eb..ace759fcde 100644 --- a/src/kits/support/Archivable.cpp +++ b/src/kits/support/Archivable.cpp @@ -42,19 +42,7 @@ const int32 FUNC_NAME_LEN = 1024; // of just NS::ClassName) -static int -GetNumber(const char*& name) -{ - int val = atoi(name); - while (isdigit(*name)) { - ++name; - } - - return val; -} - - -static void +static status_t demangle_class_name(const char* name, BString& out) { // TODO: add support for template classes @@ -62,40 +50,38 @@ demangle_class_name(const char* name, BString& out) out = ""; - // Are we in a namespace? - if (*name == 'Q') { - // Yessir, we are; how many deep are we? - int nsCount = 0; - ++name; - if (*name == '_') { - // more than 10 deep - ++name; - if (!isdigit(*name)) - ; // TODO: error handling + if (name[0] == 'Q') { + // The name is in a namespace + int namespaceCount = 0; + name++; + if (name[0] == '_') { + // more than 10 namespaces deep + if (!isdigit(*++name)) + return B_BAD_VALUE; - nsCount = GetNumber(name); - if (*name == '_') // more than 10 deep - ++name; - else - ; // this should be an error condition - } else { - nsCount = *name - '0'; - ++name; - } + namespaceCount = strtoul(name, (char**)&name, 10); + if (name[0] != '_') + return B_BAD_VALUE; + } else + namespaceCount = name[0] - '0'; - int nameLen = 0; - for (int i = 0; i < nsCount - 1; ++i) { - if (!isdigit(*name)) - ; // TODO: error handling + name++; - nameLen = GetNumber(name); - out.Append(name, nameLen); + for (int i = 0; i < namespaceCount - 1; i++) { + if (!isdigit(name[0])) + return B_BAD_VALUE; + + int nameLength = strtoul(name, (char**)&name, 10); + out.Append(name, nameLength); out += "::"; - name += nameLen; + name += nameLength; } } - out.Append(name, GetNumber(name)); + int nameLength = strtoul(name, (char**)&name, 10); + out.Append(name, nameLength); + + return B_OK; } @@ -240,7 +226,9 @@ BArchivable::Archive(BMessage* into, bool deep) const } BString name; - demangle_class_name(typeid(*this).name(), name); + status_t status = demangle_class_name(typeid(*this).name(), name); + if (status != B_OK) + return status; return into->AddString(B_CLASS_FIELD, name); } @@ -393,11 +381,17 @@ validate_instantiation(BMessage* from, const char* className) return false; } - const char* data; - for (int32 index = 0; from->FindString(B_CLASS_FIELD, index, &data) == B_OK; - ++index) { - if (!strcmp(data, className)) - return true; + BString name = className; + for (int32 pass = 0; pass < 2; pass++) { + const char* archiveClassName; + for (int32 index = 0; from->FindString(B_CLASS_FIELD, index, + &archiveClassName) == B_OK; ++index) { + if (name == archiveClassName) + return true; + } + + if (!add_private_namespace(name)) + break; } errno = B_MISMATCHED_VALUES;