// virtual BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) { // *NOTE: Changing the buffer size will require changing the scanf // calls below. char buffer[MAX_STRING]; /* Flawfinder: ignore */ char keyword[MAX_STRING]; /* Flawfinder: ignore */ char valuestr[MAX_STRING]; /* Flawfinder: ignore */ char junk[MAX_STRING]; /* Flawfinder: ignore */ BOOL success = TRUE; keyword[0] = '\0'; valuestr[0] = '\0'; mInventoryType = LLInventoryType::IT_NONE; mAssetUUID.setNull(); while(success && input_stream.good()) { input_stream.getline(buffer, MAX_STRING); sscanf( /* Flawfinder: ignore */ buffer, " %254s %254s", keyword, valuestr); if(0 == strcmp("{",keyword)) { continue; } if(0 == strcmp("}", keyword)) { break; } else if(0 == strcmp("item_id", keyword)) { mUUID.set(valuestr); } else if(0 == strcmp("parent_id", keyword)) { mParentUUID.set(valuestr); } else if(0 == strcmp("permissions", keyword)) { success = mPermissions.importLegacyStream(input_stream); } else if(0 == strcmp("sale_info", keyword)) { // Sale info used to contain next owner perm. It is now in // the permissions. Thus, we read that out, and fix legacy // objects. It's possible this op would fail, but it // should pick up the vast majority of the tasks. BOOL has_perm_mask = FALSE; U32 perm_mask = 0; success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask); if(has_perm_mask) { if(perm_mask == PERM_NONE) { perm_mask = mPermissions.getMaskOwner(); } // fair use fix. if(!(perm_mask & PERM_COPY)) { perm_mask |= PERM_TRANSFER; } mPermissions.setMaskNext(perm_mask); } } else if(0 == strcmp("shadow_id", keyword)) { mAssetUUID.set(valuestr); LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); cipher.decrypt(mAssetUUID.mData, UUID_BYTES); } else if(0 == strcmp("asset_id", keyword)) { mAssetUUID.set(valuestr); } else if(0 == strcmp("type", keyword)) { mType = LLAssetType::lookup(valuestr); } else if(0 == strcmp("inv_type", keyword)) { mInventoryType = LLInventoryType::lookup(std::string(valuestr)); } else if(0 == strcmp("flags", keyword)) { sscanf(valuestr, "%x", &mFlags); } else if(0 == strcmp("name", keyword)) { //strcpy(valuestr, buffer + strlen(keyword) + 3); // *NOTE: Not ANSI C, but widely supported. sscanf( /* Flawfinder: ignore */ buffer, " %254s%254[\t]%254[^|]", keyword, junk, valuestr); // IW: sscanf chokes and puts | in valuestr if there's no name if (valuestr[0] == '|') { valuestr[0] = '\000'; } mName.assign(valuestr); LLStringUtil::replaceNonstandardASCII(mName, ' '); LLStringUtil::replaceChar(mName, '|', ' '); } else if(0 == strcmp("desc", keyword)) { //strcpy(valuestr, buffer + strlen(keyword) + 3); // *NOTE: Not ANSI C, but widely supported. sscanf( /* Flawfinder: ignore */ buffer, " %254s%254[\t]%254[^|]", keyword, junk, valuestr); if (valuestr[0] == '|') { valuestr[0] = '\000'; } mDescription.assign(valuestr); LLStringUtil::replaceNonstandardASCII(mDescription, ' '); /* TODO -- ask Ian about this code const char *donkey = mDescription.c_str(); if (donkey[0] == '|') { llerrs << "Donkey" << llendl; } */ } else if(0 == strcmp("creation_date", keyword)) { S32 date; sscanf(valuestr, "%d", &date); mCreationDate = date; } else { llwarns << "unknown keyword '" << keyword << "' in inventory import of item " << mUUID << llendl; } } // Need to convert 1.0 simstate files to a useful inventory type // and potentially deal with bad inventory tyes eg, a landmark // marked as a texture. if((LLInventoryType::IT_NONE == mInventoryType) || !inventory_and_asset_types_match(mInventoryType, mType)) { lldebugs << "Resetting inventory type for " << mUUID << llendl; mInventoryType = LLInventoryType::defaultForAssetType(mType); } return success; }
bool LLInventoryItem::fromLLSD(LLSD& sd) { mInventoryType = LLInventoryType::IT_NONE; mAssetUUID.setNull(); std::string w; w = INV_ITEM_ID_LABEL; if (sd.has(w)) { mUUID = sd[w]; } w = INV_PARENT_ID_LABEL; if (sd.has(w)) { mParentUUID = sd[w]; } w = INV_PERMISSIONS_LABEL; if (sd.has(w)) { mPermissions = ll_permissions_from_sd(sd[w]); } w = INV_SALE_INFO_LABEL; if (sd.has(w)) { // Sale info used to contain next owner perm. It is now in // the permissions. Thus, we read that out, and fix legacy // objects. It's possible this op would fail, but it // should pick up the vast majority of the tasks. BOOL has_perm_mask = FALSE; U32 perm_mask = 0; if (!mSaleInfo.fromLLSD(sd[w], has_perm_mask, perm_mask)) { goto fail; } if (has_perm_mask) { if(perm_mask == PERM_NONE) { perm_mask = mPermissions.getMaskOwner(); } // fair use fix. if(!(perm_mask & PERM_COPY)) { perm_mask |= PERM_TRANSFER; } mPermissions.setMaskNext(perm_mask); } } w = INV_SHADOW_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); cipher.decrypt(mAssetUUID.mData, UUID_BYTES); } w = INV_ASSET_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; } w = INV_ASSET_TYPE_LABEL; if (sd.has(w)) { if (sd[w].isString()) { mType = LLAssetType::lookup(sd[w].asString().c_str()); } else if (sd[w].isInteger()) { S8 type = (U8)sd[w].asInteger(); mType = static_cast<LLAssetType::EType>(type); } } w = INV_INVENTORY_TYPE_LABEL; if (sd.has(w)) { if (sd[w].isString()) { mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str()); } else if (sd[w].isInteger()) { S8 type = (U8)sd[w].asInteger(); mInventoryType = static_cast<LLInventoryType::EType>(type); } } w = INV_FLAGS_LABEL; if (sd.has(w)) { if (sd[w].isBinary()) { mFlags = ll_U32_from_sd(sd[w]); } else if(sd[w].isInteger()) { mFlags = sd[w].asInteger(); } } w = INV_NAME_LABEL; if (sd.has(w)) { mName = sd[w].asString(); LLStringUtil::replaceNonstandardASCII(mName, ' '); LLStringUtil::replaceChar(mName, '|', ' '); } w = INV_DESC_LABEL; if (sd.has(w)) { mDescription = sd[w].asString(); LLStringUtil::replaceNonstandardASCII(mDescription, ' '); } w = INV_CREATION_DATE_LABEL; if (sd.has(w)) { mCreationDate = sd[w].asInteger(); } // Need to convert 1.0 simstate files to a useful inventory type // and potentially deal with bad inventory tyes eg, a landmark // marked as a texture. if((LLInventoryType::IT_NONE == mInventoryType) || !inventory_and_asset_types_match(mInventoryType, mType)) { lldebugs << "Resetting inventory type for " << mUUID << llendl; mInventoryType = LLInventoryType::defaultForAssetType(mType); } return true; fail: return false; }
bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) { LL_RECORD_BLOCK_TIME(FTM_INVENTORY_SD_DESERIALIZE); if (is_new) { // If we're adding LLSD to an existing object, need avoid // clobbering these fields. mInventoryType = LLInventoryType::IT_NONE; mAssetUUID.setNull(); } std::string w; w = INV_ITEM_ID_LABEL; if (sd.has(w)) { mUUID = sd[w]; } w = INV_PARENT_ID_LABEL; if (sd.has(w)) { mParentUUID = sd[w]; } w = INV_PERMISSIONS_LABEL; if (sd.has(w)) { mPermissions = ll_permissions_from_sd(sd[w]); } w = INV_SALE_INFO_LABEL; if (sd.has(w)) { // Sale info used to contain next owner perm. It is now in // the permissions. Thus, we read that out, and fix legacy // objects. It's possible this op would fail, but it // should pick up the vast majority of the tasks. BOOL has_perm_mask = FALSE; U32 perm_mask = 0; if (!mSaleInfo.fromLLSD(sd[w], has_perm_mask, perm_mask)) { goto fail; } if (has_perm_mask) { if(perm_mask == PERM_NONE) { perm_mask = mPermissions.getMaskOwner(); } // fair use fix. if(!(perm_mask & PERM_COPY)) { perm_mask |= PERM_TRANSFER; } mPermissions.setMaskNext(perm_mask); } } w = INV_SHADOW_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); cipher.decrypt(mAssetUUID.mData, UUID_BYTES); } w = INV_ASSET_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; } w = INV_LINKED_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; } w = INV_ASSET_TYPE_LABEL; if (sd.has(w)) { if (sd[w].isString()) { mType = LLAssetType::lookup(sd[w].asString().c_str()); } else if (sd[w].isInteger()) { S8 type = (U8)sd[w].asInteger(); mType = static_cast<LLAssetType::EType>(type); } } w = INV_INVENTORY_TYPE_LABEL; if (sd.has(w)) { if (sd[w].isString()) { mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str()); } else if (sd[w].isInteger()) { S8 type = (U8)sd[w].asInteger(); mInventoryType = static_cast<LLInventoryType::EType>(type); } } w = INV_FLAGS_LABEL; if (sd.has(w)) { if (sd[w].isBinary()) { mFlags = ll_U32_from_sd(sd[w]); } else if(sd[w].isInteger()) { mFlags = sd[w].asInteger(); } //<singu> // Define a few magic constants that are not accessible otherwise, from here. // mInventoryType: static U32 IT_WEARABLE = 18; // LLInventoryType::IT_WEARABLE // mType, these are the two asset types that are IT_WEARABLE: static U32 AT_BODYPART = 13; // LLAssetType::AT_BODYPART // Viewer local values: static U32 WT_UNKNOWN = 16; // LLWearableType::WT_UNKNOWN static U32 WT_COUNT = 17; // LLWearableType::WT_COUNT // The last 8 bits of mFlags contain the wearable type. static U32 II_FLAGS_WEARABLES_MASK = 0xff; // LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK // The wearable type is stored in the lower 8 bits of mFlags. U32 wt = mFlags & II_FLAGS_WEARABLES_MASK; // Because WT_UNKNOWN now has locally a special meaning, make sure we don't receive it from the server. if (wt == WT_UNKNOWN) { LL_DEBUGS() << "Received inventory item with wearable type WT_UNKNOWN from server!" << LL_ENDL; // Change this new wearable type to WT_COUNT, as if when we had not inserted WT_UNKNOWN locally. mFlags += 1; wt = WT_COUNT; } // Detect possible problematic items. if (wt == 0 && mInventoryType == IT_WEARABLE && mType != AT_BODYPART) { // This is not possible, and therefore is probably an item creatd by a pre-multiwear viewer (or Second Inventory, etc). // The wearable type is NOT a shape (0) in that case of course, but we don't know what it is without downloading the // asset. mFlags |= WT_UNKNOWN; } //</singu> } w = INV_NAME_LABEL; if (sd.has(w)) { mName = sd[w].asString(); LLStringUtil::replaceNonstandardASCII(mName, ' '); LLStringUtil::replaceChar(mName, '|', ' '); } w = INV_DESC_LABEL; if (sd.has(w)) { mDescription = sd[w].asString(); LLStringUtil::replaceNonstandardASCII(mDescription, ' '); } w = INV_CREATION_DATE_LABEL; if (sd.has(w)) { mCreationDate = sd[w].asInteger(); } // Need to convert 1.0 simstate files to a useful inventory type // and potentially deal with bad inventory tyes eg, a landmark // marked as a texture. if((LLInventoryType::IT_NONE == mInventoryType) || !inventory_and_asset_types_match(mInventoryType, mType)) { LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL; mInventoryType = LLInventoryType::defaultForAssetType(mType); } mPermissions.initMasks(mInventoryType); return true; fail: return false; }