Crash when loading IoStore container from install-time GooglePAD pack

Hi!

In our game we have custom downloadable content system based on pak files. Recently I was upgrading it to use IoStore. When we tried to put IoStore containers into install-time GooglePAD pack we’ve got crash

FFileHandleAndroid::Seek (AndroidPlatformFile.cpp:297) FCachedFileHandle::InnerSeek (IPlatformFileCachedWrapper.h:208) FCachedFileHandle::Read (IPlatformFileCachedWrapper.h:108) FIoStoreTocResource::Read (IoStore.cpp:2931) FFileIoStoreReader::Initialize (IoDispatcherFileBackend.cpp:678) FFileIoStore::Mount (IoDispatcherFileBackend.cpp:1278) FPakPlatformFile::Mount (IPlatformFilePak.cpp:7900) FPakPlatformFile::HandleMountPakDelegate (IPlatformFilePak.cpp:8204)I’ve investigated it and found that it occurs because when FFileHandleAndroid is created from an AAsset with non-zero offset (which appears to be the case for files in install-time packs) its CurrentOffset is initialized to 0 (despite actually being non-zero). And if FFileHandleAndroid is wrapped into FCachedFileHandle initial value of FCachedFileHandle::FilePos is calculated using the value of CurrentOffset and ends up being negative. It’s then used to calculate AlignedFilePos in FCachedFileHandle::Read which ends up negative too triggering check in FFileHandleAndroid::Seek and then crash. I’ve fixed it by setting CurrentOffset to Start in constructor of FFileHandleAndroid from AAsset like this. Does it look like a valid solution?

FFileHandleAndroid(const FString & path, AAsset * asset) : File(MakeShareable(new FileReference(path, asset))) , Start(0), Length(0), CurrentOffset(0) { #if UE_ANDROID_FILE_64 && PLATFORM_32BITS File->Handle = AAsset_openFileDescriptor64(File->Asset, &Start, &Length); #else off_t OutStart = Start; off_t OutLength = Length; File->Handle = AAsset_openFileDescriptor(File->Asset, &OutStart, &OutLength); Start = OutStart; Length = OutLength; CurrentOffset = Start; #endif CheckValid(); LogInfo(); }

Yes, this is an error and your fix is correct; it is assumed CurrentOffset is an absolute position not relative to Start. Since UE5 no longer supports 32-bit I’m making this change for the next release:

FFileHandleAndroid(const FString & path, AAsset * asset) : File(MakeShareable(new FileReference(path, asset))) , Start(0), Length(0), CurrentOffset(0) { off64_t OutStart = Start; off64_t OutLength = Length; File->Handle = AAsset_openFileDescriptor64(File->Asset, &OutStart, &OutLength); CurrentOffset = Start = OutStart; Length = OutLength; CheckValid(); LogInfo(); }Note compressed assets are first decompressed and Start would be zero which is likely why it wasn’t noticed earlier.