Skip to content

Commit 12a218b

Browse files
committed
Protect against empty requested paths.
1 parent f6bac93 commit 12a218b

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

Penumbra/Interop/Hooks/ResourceLoading/ResourceService.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Dalamud.Hooking;
2+
using Dalamud.Interface.Windowing;
23
using Dalamud.Plugin.Services;
34
using Dalamud.Utility.Signatures;
45
using FFXIVClientStructs.FFXIV.Client.System.Resource;
@@ -85,7 +86,8 @@ public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref R
8586
ResourceType* pResourceType, int* pResourceHash, byte* pPath, GetResourceParameters* pGetResParams, nint unk7, uint unk8);
8687

8788
private delegate ResourceHandle* GetResourceAsyncPrototype(ResourceManager* resourceManager, ResourceCategory* pCategoryId,
88-
ResourceType* pResourceType, int* pResourceHash, byte* pPath, GetResourceParameters* pGetResParams, byte isUnknown, nint unk8, uint unk9);
89+
ResourceType* pResourceType, int* pResourceHash, byte* pPath, GetResourceParameters* pGetResParams, byte isUnknown, nint unk8,
90+
uint unk9);
8991

9092
[Signature(Sigs.GetResourceSync, DetourName = nameof(GetResourceSyncDetour))]
9193
private readonly Hook<GetResourceSyncPrototype> _getResourceSyncHook = null!;
@@ -118,18 +120,26 @@ public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref R
118120
unk9);
119121
}
120122

121-
var original = gamePath;
123+
if (gamePath.IsEmpty)
124+
{
125+
Penumbra.Log.Error($"[ResourceService] Empty resource path requested with category {*categoryId}, type {*resourceType}, hash {*resourceHash}.");
126+
return null;
127+
}
128+
129+
var original = gamePath;
122130
ResourceHandle* returnValue = null;
123131
ResourceRequested?.Invoke(ref *categoryId, ref *resourceType, ref *resourceHash, ref gamePath, original, pGetResParams, ref isSync,
124132
ref returnValue);
125133
if (returnValue != null)
126134
return returnValue;
127135

128-
return GetOriginalResource(isSync, *categoryId, *resourceType, *resourceHash, gamePath.Path, original, pGetResParams, isUnk, unk8, unk9);
136+
return GetOriginalResource(isSync, *categoryId, *resourceType, *resourceHash, gamePath.Path, original, pGetResParams, isUnk, unk8,
137+
unk9);
129138
}
130139

131140
/// <summary> Call the original GetResource function. </summary>
132-
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, CiByteString path, Utf8GamePath original,
141+
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, CiByteString path,
142+
Utf8GamePath original,
133143
GetResourceParameters* resourceParameters = null, byte unk = 0, nint unk8 = 0, uint unk9 = 0)
134144
{
135145
var previous = _currentGetResourcePath.Value;
@@ -141,7 +151,8 @@ public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref R
141151
resourceParameters, unk8, unk9)
142152
: _getResourceAsyncHook.OriginalDisposeSafe(_resourceManager.ResourceManager, &categoryId, &type, &hash, path.Path,
143153
resourceParameters, unk, unk8, unk9);
144-
} finally
154+
}
155+
finally
145156
{
146157
_currentGetResourcePath.Value = previous;
147158
}
@@ -163,7 +174,8 @@ public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref R
163174
/// <param name="syncOriginal">The original game path of the resource, if loaded synchronously.</param>
164175
/// <param name="previousState">The previous state of the resource.</param>
165176
/// <param name="returnValue">The return value to use.</param>
166-
public delegate void ResourceStateUpdatedDelegate(ResourceHandle* handle, Utf8GamePath syncOriginal, (byte UnkState, LoadState LoadState) previousState, ref uint returnValue);
177+
public delegate void ResourceStateUpdatedDelegate(ResourceHandle* handle, Utf8GamePath syncOriginal,
178+
(byte UnkState, LoadState LoadState) previousState, ref uint returnValue);
167179

168180
/// <summary>
169181
/// <inheritdoc cref="ResourceStateUpdatingDelegate"/> <para/>
@@ -185,7 +197,7 @@ public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref R
185197
private uint UpdateResourceStateDetour(ResourceHandle* handle, byte offFileThread)
186198
{
187199
var previousState = (handle->UnkState, handle->LoadState);
188-
var syncOriginal = _currentGetResourcePath.IsValueCreated ? _currentGetResourcePath.Value : Utf8GamePath.Empty;
200+
var syncOriginal = _currentGetResourcePath.IsValueCreated ? _currentGetResourcePath.Value : Utf8GamePath.Empty;
189201
ResourceStateUpdating?.Invoke(handle, syncOriginal);
190202
var ret = _updateResourceStateHook.OriginalDisposeSafe(handle, offFileThread);
191203
ResourceStateUpdated?.Invoke(handle, syncOriginal, previousState, ref ret);

0 commit comments

Comments
 (0)