@@ -1530,7 +1530,7 @@ void StepHeaderField (int headerFieldLength)
1530
1530
inputIndex += headerIndex ;
1531
1531
}
1532
1532
1533
- unsafe bool StepHeaderValue ( byte * inbuf , ref bool midline )
1533
+ unsafe bool StepHeaderValue ( byte * inbuf , ref bool midline , ref bool detectedBareLinefeed )
1534
1534
{
1535
1535
byte * inptr = inbuf + inputIndex ;
1536
1536
byte * inend = inbuf + inputEnd ;
@@ -1595,6 +1595,9 @@ unsafe bool StepHeaderValue (byte* inbuf, ref bool midline)
1595
1595
break ;
1596
1596
}
1597
1597
1598
+ if ( index > 0 && * ( inptr - 1 ) != ( byte ) '\r ' )
1599
+ detectedBareLinefeed = true ;
1600
+
1598
1601
// Consume the newline and update our line number state.
1599
1602
inptr ++ ;
1600
1603
@@ -1619,12 +1622,13 @@ unsafe bool StepHeaderValue (byte* inbuf, ref bool midline)
1619
1622
return inptr < inend ;
1620
1623
}
1621
1624
1622
- bool IsEndOfHeaderBlock ( int left )
1625
+ bool IsEndOfHeaderBlock ( int left , ref bool detectedBareLinefeed )
1623
1626
{
1624
1627
if ( input [ inputIndex ] == ( byte ) '\n ' ) {
1625
1628
state = MimeParserState . Content ;
1626
1629
inputIndex ++ ;
1627
1630
IncrementLineNumber ( inputIndex ) ;
1631
+ detectedBareLinefeed = true ;
1628
1632
return true ;
1629
1633
}
1630
1634
@@ -1724,6 +1728,7 @@ Header CreateHeader (long beginOffset, int beginLineNumber, int fieldNameLength,
1724
1728
unsafe void StepHeaders ( byte * inbuf , CancellationToken cancellationToken )
1725
1729
{
1726
1730
int headersBeginLineNumber = lineNumber ;
1731
+ bool detectedBareLinefeed = false ;
1727
1732
var eof = false ;
1728
1733
1729
1734
headerBlockBegin = GetOffset ( inputIndex ) ;
@@ -1770,7 +1775,7 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1770
1775
}
1771
1776
1772
1777
// Check for an empty line denoting the end of the header block.
1773
- if ( IsEndOfHeaderBlock ( left ) ) {
1778
+ if ( IsEndOfHeaderBlock ( left , ref detectedBareLinefeed ) ) {
1774
1779
state = MimeParserState . Content ;
1775
1780
break ;
1776
1781
}
@@ -1843,8 +1848,8 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1843
1848
bool midline = true ;
1844
1849
1845
1850
// Consume the header value.
1846
- while ( ! StepHeaderValue ( inbuf , ref midline ) ) {
1847
- if ( ReadAhead ( 1 , 0 , cancellationToken ) == 0 ) {
1851
+ while ( ! StepHeaderValue ( inbuf , ref midline , ref detectedBareLinefeed ) ) {
1852
+ if ( ReadAhead ( 1 , 1 , cancellationToken ) == 0 ) {
1848
1853
if ( midline )
1849
1854
OnComplianceIssueEncountered ( MimeComplianceStatus . IncompleteHeader , beginOffset , beginLineNumber ) ;
1850
1855
else
@@ -1871,6 +1876,9 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1871
1876
Debugger . Break ( ) ;
1872
1877
#endif
1873
1878
1879
+ if ( detectedBareLinefeed )
1880
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInHeader , headerBlockBegin , headersBeginLineNumber ) ;
1881
+
1874
1882
headerBlockEnd = GetOffset ( inputIndex ) ;
1875
1883
1876
1884
OnHeadersEnd ( headerBlockBegin , headersBeginLineNumber , headerBlockEnd , lineNumber , cancellationToken ) ;
@@ -1889,6 +1897,9 @@ unsafe bool InnerSkipLine (byte* inbuf, bool consumeNewLine)
1889
1897
if ( inptr < inend ) {
1890
1898
inputIndex = ( int ) ( inptr - inbuf ) ;
1891
1899
1900
+ if ( input [ inputIndex - 1 ] != ( byte ) '\r ' )
1901
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , GetOffset ( inputIndex ) , lineNumber ) ;
1902
+
1892
1903
if ( consumeNewLine ) {
1893
1904
inputIndex ++ ;
1894
1905
IncrementLineNumber ( inputIndex ) ;
@@ -2236,6 +2247,9 @@ unsafe int ConstructMimePart (byte* inbuf, CancellationToken cancellationToken)
2236
2247
var result = ScanContent ( ScanContentType . MimeContent , inbuf , beginOffset , beginLineNumber , true , cancellationToken ) ;
2237
2248
OnMimePartContentEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , result . Format , cancellationToken ) ;
2238
2249
2250
+ if ( result . Format ! = NewLineFormat . Dos )
2251
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2252
+
2239
2253
return result . Lines ;
2240
2254
}
2241
2255
@@ -2326,6 +2340,9 @@ unsafe void MultipartScanPreamble (byte* inbuf, CancellationToken cancellationTo
2326
2340
OnMultipartPreambleBegin ( beginOffset , beginLineNumber , cancellationToken ) ;
2327
2341
var result = ScanContent ( ScanContentType . MultipartPreamble , inbuf , beginOffset , beginLineNumber , false , cancellationToken ) ;
2328
2342
OnMultipartPreambleEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , cancellationToken ) ;
2343
+
2344
+ if ( result . Format != NewLineFormat . Dos )
2345
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2329
2346
}
2330
2347
2331
2348
unsafe void MultipartScanEpilogue ( byte * inbuf , CancellationToken cancellationToken )
@@ -2336,6 +2353,9 @@ unsafe void MultipartScanEpilogue (byte* inbuf, CancellationToken cancellationTo
2336
2353
OnMultipartEpilogueBegin ( beginOffset , beginLineNumber , cancellationToken ) ;
2337
2354
var result = ScanContent ( ScanContentType . MultipartEpilogue , inbuf , beginOffset , beginLineNumber , true , cancellationToken ) ;
2338
2355
OnMultipartEpilogueEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , cancellationToken ) ;
2356
+
2357
+ if ( result . Format != NewLineFormat . Dos )
2358
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2339
2359
}
2340
2360
2341
2361
unsafe void MultipartScanSubparts ( ContentType multipartContentType , byte * inbuf , int depth , CancellationToken cancellationToken )
0 commit comments