Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent possible crash when archiving in folder with non-archived files #1632

Merged
merged 1 commit into from
Sep 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/NLog/Targets/FileTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1464,12 +1464,27 @@ private void EnsureArchiveCount(List<string> oldArchiveFileNames)
}
}

/// <summary>
/// Parse filename with date and sequence pattern
/// </summary>
/// <param name="archiveFileNameWithoutPath"></param>
/// <param name="dateFormat">dateformat for archive</param>
/// <param name="fileTemplate"></param>
/// <param name="date">the found pattern. When failed, then default</param>
/// <param name="sequence">the found pattern. When failed, then default</param>
/// <returns></returns>
private static bool TryParseDateAndSequence(string archiveFileNameWithoutPath, string dateFormat, FileNameTemplate fileTemplate, out DateTime date, out int sequence)
{
int trailerLength = fileTemplate.Template.Length - fileTemplate.EndAt;
int dateAndSequenceIndex = fileTemplate.BeginAt;
int dateAndSequenceLength = archiveFileNameWithoutPath.Length - trailerLength - dateAndSequenceIndex;

if (dateAndSequenceLength < 0)
{
date = default(DateTime);
sequence = 0;
return false;
}
string dateAndSequence = archiveFileNameWithoutPath.Substring(dateAndSequenceIndex, dateAndSequenceLength);
int sequenceIndex = dateAndSequence.LastIndexOf('.') + 1;

Expand Down
35 changes: 23 additions & 12 deletions tests/NLog.UnitTests/Targets/FileTargetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1851,25 +1851,31 @@ public void DisposingFileTarget_WhenNotIntialized_ShouldNotThrow()
[Fact]
public void FileTarget_ArchiveNumbering_DateAndSequence()
{
FileTarget_ArchiveNumbering_DateAndSequenceTests(enableCompression: false);
FileTarget_ArchiveNumbering_DateAndSequenceTests(enableCompression: false, fileTxt: "file.txt", archiveFileName: Path.Combine("archive", "{#}.txt"));
}

[Fact]
public void FileTarget_ArchiveNumbering_DateAndSequence_archive_same_as_log_name()
{
FileTarget_ArchiveNumbering_DateAndSequenceTests(enableCompression: false, fileTxt: "file-${date:format=yyyy-MM-dd}.txt", archiveFileName: "file-{#}.txt");
}

#if NET4_5
[Fact]
public void FileTarget_ArchiveNumbering_DateAndSequence_WithCompression()
{
FileTarget_ArchiveNumbering_DateAndSequenceTests(enableCompression: true);
FileTarget_ArchiveNumbering_DateAndSequenceTests(enableCompression: true, fileTxt: "file.txt", archiveFileName: Path.Combine("archive", "{#}.zip"));
}
#endif

private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompression)
private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompression, string fileTxt, string archiveFileName)
{
const string archiveDateFormat = "yyyy-MM-dd";
const int archiveAboveSize = 1000;

var tempPath = ArchiveFileNameHelper.GenerateTempPath();
var logFile = Path.Combine(tempPath, "file.txt");
var archiveExtension = enableCompression ? "zip" : "txt";
Layout logFile = Path.Combine(tempPath, fileTxt);
var logFileName = logFile.Render(LogEventInfo.CreateNullEvent());
try
{
var fileTarget = WrapFileTarget(new FileTarget
Expand All @@ -1878,7 +1884,7 @@ private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompres
EnableArchiveFileCompression = enableCompression,
#endif
FileName = logFile,
ArchiveFileName = Path.Combine(tempPath, "archive", "{#}." + archiveExtension),
ArchiveFileName = Path.Combine(tempPath, archiveFileName),
ArchiveDateFormat = archiveDateFormat,
ArchiveAboveSize = archiveAboveSize,
LineEnding = LineEndingMode.LF,
Expand All @@ -1898,7 +1904,7 @@ private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompres
Generate1000BytesLog('d');
Generate1000BytesLog('e');

string archiveFilename = DateTime.Now.ToString(archiveDateFormat);
string renderedArchiveFileName = archiveFileName.Replace("{#}", DateTime.Now.ToString(archiveDateFormat));

LogManager.Configuration = null;

Expand All @@ -1908,9 +1914,12 @@ private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompres
#else
var assertFileContents = new Action<string, string, Encoding>(AssertFileContents);
#endif
ArchiveFileNameHelper helper = new ArchiveFileNameHelper(Path.Combine(tempPath, "archive"), archiveFilename, archiveExtension);
var extension = Path.GetExtension(renderedArchiveFileName);
var fileNameWithoutExt = renderedArchiveFileName.Substring(0, renderedArchiveFileName.Length - extension.Length);
ArchiveFileNameHelper helper = new ArchiveFileNameHelper(tempPath, fileNameWithoutExt, extension);

AssertFileContents(logFile,

AssertFileContents(logFileName,
StringRepeat(250, "eee\n"),
Encoding.UTF8);

Expand All @@ -1923,8 +1932,8 @@ private void FileTarget_ArchiveNumbering_DateAndSequenceTests(bool enableCompres
}
finally
{
if (File.Exists(logFile))
File.Delete(logFile);
if (File.Exists(logFileName))
File.Delete(logFileName);
if (Directory.Exists(tempPath))
Directory.Delete(tempPath, true);
}
Expand Down Expand Up @@ -2355,12 +2364,14 @@ private class ArchiveFileNameHelper
/// </summary>
public string Ext { get; set; }



/// <summary>
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
/// </summary>
public ArchiveFileNameHelper(string folderName, string fileName, string ext)
{
Ext = ext;
Ext = ext.TrimStart('.');
FileName = fileName;
FolderName = folderName;
}
Expand Down