Skip to content

Commit

Permalink
Merge pull request #288 from Mutagen-Modding/287-overflow-records-not…
Browse files Browse the repository at this point in the history
…-handled-in-modheaders

Fixes and tests for subrecord length overflow in mod headers
  • Loading branch information
Noggog committed Apr 22, 2022
2 parents c1bfb31 + 00e7c6c commit 571c1b3
Show file tree
Hide file tree
Showing 81 changed files with 272 additions and 253 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Mutagen.Bethesda.Plugins;
using Mutagen.Bethesda.Plugins.Binary.Headers;
using Mutagen.Bethesda.Plugins.Meta;
using Mutagen.Bethesda.Strings.DI;
using Mutagen.Bethesda.Testing;
using Mutagen.Bethesda.UnitTests.Placeholders;
using Xunit;
Expand Down Expand Up @@ -116,9 +117,9 @@ public void EnumerateSubrecordsDirectWithOverflow()
}

[Fact]
public void ModHeaderOverflow()
public void ModHeaderFrameOverflow()
{
byte[] b = TestDataPathing.GetBytes("Plugins/Binary/Headers/ModHeaderOverflow");
byte[] b = TestDataPathing.GetBytes(TestDataPathing.HeaderOverflow);
var modHeader = new ModHeaderFrame(GameConstants.SkyrimSE, b);
var recs = modHeader.ToList();
recs.Should().HaveCount(3);
Expand All @@ -130,4 +131,13 @@ public void ModHeaderOverflow()
recs[2].ContentLength.Should().Be(0x04);
recs[2].AsInt32().Should().Be(0x04030201);
}

[Fact]
public void MastersEnumerationWithOverflow()
{
byte[] b = TestDataPathing.GetBytes(TestDataPathing.HeaderOverflow);
var modHeader = new ModHeaderFrame(GameConstants.SkyrimSE, b);
modHeader.Masters().Select(x => x.AsString(MutagenEncodingProvider._1252))
.Should().Equal("Dawnguard.esm");
}
}
4 changes: 2 additions & 2 deletions Mutagen.Bethesda.Core/Plugins/Binary/Headers/HeaderExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,9 @@ public static IEnumerable<SubrecordPinFrame> EnumerateSubrecords(this ModHeaderF
return EnumerateSubrecords(modHeader.HeaderAndContentData, modHeader.Meta, modHeader.HeaderLength, lengthOverflowTypes ?? _headerOverflow);
}

public static IEnumerable<SubrecordPinFrame> Masters(this ModHeaderFrame modHeader)
public static IEnumerable<SubrecordPinFrame> Masters(this ModHeaderFrame modHeader, ICollection<RecordType>? lengthOverflowTypes = null)
{
foreach (var pin in EnumerateSubrecords(modHeader, lengthOverflowTypes: Array.Empty<RecordType>()))
foreach (var pin in EnumerateSubrecords(modHeader, lengthOverflowTypes: lengthOverflowTypes ?? _headerOverflow))
{
if (pin.RecordType == RecordTypes.MAST)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,15 @@ internal abstract class PluginBinaryOverlay : ILoquiObject
{
SubrecordHeader subMeta = stream.GetSubrecord();
lastParsedType = subMeta.RecordType;
var minimumFinalPos = stream.Position + subMeta.TotalLength;
var minimumFinalPos = stream.Position;
if (lastParsed.LengthOverride.HasValue)
{
minimumFinalPos += lastParsed.LengthOverride.Value + subMeta.HeaderLength;
}
else
{
minimumFinalPos += subMeta.TotalLength;
}
var parsed = fill(
stream: stream,
finalPos: minimumFinalPos,
Expand Down Expand Up @@ -262,7 +270,7 @@ internal abstract class PluginBinaryOverlay : ILoquiObject
var minimumFinalPos = stream.Position + subMeta.TotalLength;
var parsed = fill(
stream: stream,
finalPos: finalPos,
finalPos: minimumFinalPos,
offset: offset,
recordParseCount: recordParseCount,
type: subMeta.RecordType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public static class PluginUtilityTranslation
lastParsed: previousParse,
recordParseCount: recordParseCount,
nextRecordType: subMeta.RecordType,
contentLength: subMeta.ContentLength,
contentLength: previousParse.LengthOverride ?? subMeta.ContentLength,
translationParams: translationParams);
if (!parsed.KeepParsing) break;
if (parsed.DuplicateParseMarker != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ internal partial class BoneBinaryOverlay :
{
if (lastParsed.ParsedIndex.HasValue && lastParsed.ParsedIndex.Value >= (int)Bone_FieldIndex.Values) return ParseResult.Stop;
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Values = BinaryOverlayList.FactoryByStartIndex<Single>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ internal partial class DestructibleBinaryOverlay :
{
if (lastParsed.ParsedIndex.HasValue && lastParsed.ParsedIndex.Value >= (int)Destructible_FieldIndex.Resistances) return ParseResult.Stop;
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Resistances = BinaryOverlayList.FactoryByStartIndex<ResistanceDestructibleBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
11 changes: 1 addition & 10 deletions Mutagen.Bethesda.Fallout4/Records/Fallout4ModHeader_Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2681,16 +2681,7 @@ internal partial class Fallout4ModHeaderBinaryOverlay :
case RecordTypeInts.ONAM:
{
var subMeta = stream.ReadSubrecord();
int subLen;
if (subMeta.RecordType == RecordTypes.XXXX)
{
subLen = checked((int)stream.ReadUInt32());
stream.ReadSubrecord();
}
else
{
subLen = subMeta.ContentLength;
}
var subLen = finalPos - stream.Position;
this.OverriddenForms = BinaryOverlayList.FactoryByStartIndex<IFormLinkGetter<IFallout4MajorRecordGetter>>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3902,7 +3902,7 @@ internal partial class ActivatorBinaryOverlay :
case RecordTypeInts.PRPS:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Properties = BinaryOverlayList.FactoryByStartIndex<ObjectPropertyBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4809,7 +4809,7 @@ internal partial class ArmorBinaryOverlay :
case RecordTypeInts.DAMA:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Resistances = BinaryOverlayList.FactoryByStartIndex<ArmorResistanceBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand All @@ -4826,7 +4826,7 @@ internal partial class ArmorBinaryOverlay :
case RecordTypeInts.APPR:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.AttachParentSlots = BinaryOverlayList.FactoryByStartIndex<IFormLinkGetter<IKeywordGetter>>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2107,7 +2107,7 @@ internal partial class ClassBinaryOverlay :
case RecordTypeInts.PRPS:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Properties = BinaryOverlayList.FactoryByStartIndex<ObjectPropertyBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2404,7 +2404,7 @@ internal partial class ClimateBinaryOverlay :
case RecordTypeInts.WLST:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Weathers = BinaryOverlayList.FactoryByStartIndex<WeatherTypeBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3565,7 +3565,7 @@ internal partial class ContainerBinaryOverlay :
case RecordTypeInts.PRPS:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Properties = BinaryOverlayList.FactoryByStartIndex<ObjectPropertyBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,7 @@ internal partial class DamageTypeIndexedBinaryOverlay :
case RecordTypeInts.DNAM:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.DamageTypes = BinaryOverlayList.FactoryByStartIndex<UInt32>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,7 @@ internal partial class DamageTypeBinaryOverlay :
case RecordTypeInts.DNAM:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.DamageTypes = BinaryOverlayList.FactoryByStartIndex<IFormLinkGetter<IDamageTypeTargetGetter>>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3142,7 +3142,7 @@ internal partial class FloraBinaryOverlay :
case RecordTypeInts.PRPS:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Properties = BinaryOverlayList.FactoryByStartIndex<ObjectPropertyBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5059,7 +5059,7 @@ internal partial class FurnitureBinaryOverlay :
case RecordTypeInts.PRPS:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.Properties = BinaryOverlayList.FactoryByStartIndex<ObjectPropertyBinaryOverlay>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down Expand Up @@ -5187,7 +5187,7 @@ internal partial class FurnitureBinaryOverlay :
case RecordTypeInts.APPR:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.AttachParentSlots = BinaryOverlayList.FactoryByStartIndex<IFormLinkGetter<IKeywordGetter>>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2420,7 +2420,7 @@ internal partial class IdleAnimationBinaryOverlay :
case RecordTypeInts.ANAM:
{
var subMeta = stream.ReadSubrecord();
var subLen = subMeta.ContentLength;
var subLen = finalPos - stream.Position;
this.RelatedIdles = BinaryOverlayList.FactoryByStartIndex<IFormLinkGetter<IIdleRelationGetter>>(
mem: stream.RemainingMemory.Slice(0, subLen),
package: _package,
Expand Down

0 comments on commit 571c1b3

Please sign in to comment.