@@ -1525,7 +1525,7 @@ void StepHeaderField (int headerFieldLength)
1525
1525
inputIndex += headerIndex ;
1526
1526
}
1527
1527
1528
- unsafe bool StepHeaderValue ( byte * inbuf , ref bool midline )
1528
+ unsafe bool StepHeaderValue ( byte * inbuf , ref bool midline , ref bool detectedBareLinefeed )
1529
1529
{
1530
1530
byte * inptr = inbuf + inputIndex ;
1531
1531
byte * inend = inbuf + inputEnd ;
@@ -1545,6 +1545,9 @@ unsafe bool StepHeaderValue (byte* inbuf, ref bool midline)
1545
1545
break ;
1546
1546
}
1547
1547
1548
+ if ( index > 0 && * ( inptr - 1 ) != ( byte ) '\r ' )
1549
+ detectedBareLinefeed = true ;
1550
+
1548
1551
// Consume the newline and update our line number state.
1549
1552
inptr ++ ;
1550
1553
@@ -1569,12 +1572,13 @@ unsafe bool StepHeaderValue (byte* inbuf, ref bool midline)
1569
1572
return inptr < inend ;
1570
1573
}
1571
1574
1572
- bool IsEndOfHeaderBlock ( int left )
1575
+ bool IsEndOfHeaderBlock ( int left , ref bool detectedBareLinefeed )
1573
1576
{
1574
1577
if ( input [ inputIndex ] == ( byte ) '\n ' ) {
1575
1578
state = MimeParserState . Content ;
1576
1579
inputIndex ++ ;
1577
1580
IncrementLineNumber ( inputIndex ) ;
1581
+ detectedBareLinefeed = true ;
1578
1582
return true ;
1579
1583
}
1580
1584
@@ -1675,6 +1679,7 @@ Header CreateHeader (long beginOffset, int beginLineNumber, int fieldNameLength,
1675
1679
unsafe void StepHeaders ( byte * inbuf , CancellationToken cancellationToken )
1676
1680
{
1677
1681
int headersBeginLineNumber = lineNumber ;
1682
+ bool detectedBareLinefeed = false ;
1678
1683
var eof = false ;
1679
1684
1680
1685
headerBlockBegin = GetOffset ( inputIndex ) ;
@@ -1721,7 +1726,7 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1721
1726
}
1722
1727
1723
1728
// Check for an empty line denoting the end of the header block.
1724
- if ( IsEndOfHeaderBlock ( left ) ) {
1729
+ if ( IsEndOfHeaderBlock ( left , ref detectedBareLinefeed ) ) {
1725
1730
state = MimeParserState . Content ;
1726
1731
break ;
1727
1732
}
@@ -1794,8 +1799,8 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1794
1799
bool midline = true ;
1795
1800
1796
1801
// Consume the header value.
1797
- while ( ! StepHeaderValue ( inbuf , ref midline ) ) {
1798
- if ( ReadAhead ( 1 , 0 , cancellationToken ) == 0 ) {
1802
+ while ( ! StepHeaderValue ( inbuf , ref midline , ref detectedBareLinefeed ) ) {
1803
+ if ( ReadAhead ( 1 , 1 , cancellationToken ) == 0 ) {
1799
1804
if ( midline )
1800
1805
OnComplianceIssueEncountered ( MimeComplianceStatus . IncompleteHeader , beginOffset , beginLineNumber ) ;
1801
1806
else
@@ -1822,6 +1827,9 @@ unsafe void StepHeaders (byte* inbuf, CancellationToken cancellationToken)
1822
1827
Debugger . Break ( ) ;
1823
1828
#endif
1824
1829
1830
+ if ( detectedBareLinefeed )
1831
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInHeader , headerBlockBegin , headersBeginLineNumber ) ;
1832
+
1825
1833
headerBlockEnd = GetOffset ( inputIndex ) ;
1826
1834
1827
1835
OnHeadersEnd ( headerBlockBegin , headersBeginLineNumber , headerBlockEnd , lineNumber , cancellationToken ) ;
@@ -1841,6 +1849,9 @@ unsafe bool InnerSkipLine (byte* inbuf, bool consumeNewLine)
1841
1849
if ( inptr < inend ) {
1842
1850
inputIndex = ( int ) ( inptr - inbuf ) ;
1843
1851
1852
+ if ( input [ inputIndex - 1 ] != ( byte ) '\r ' )
1853
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , GetOffset ( inputIndex ) , lineNumber ) ;
1854
+
1844
1855
if ( consumeNewLine ) {
1845
1856
inputIndex ++ ;
1846
1857
IncrementLineNumber ( inputIndex ) ;
@@ -2189,6 +2200,9 @@ unsafe int ConstructMimePart (byte* inbuf, CancellationToken cancellationToken)
2189
2200
var result = ScanContent ( ScanContentType . MimeContent , inbuf , beginOffset , beginLineNumber , true , cancellationToken ) ;
2190
2201
OnMimePartContentEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , result . Format , cancellationToken ) ;
2191
2202
2203
+ if ( result . Format ! = NewLineFormat . Dos )
2204
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2205
+
2192
2206
return result . Lines ;
2193
2207
}
2194
2208
@@ -2280,6 +2294,9 @@ unsafe void MultipartScanPreamble (byte* inbuf, CancellationToken cancellationTo
2280
2294
OnMultipartPreambleBegin ( beginOffset , beginLineNumber , cancellationToken ) ;
2281
2295
var result = ScanContent ( ScanContentType . MultipartPreamble , inbuf , beginOffset , beginLineNumber , false , cancellationToken ) ;
2282
2296
OnMultipartPreambleEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , cancellationToken ) ;
2297
+
2298
+ if ( result . Format != NewLineFormat . Dos )
2299
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2283
2300
}
2284
2301
2285
2302
unsafe void MultipartScanEpilogue ( byte * inbuf , CancellationToken cancellationToken )
@@ -2290,6 +2307,9 @@ unsafe void MultipartScanEpilogue (byte* inbuf, CancellationToken cancellationTo
2290
2307
OnMultipartEpilogueBegin ( beginOffset , beginLineNumber , cancellationToken ) ;
2291
2308
var result = ScanContent ( ScanContentType . MultipartEpilogue , inbuf , beginOffset , beginLineNumber , true , cancellationToken ) ;
2292
2309
OnMultipartEpilogueEnd ( beginOffset , beginLineNumber , beginOffset + result . ContentLength , result . Lines , cancellationToken ) ;
2310
+
2311
+ if ( result . Format != NewLineFormat . Dos )
2312
+ OnComplianceIssueEncountered ( MimeComplianceStatus . BareLinefeedInBody , beginOffset , beginLineNumber ) ;
2293
2313
}
2294
2314
2295
2315
unsafe void MultipartScanSubparts ( ContentType multipartContentType , byte * inbuf , int depth , CancellationToken cancellationToken )
0 commit comments