Skip to content

Commit 15a7420

Browse files
committed
Optimize spf logic
1 parent 03c62fb commit 15a7420

File tree

3 files changed

+49
-25
lines changed

3 files changed

+49
-25
lines changed

src/Nager.EmailAuthentication.UnitTest/SpfRecordParserTest/FragmentParser/BasicTest.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public void Should_Parse_Spf_With_Include_And_All()
1919
Assert.IsNotNull(spfDataFragment.SpfTerms);
2020
Assert.AreEqual(2, spfDataFragment.SpfTerms.Length);
2121

22-
2322
if (spfDataFragment.SpfTerms[0] is ModifierBase spfModifier)
2423
{
2524
Assert.Fail("Wrong mapping, is not a modifier");
@@ -85,5 +84,17 @@ public void Should_Parse_Spf_With_Ip4_Uppercase()
8584
Assert.IsNotNull(spfDataFragment.SpfTerms);
8685
Assert.AreEqual(3, spfDataFragment.SpfTerms.Length);
8786
}
87+
88+
[TestMethod]
89+
public void Should_Parse_Spf_With_Includes_And_Space_At_The_End()
90+
{
91+
var spf = "v=spf1 include:spf.protection.outlook.com -all ";
92+
var isSuccessful = SpfRecordDataFragmentParserV1.TryParse(spf, out var spfDataFragment);
93+
94+
Assert.IsTrue(isSuccessful);
95+
Assert.IsNotNull(spfDataFragment);
96+
Assert.IsNotNull(spfDataFragment.SpfTerms);
97+
Assert.AreEqual(2, spfDataFragment.SpfTerms.Length);
98+
}
8899
}
89100
}

src/Nager.EmailAuthentication/FragmentParsers/SpfRecordDataFragmentParserV1.cs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ public static bool TryParse(
3737
var spfTerms = new List<SpfTerm>();
3838
var mechanismTypes = new Dictionary<string, Type>
3939
{
40-
{ AllMechanism.MechanismKey, typeof(AllMechanism) },
4140
{ Ip4Mechanism.MechanismKey, typeof(Ip4Mechanism) },
4241
{ Ip6Mechanism.MechanismKey, typeof(Ip6Mechanism) },
4342
{ IncludeMechanism.MechanismKey, typeof(IncludeMechanism) },
44-
{ ExistsMechanism.MechanismKey, typeof(ExistsMechanism) },
4543
{ AMechanism.MechanismKey, typeof(AMechanism) },
4644
{ MxMechanism.MechanismKey, typeof(MxMechanism) },
45+
{ ExistsMechanism.MechanismKey, typeof(ExistsMechanism) },
4746
{ PtrMechanism.MechanismKey, typeof(PtrMechanism) },
47+
{ AllMechanism.MechanismKey, typeof(AllMechanism) },
4848
};
4949

5050
var modifierTypes = new Dictionary<string, Type>
@@ -64,6 +64,7 @@ public static bool TryParse(
6464
termIndex++;
6565

6666
nextIndexOfDelimiter = inputSpan.IndexOf(spfTermDelimiter);
67+
6768
if (nextIndexOfDelimiter == 0)
6869
{
6970
inputSpan = inputSpan[1..];
@@ -80,6 +81,11 @@ public static bool TryParse(
8081
value = inputSpan[..nextIndexOfDelimiter].Trim();
8182
}
8283

84+
if (value.Length == 0)
85+
{
86+
continue;
87+
}
88+
8389
var qualifier = '+';
8490
var indexOfQualifier = Array.IndexOf(allowedQualifiers, value[0]);
8591
if (indexOfQualifier != -1)
@@ -88,15 +94,16 @@ public static bool TryParse(
8894
value = value[1..];
8995
}
9096

97+
var match = false;
98+
9199
foreach (var mechanismType in mechanismTypes)
92100
{
93101
if (!value.StartsWith(mechanismType.Key, StringComparison.OrdinalIgnoreCase))
94102
{
95103
continue;
96104
}
97105

98-
var term = Activator.CreateInstance(mechanismType.Value) as SpfTerm;
99-
if (term is null)
106+
if (Activator.CreateInstance(mechanismType.Value) is not SpfTerm term)
100107
{
101108
continue;
102109
}
@@ -114,39 +121,45 @@ public static bool TryParse(
114121
}
115122

116123
spfTerms.Add(spfMechanism);
124+
match = true;
117125
break;
118126
}
119127
}
120128

121-
foreach (var modifierType in modifierTypes)
129+
if (!match)
122130
{
123-
if (!value.StartsWith(modifierType.Key, StringComparison.OrdinalIgnoreCase))
131+
foreach (var modifierType in modifierTypes)
124132
{
125-
continue;
126-
}
133+
if (!value.StartsWith(modifierType.Key, StringComparison.OrdinalIgnoreCase))
134+
{
135+
continue;
136+
}
127137

128-
var term = Activator.CreateInstance(modifierType.Value) as SpfTerm;
129-
if (term is null)
130-
{
131-
continue;
132-
}
138+
if (Activator.CreateInstance(modifierType.Value) is not SpfTerm term)
139+
{
140+
continue;
141+
}
133142

134-
term.Index = termIndex;
143+
term.Index = termIndex;
135144

136-
if (term is ModifierBase spfModifier)
137-
{
138-
value = value[modifierType.Key.Length..];
139-
if (value.Length > 0)
145+
if (term is ModifierBase spfModifier)
140146
{
141-
spfModifier.GetDataPart(value);
147+
value = value[modifierType.Key.Length..];
148+
if (value.Length > 0)
149+
{
150+
spfModifier.GetDataPart(value);
151+
}
152+
153+
spfTerms.Add(spfModifier);
154+
break;
142155
}
143-
144-
spfTerms.Add(spfModifier);
145-
break;
146156
}
147157
}
148158

149-
//Failure found no match
159+
if (!match)
160+
{
161+
//Failure found no match
162+
}
150163

151164
inputSpan = inputSpan[(nextIndexOfDelimiter + 1)..];
152165
}

src/Nager.EmailAuthentication/Nager.EmailAuthentication.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
2222

23-
<Version>4.0.1</Version>
23+
<Version>4.0.2</Version>
2424
</PropertyGroup>
2525

2626
<ItemGroup>

0 commit comments

Comments
 (0)