don't cache invalid offsets unless brute forced

don't cache objects parsed if their offset doesn't match the cross-reference offset, unless the object was parsed by a brute-force search operation. this is because 1 object may lie in 2 streams, 1 valid and 1 invalid. If the invalid stream is parsed first for another object then the valid stream will never be read.
This commit is contained in:
Eliot Jones
2020-01-07 14:54:12 +00:00
parent 903d71a93d
commit 10dc5a8eed
3 changed files with 9 additions and 11 deletions

View File

@@ -15,7 +15,7 @@
bool TryGetCached(IndirectReference reference, out ObjectToken objectToken);
void Cache(ObjectToken objectToken);
void Cache(ObjectToken objectToken, bool force = false);
}
internal class ObjectLocationProvider : IObjectLocationProvider
@@ -83,21 +83,19 @@
return cache.TryGetValue(reference, out objectToken);
}
public void Cache(ObjectToken objectToken)
public void Cache(ObjectToken objectToken, bool force = false)
{
if (objectToken == null)
{
throw new ArgumentNullException();
}
if (cache.TryGetValue(objectToken.Number, out var existing))
// Don't cache incorrect locations.
var crossReference = crossReferenceTable();
if (!force && crossReference != null && crossReference.ObjectOffsets.TryGetValue(objectToken.Number, out var expected)
&& objectToken.Position != expected)
{
var crossReference = crossReferenceTable();
if (crossReference != null && crossReference.ObjectOffsets.TryGetValue(objectToken.Number, out var expected)
&& existing.Position == expected)
{
return;
}
return;
}
cache[objectToken.Number] = objectToken;

View File

@@ -671,7 +671,7 @@
while (MoveNext())
{
objectLocationProvider.Cache((ObjectToken)CurrentToken);
objectLocationProvider.Cache((ObjectToken)CurrentToken, true);
}
if (!objectLocationProvider.TryGetCached(reference, out objectToken))