#3905 Crashes in LLInventoryModel::saveToFile

I don't expect it to fix the problem. Just making things more explicit
in places of most frequent crashes.
master
Andrey Kleshchev 2025-04-30 23:45:22 +03:00 committed by Andrey Kleshchev
parent 778a69c6e1
commit f73e0d09aa
10 changed files with 49 additions and 31 deletions

View File

@ -928,7 +928,7 @@ bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool inclu
LLSD LLInventoryItem::asLLSD() const
{
LLSD sd = LLSD();
LLSD sd;
asLLSD(sd);
return sd;
}
@ -937,7 +937,7 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
{
sd[INV_ITEM_ID_LABEL] = mUUID;
sd[INV_PARENT_ID_LABEL] = mParentUUID;
sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions);
ll_fill_sd_from_permissions(sd[INV_PERMISSIONS_LABEL], mPermissions);
if (mThumbnailUUID.notNull())
{
@ -963,19 +963,22 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
cipher.encrypt(shadow_id.mData, UUID_BYTES);
sd[INV_SHADOW_ID_LABEL] = shadow_id;
}
sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
if(!inv_type_str.empty())
{
sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
}
else
{
sd[INV_INVENTORY_TYPE_LABEL] = (LLSD::Integer)mInventoryType;
}
//sd[INV_FLAGS_LABEL] = (S32)mFlags;
sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD();
mSaleInfo.asLLSD(sd[INV_SALE_INFO_LABEL]);
sd[INV_NAME_LABEL] = mName;
sd[INV_DESC_LABEL] = mDescription;
sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
sd[INV_CREATION_DATE_LABEL] = (LLSD::Integer)mCreationDate;
}
bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
@ -1501,12 +1504,11 @@ bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool)
return true;
}
LLSD LLInventoryCategory::exportLLSD() const
void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
{
LLSD cat_data;
cat_data[INV_FOLDER_ID_LABEL] = mUUID;
cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
cat_data[INV_NAME_LABEL] = mName;
@ -1518,8 +1520,6 @@ LLSD LLInventoryCategory::exportLLSD() const
{
cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
}
return cat_data;
}
bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
@ -1570,7 +1570,7 @@ bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
return true;
}
///----------------------------------------------------------------------------
/// Local function definitions
/// Local function definitions for testing purposes
///----------------------------------------------------------------------------
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)

View File

@ -273,7 +273,7 @@ public:
virtual bool importLegacyStream(std::istream& input_stream);
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
LLSD exportLLSD() const;
virtual void exportLLSD(LLSD& sd) const;
bool importLLSD(const LLSD& cat_data);
//--------------------------------------------------------------------
// Member Variables
@ -288,6 +288,7 @@ protected:
//
// These functions convert between structured data and an inventory
// item, appropriate for serialization.
// Not up to date (no favorites, nor thumbnails), for testing purposes
//-----------------------------------------------------------------------------
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat);

View File

@ -1012,17 +1012,21 @@ static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
{
LLSD rv;
ll_fill_sd_from_permissions(rv, perm);
return rv;
}
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm)
{
rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
return rv;
rv[PERM_BASE_MASK_LABEL] = (LLSD::Integer)perm.getMaskBase();
rv[PERM_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskOwner();
rv[PERM_GROUP_MASK_LABEL] = (LLSD::Integer)perm.getMaskGroup();
rv[PERM_EVERYONE_MASK_LABEL] = (LLSD::Integer)perm.getMaskEveryone();
rv[PERM_NEXT_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskNextOwner();
}
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)

View File

@ -435,6 +435,7 @@ protected:
// like 'creator_id', 'owner_id', etc, with the value copied from the
// permission object.
LLSD ll_create_sd_from_permissions(const LLPermissions& perm);
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm);
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);
#endif

View File

@ -90,15 +90,20 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
LLSD LLSaleInfo::asLLSD() const
{
LLSD sd;
asLLSD(sd);
return sd;
}
void LLSaleInfo::asLLSD(LLSD& sd) const
{
const char* type = lookup(mSaleType);
if (!type)
{
LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL;
type = lookup(LLSaleInfo::FS_NOT);
}
sd["sale_type"] = type;
sd["sale_type"] = std::string(type);
sd["sale_price"] = mSalePrice;
return sd;
}
bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask)

View File

@ -86,6 +86,7 @@ public:
bool exportLegacyStream(std::ostream& output_stream) const;
LLSD asLLSD() const;
void asLLSD(LLSD &sd) const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask);
bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask);

View File

@ -329,7 +329,9 @@ namespace tut
}
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
LLSD sd;
src1->asLLSD(sd);
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
fileXML.close();
@ -458,7 +460,9 @@ namespace tut
}
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
LLSD sd;
src1->exportLLSD(sd);
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
fileXML.close();
llifstream file(filename.c_str());

View File

@ -3500,7 +3500,9 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
{
if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
LLSD sd = LLSD::emptyMap();
cat->exportLLSD(sd);
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
cat_count++;
}
@ -3514,7 +3516,9 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
auto it_count = items.size();
for (auto& item : items)
{
fileXML << LLSDOStreamer<LLSDNotationFormatter>(item->asLLSD()) << std::endl;
LLSD sd = LLSD::emptyMap();
item->asLLSD(sd);
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
if (fileXML.fail())
{

View File

@ -751,13 +751,11 @@ S32 LLViewerInventoryCategory::getViewerDescendentCount() const
return descendents_actual;
}
LLSD LLViewerInventoryCategory::exportLLSD() const
void LLViewerInventoryCategory::exportLLSD(LLSD & cat_data) const
{
LLSD cat_data = LLInventoryCategory::exportLLSD();
LLInventoryCategory::exportLLSD(cat_data);
cat_data[INV_OWNER_ID] = mOwnerID;
cat_data[INV_VERSION] = mVersion;
return cat_data;
}
bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)

View File

@ -232,8 +232,8 @@ public:
// How many descendents do we currently have information for in the InventoryModel?
S32 getViewerDescendentCount() const;
LLSD exportLLSD() const;
bool importLLSD(const LLSD& cat_data);
virtual void exportLLSD(LLSD &sd) const;
virtual bool importLLSD(const LLSD& cat_data);
void determineFolderType();
void changeType(LLFolderType::EType new_folder_type);