From b1970bb8d83df7a5cbfe7c15946166f0d2317378 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 10 Feb 2006 02:24:34 +0000 Subject: [PATCH] When only the app version_info was contained in the resources/attribute we read from (and the system version_info missing) GetVersionInfo() always failed. Given that rc only writes the app version_info, mimeset never created a BEOS:APP_VERSION attribute (nor ones for supported types icons). The version attribute was usually created nevertheless, as a side effect of the subsequent setversion invocation. Under Linux the attribute emulation can accidentially pick up the attributes of an earlier deleted node that had the the same node ID as the file in question, which in this case could cause an invalid BEOS:APP_VERSION attribute (the app version_info part at least). Now GetVersionInfo() doesn't fail anymore, when only one info could be read (the other one is zeroed). Not sure, if that is what BeOS does, but it shouldn't harm. This fixes bug #100. Also made SetVersionInfo() zero out what couldn't be read before writing it back. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16320 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/build/libbe/storage/AppFileInfo.cpp | 72 +++++++++++++++---------- src/kits/storage/AppFileInfo.cpp | 72 +++++++++++++++---------- 2 files changed, 88 insertions(+), 56 deletions(-) diff --git a/src/build/libbe/storage/AppFileInfo.cpp b/src/build/libbe/storage/AppFileInfo.cpp index e7e9767348..67c9416535 100644 --- a/src/build/libbe/storage/AppFileInfo.cpp +++ b/src/build/libbe/storage/AppFileInfo.cpp @@ -638,37 +638,46 @@ status_t BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const { // check params and initialization - status_t error = (info ? B_OK : B_BAD_VALUE); + if (!info) + return B_BAD_VALUE; + int32 index = 0; - if (error == B_OK) { - switch (kind) { - case B_APP_VERSION_KIND: - index = 0; - break; - case B_SYSTEM_VERSION_KIND: - index = 1; - break; - default: - error = B_BAD_VALUE; - break; - } + switch (kind) { + case B_APP_VERSION_KIND: + index = 0; + break; + case B_SYSTEM_VERSION_KIND: + index = 1; + break; + default: + return B_BAD_VALUE; } - if (error == B_OK && InitCheck() != B_OK) - error = B_NO_INIT; + + if (InitCheck() != B_OK) + return B_NO_INIT; + // read the data size_t read = 0; version_info infos[2]; - if (error == B_OK) { - error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, - B_VERSION_INFO_TYPE, infos, - 2 * sizeof(version_info), read); - } - // check the read data -- null terminate the string - if (error == B_OK && read != 2 * sizeof(version_info)) - error = B_ERROR; - if (error == B_OK) + status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, + B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); + if (error != B_OK) + return error; + + // check the read data + if (read == sizeof(version_info)) { + // only the app version info is there -- return a cleared system info + if (index == 0) + *info = infos[index]; + else if (index == 1) + memset(info, 0, sizeof(version_info)); + } else if (read == 2 * sizeof(version_info)) { *info = infos[index]; - return error; + } else + return B_ERROR; + + // return result + return B_OK; } // SetVersionInfo @@ -714,9 +723,16 @@ BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind) version_info infos[2]; if (error == B_OK) { size_t read; - _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, - B_VERSION_INFO_TYPE, infos, - 2 * sizeof(version_info), read); + if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, + B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), + read) == B_OK) { + // clear the part that hasn't been read + if (read < sizeof(infos)) + memset((char*)infos + read, 0, sizeof(infos) - read); + } else { + // failed to read -- clear + memset(infos, 0, sizeof(infos)); + } } infos[index] = *info; // write the data diff --git a/src/kits/storage/AppFileInfo.cpp b/src/kits/storage/AppFileInfo.cpp index 09c71cb814..6fbc1cd2de 100644 --- a/src/kits/storage/AppFileInfo.cpp +++ b/src/kits/storage/AppFileInfo.cpp @@ -638,37 +638,46 @@ status_t BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const { // check params and initialization - status_t error = (info ? B_OK : B_BAD_VALUE); + if (!info) + return B_BAD_VALUE; + int32 index = 0; - if (error == B_OK) { - switch (kind) { - case B_APP_VERSION_KIND: - index = 0; - break; - case B_SYSTEM_VERSION_KIND: - index = 1; - break; - default: - error = B_BAD_VALUE; - break; - } + switch (kind) { + case B_APP_VERSION_KIND: + index = 0; + break; + case B_SYSTEM_VERSION_KIND: + index = 1; + break; + default: + return B_BAD_VALUE; } - if (error == B_OK && InitCheck() != B_OK) - error = B_NO_INIT; + + if (InitCheck() != B_OK) + return B_NO_INIT; + // read the data size_t read = 0; version_info infos[2]; - if (error == B_OK) { - error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, - B_VERSION_INFO_TYPE, infos, - 2 * sizeof(version_info), read); - } - // check the read data -- null terminate the string - if (error == B_OK && read != 2 * sizeof(version_info)) - error = B_ERROR; - if (error == B_OK) + status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, + B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read); + if (error != B_OK) + return error; + + // check the read data + if (read == sizeof(version_info)) { + // only the app version info is there -- return a cleared system info + if (index == 0) + *info = infos[index]; + else if (index == 1) + memset(info, 0, sizeof(version_info)); + } else if (read == 2 * sizeof(version_info)) { *info = infos[index]; - return error; + } else + return B_ERROR; + + // return result + return B_OK; } // SetVersionInfo @@ -714,9 +723,16 @@ BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind) version_info infos[2]; if (error == B_OK) { size_t read; - _ReadData(kVersionInfoAttribute, kVersionInfoResourceID, - B_VERSION_INFO_TYPE, infos, - 2 * sizeof(version_info), read); + if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID, + B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), + read) == B_OK) { + // clear the part that hasn't been read + if (read < sizeof(infos)) + memset((char*)infos + read, 0, sizeof(infos) - read); + } else { + // failed to read -- clear + memset(infos, 0, sizeof(infos)); + } } infos[index] = *info; // write the data