Skip to content

Commit 567ac2f

Browse files
authored
Add Exception Handling Around More Recursive Extractor Calls (#599)
* Add Catch around Recursive Extractor calls Was able to reproduce overflow exceptions thrown here causing end to execution, I think this is potentially the same root cause of issue #598's report of null streams causing a crash as well. * Fix Capitalization * Clamp GetLocation to end of file
1 parent 92a437d commit 567ac2f

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

AppInspector.RulesEngine/RuleProcessor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,11 +566,11 @@ internal static string ExtractExcerpt(TextContainer text, Location start, Locati
566566

567567
int startLineNumber =
568568
start.Line < 0 ? 0 : start.Line > text.LineEnds.Count ? text.LineEnds.Count - 1 : start.Line;
569-
int endLineNUmber =
569+
int endLineNumber =
570570
end.Line < 0 ? 0 : end.Line > text.LineEnds.Count ? text.LineEnds.Count - 1 : end.Line;
571571
// First we try to include the number of lines of context requested
572572
var excerptStartLine = Math.Max(0, startLineNumber - context);
573-
var excerptEndLine = Math.Min(text.LineEnds.Count - 1, endLineNUmber + context);
573+
var excerptEndLine = Math.Min(text.LineEnds.Count - 1, endLineNumber + context);
574574
var startIndex = text.LineStarts[excerptStartLine];
575575
var endIndex = text.LineEnds[excerptEndLine] + 1;
576576
// Maximum number of characters to capture on each side

AppInspector.RulesEngine/TextContainer.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,14 @@ public string GetLineContent(int line)
449449

450450
/// <summary>
451451
/// Returns location (Line, Column) for given index in text
452+
/// If the index is beyond the end of the file, clamps to the end
452453
/// </summary>
453454
/// <param name="index"> Position in text (line is one-indexed)</param>
454455
/// <returns> Location </returns>
455456
public Location GetLocation(int index)
456457
{
457458
for (var i = 1; i < LineEnds.Count; i++)
459+
{
458460
if (LineEnds[i] >= index)
459461
{
460462
return new Location
@@ -463,6 +465,17 @@ public Location GetLocation(int index)
463465
Line = i
464466
};
465467
}
468+
}
469+
470+
// If the index is beyond the end of the file, clamp to the end of the file
471+
if (index > LineEnds[^1])
472+
{
473+
return new Location()
474+
{
475+
Column = LineEnds[^1] - LineStarts[^1],
476+
Line = LineEnds.Count
477+
};
478+
}
466479

467480
return new Location();
468481
}

AppInspector/Commands/AnalyzeCommand.cs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Concurrent;
66
using System.Collections.Generic;
7+
using System.Collections.Immutable;
78
using System.Diagnostics;
89
using System.Globalization;
910
using System.IO;
@@ -771,21 +772,38 @@ private IEnumerable<FileEntry> EnumerateFileEntries()
771772

772773
if (contents != null)
773774
{
774-
if (_options.DisableCrawlArchives)
775+
IList<FileEntry> entriesToYield = new List<FileEntry>();
776+
try
775777
{
776-
yield return new FileEntry(srcFile, contents);
778+
if (_options.DisableCrawlArchives)
779+
{
780+
entriesToYield.Add(new FileEntry(srcFile, contents));
781+
}
782+
else
783+
{
784+
// Use MemoryStreamCutoff = 1 to force using FileStream with DeleteOnClose for backing, and avoid memory exhaustion.
785+
ExtractorOptions opts = new()
786+
{
787+
Parallel = false, DenyFilters = _options.FilePathExclusions, MemoryStreamCutoff = 1
788+
};
789+
// This works if the contents contain any kind of file.
790+
// If the file is an archive this gets all the entries it contains.
791+
// If the file is not an archive, the stream is wrapped in a FileEntry container and yielded
792+
entriesToYield = extractor.Extract(srcFile, contents, opts).ToImmutableList();
793+
}
777794
}
778-
else
795+
catch (Exception e)
779796
{
780-
// Use MemoryStreamCutoff = 1 to force using FileStream with DeleteOnClose for backing, and avoid memory exhaustion.
781-
ExtractorOptions opts = new()
782-
{
783-
Parallel = false, DenyFilters = _options.FilePathExclusions, MemoryStreamCutoff = 1
784-
};
785-
// This works if the contents contain any kind of file.
786-
// If the file is an archive this gets all the entries it contains.
787-
// If the file is not an archive, the stream is wrapped in a FileEntry container and yielded
788-
foreach (var entry in extractor.Extract(srcFile, contents, opts)) yield return entry;
797+
_logger.LogDebug(
798+
"Failed to analyze file {Path}. {Type}:{Message}. ({StackTrace})",
799+
srcFile, e.GetType(), e.Message, e.StackTrace);
800+
_metaDataHelper?.Metadata.Files.Add(new FileRecord
801+
{ FileName = srcFile, Status = ScanState.Error });
802+
}
803+
804+
foreach (var entry in entriesToYield)
805+
{
806+
yield return entry;
789807
}
790808
}
791809

0 commit comments

Comments
 (0)