Skip to content

Commit

Permalink
1.1.3.14 Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Taicanium committed Apr 20, 2024
1 parent e0e6797 commit 3740cfb
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 30 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 1.1.3.14 - 20/04/2024
- We now scan pre-existing destination files for apparent source log data, and refuse to overwrite them if it exists.

# 1.1.3.13 - 17/04/2024
- File and folder selection dialogs now open by default to the standard F-Chat 3.0 log location (%appdata%/fchat/data) when selecting source logs, and to the user's desktop when selecting a destination.
- Minor fix: HTML output files containing a second, empty HTML body.
Expand Down
56 changes: 45 additions & 11 deletions Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,24 @@ static class Common
<body>";
public static bool plaintext = true;
public static string lastException = string.Empty;
public static uint lastTimestamp;
public static uint lastTimestamp = 0U;
public readonly static Dictionary<string, string> tagClosings = new()
{
{ "b", "</b>" },
{ "big", "</span>" },
{ "color", "</span>" },
{ "eicon", ".gif\" />" },
{ "i", "</i>" },
{ "icon", ".png\" /></a>" },
{ "noparse", "</script>" },
{ "s", "</s>" },
{ "u", "</u>" },
{ "session", "</a>" },
{ "spoiler", "</span>" },
{ "sub", "</sub>" },
{ "sup", "</sup>" },
{ "big", "</span>" },
{ "noparse", "</script>" },
{ "u", "</u>" },
{ "url", "</a>" },
{ "icon", ".png\" /></a>" },
{ "eicon", ".gif\" />" },
{ "user", "</span></a>" },
{ "spoiler", "</span>" },
{ "session", "</a>" },
{ "color", "</span>" },
};
public static DateTime timeBegin;

Expand Down Expand Up @@ -123,15 +123,15 @@ public static bool IsValidPattern(string? pattern = null)
return true;
}

public static bool IsValidTimestamp(uint timestamp)
public static bool IsValidTimestamp(uint timestamp, bool TSTestOverride = false)
{
if (timestamp < 1) // If it came before Jan. 1, 1970, there's a problem.
return false;
if (timestamp > UNIXTimestamp()) // If it's in the future, also a problem.
return false;
if ((DTFromStamp(timestamp).ToString(dateFormat) ?? string.Empty).Equals(string.Empty)) // If it can't be translated to a date, also a problem.
return false;
if (timestamp < lastTimestamp) // If it isn't sequential, also a problem, because F-Chat would never save it that way.
if (!TSTestOverride && timestamp < lastTimestamp) // If it isn't sequential, also a problem, because F-Chat would never save it that way.
// In this case specifically, there's an extremely high chance we're about to produce garbage data in the output.
return false;
return true;
Expand All @@ -145,6 +145,40 @@ public static void LogException(Exception e)
return;
}

public static bool LogTest(string targetFile)
{
byte[] idBuffer = new byte[4];
byte[] srcBuffer;
using FileStream srcFS = new FileInfo(targetFile).OpenRead();

if (srcFS.Read(idBuffer, 0, 4) < 4)
return false;
if (!IsValidTimestamp(BEInt(idBuffer), true))
return false;

if (srcFS.ReadByte() > 6)
return false;

int profLen = srcFS.ReadByte();
if (profLen == -1)
return false;

if (profLen > 0)
{
srcBuffer = new byte[profLen];
if (srcFS.Read(srcBuffer, 0, profLen) < profLen)
return false;
}

if (srcFS.Read(idBuffer, 0, 2) < 2)
return false;

// We assume a valid log file starting from here, as the header format of the message is now confirmed -
// and we can't assume the very first message in a file *didn't* happen to just be truncated or empty.

return true;
}

public static uint UNIXTimestamp()
{
return (uint)Math.Floor(DateTime.UtcNow.Subtract(epoch).TotalSeconds);
Expand Down
2 changes: 1 addition & 1 deletion FLogS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<UseWPF>true</UseWPF>
<SignAssembly>False</SignAssembly>
<Title>FLogS</Title>
<Version>1.1.3.13</Version>
<Version>1.1.3.14</Version>
<IncludeSymbols>True</IncludeSymbols>
<ErrorReport>none</ErrorReport>
<UseWindowsForms>True</UseWindowsForms>
Expand Down
1 change: 0 additions & 1 deletion KNOWN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
- Ads are read correctly as they are in later versions, but much older clients didn't record ads as uniquely ID'd messages - they appear to have just been plaintext, with no delimiter. Reading them causes patches of garbage.

# Todo
- Preliminary scan of selected destination files, if they exist. If they appear at a glance to be un-translated user logs, refuse to overwrite them. (i.e. if it appears the user accidentally used a source log as the destination)
- Android version for mobile users of F-Chat.
33 changes: 29 additions & 4 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private enum FLogS_ERROR
DEST_NOT_DIRECTORY,
DEST_NOT_FILE,
DEST_NOT_FOUND,
DEST_SENSITIVE, // Todo.
DEST_SENSITIVE,
NO_DEST,
NO_DEST_DIR,
NO_REGEX,
Expand Down Expand Up @@ -253,7 +253,7 @@ private void FormatOverride(object? sender, RoutedEventArgs e)
(FLogS_ERROR.DEST_NOT_DIRECTORY, _) => "Destination is not a directory.",
(FLogS_ERROR.DEST_NOT_FILE, _) => "Destination is not a file.",
(FLogS_ERROR.DEST_NOT_FOUND, _) => "Destination directory does not exist.",
(FLogS_ERROR.DEST_SENSITIVE, _) => "Destination appears to contain source log data.", // Todo.
(FLogS_ERROR.DEST_SENSITIVE, _) => "Destination appears to contain source log data.",
(FLogS_ERROR.NO_DEST, _) => "No destination file selected.",
(FLogS_ERROR.NO_DEST_DIR, _) => "No destination directory selected.",
(FLogS_ERROR.NO_REGEX, _) => "No search text entered.",
Expand Down Expand Up @@ -497,8 +497,17 @@ private void TextboxUpdated(object? sender, EventArgs e)
directoryError = FLogS_ERROR.SOURCES_NOT_FOUND;
else if (file.Equals(outFile))
directoryError = FLogS_ERROR.SOURCE_CONFLICT;
else if (directoryError == FLogS_ERROR.NONE && File.Exists(outFile))

if (File.Exists(outFile))
{
if (Common.LogTest(outFile))
{
directoryError = FLogS_ERROR.DEST_SENSITIVE;
break;
}

directoryWarning = FLogS_WARNING.MULTI_OVERWRITE;
}
}
}

Expand All @@ -515,7 +524,12 @@ private void TextboxUpdated(object? sender, EventArgs e)
else if (FileSource.Text.Equals(FileOutput.Text))
fileError = FLogS_ERROR.SOURCE_EQUALS_DEST;
else if (File.Exists(FileOutput.Text))
{
if (Common.LogTest(FileOutput.Text))
fileError = FLogS_ERROR.DEST_SENSITIVE;

fileWarning = FLogS_WARNING.SINGLE_OVERWRITE;
}

if (PhraseSource.Text.Length == 0)
phraseError = FLogS_ERROR.NO_SOURCES;
Expand All @@ -534,16 +548,27 @@ private void TextboxUpdated(object? sender, EventArgs e)
foreach (string file in PhraseSource.Text.Split(';'))
{
string outFile = Path.Join(PhraseOutput.Text, Path.GetFileNameWithoutExtension(file));

if (!Common.plaintext)
outFile += ".html";
else
outFile += ".txt";

if (!File.Exists(file))
phraseError = FLogS_ERROR.SOURCES_NOT_FOUND;
else if (file.Equals(outFile))
phraseError = FLogS_ERROR.SOURCE_CONFLICT;
else if (phraseError == FLogS_ERROR.NONE && File.Exists(outFile))

if (File.Exists(outFile))
{
if (Common.LogTest(outFile))
{
phraseError = FLogS_ERROR.DEST_SENSITIVE;
break;
}

phraseWarning = FLogS_WARNING.MULTI_OVERWRITE;
}
}
}
}
Expand Down
26 changes: 13 additions & 13 deletions MessagePool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,20 @@ internal partial class MessagePool
private readonly Dictionary<string, int> tagCounts = new()
{
{ "b", 0 },
{ "big", 0 },
{ "color", 0 },
{ "eicon", 0 },
{ "i", 0 },
{ "icon", 0 },
{ "noparse", 0 },
{ "s", 0 },
{ "u", 0 },
{ "session", 0 },
{ "spoiler", 0 },
{ "sub", 0 },
{ "sup", 0 },
{ "big", 0 },
{ "noparse", 0 },
{ "u", 0 },
{ "url", 0 },
{ "icon", 0 },
{ "eicon", 0 },
{ "user", 0 },
{ "spoiler", 0 },
{ "session", 0 },
{ "color", 0 },
};
private Stack<string>? tagHistory;
private uint thisDate = 1U;
Expand Down Expand Up @@ -272,7 +272,7 @@ private bool TranslateIDX(FileStream srcFS)
/*
* I have not reverse-engineered the IDX format beyond reading channel/profile names from it.
* It appears to contain 8-byte blocks of numerical data in ascending value; there are more such blocks in IDX files paired with older logs.
* I don't know what the blocks represent, but they are almost certainly not timestamps.
* I don't know what the blocks represent, but they are almost certainly not timestamps - they're several powers of ten too large.
*/

string? fileName = Path.GetFileNameWithoutExtension(srcFile);
Expand Down Expand Up @@ -587,8 +587,8 @@ private bool TranslateMessage(FileStream srcFS, StreamWriter dstFS)
}

lastPosition = (uint)srcFS.Position;
bool nextTimestamp = false;
while (!nextTimestamp) // Search for the next message by locating its timestamp and delimiter. It's the latter we're *really* looking for; the timestamp just helps us identify it.
bool nextID = false;
while (!nextID) // Search for the next message by locating its delimiter.
{
srcFS.ReadByte();
srcFS.Read(idBuffer, 0, 4);
Expand All @@ -607,7 +607,7 @@ private bool TranslateMessage(FileStream srcFS, StreamWriter dstFS)
discrepancy = (int)srcFS.Position - (int)lastPosition;
lastDiscrepancy += discrepancy;
lastPosition = (uint)srcFS.Position;
nextTimestamp = true;
nextID = true;
unreadBytes += discrepancy;
srcFS.ReadByte();
}
Expand All @@ -626,7 +626,7 @@ private bool TranslateMessage(FileStream srcFS, StreamWriter dstFS)
discrepancy = (int)srcFS.Position - (int)lastPosition - 2;
lastDiscrepancy += discrepancy;
lastPosition = (uint)srcFS.Position;
nextTimestamp = true;
nextID = true;
unreadBytes += discrepancy;
}
}
Expand Down

0 comments on commit 3740cfb

Please sign in to comment.