This commit is contained in:
Koen van de Sande 2026-06-19 02:57:34 +00:00 committed by GitHub
commit 088db344e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 76 additions and 10 deletions

View file

@ -3043,6 +3043,36 @@ begin
end;
end;
// Returns True if the file has lines longer than MaxLen bytes.
// Only reads the first MaxLen+1 bytes to check.
function FileHasLongLines(const sFileName: String; MaxLen: SizeInt): Boolean;
var
CheckLen, J: SizeInt;
CheckBuf: AnsiString;
begin
Result := False;
try
with TFileStreamUAC.Create(sFileName, fmOpenRead or fmShareDenyNone) do
try
CheckLen := Min(Size, MaxLen + 1);
SetLength(CheckBuf, CheckLen);
Read(Pointer(CheckBuf)^, CheckLen);
if CheckLen <= MaxLen then
Exit; // File is smaller than the limit
for J := 1 to CheckLen do
begin
if CheckBuf[J] in [#10, #13] then
Exit; // Found a newline within the limit
end;
Result := True; // No newline found in first MaxLen+1 bytes
finally
Free;
end;
except
Result := True; // On error, assume long lines to be safe
end;
end;
function TfrmViewer.CheckSynEdit(const sFileName: String; bForce: Boolean = False): Boolean;
var
AFile: TFile;
@ -3094,6 +3124,19 @@ begin
PushPop(FElevate);
end;
end;
// Skip files with extremely long lines (e.g. minified JSON)
// that would freeze SynEdit's highlighter/word-wrap.
if Result and not bForce then
begin
PushPop(FElevate);
try
if FileHasLongLines(sFileName, 8192) then
Result := False;
finally
PushPop(FElevate);
end;
end;
end;
function TfrmViewer.LoadGraphics(const sFileName:String): Boolean;

View file

@ -51,7 +51,7 @@ type
implementation
uses
StreamEx, URIParser, MD5, FileUtil, LazFileUtils, Forms, uDCUtils, DCOSUtils, DCStrUtils,
StreamEx, URIParser, MD5, FileUtil, LazFileUtils, Forms, Math, uDCUtils, DCOSUtils, DCStrUtils,
uDebug, uReSample, uGlobsPaths, uGlobs, uPixmapManager, uFileSystemFileSource,
uGraphics, uFileProcs;
@ -92,9 +92,10 @@ end;
procedure TThumbnailManager.DoCreatePreviewText;
var
S: String;
Y: Integer;
Y, P, LineStart: Integer;
Stream: TFileStreamEx;
Reader: TStreamReader;
MaxChars, MaxRead: Integer;
Buf: AnsiString;
begin
FBitmap:= TBitmap.Create;
with FBitmap do
@ -104,18 +105,40 @@ begin
Canvas.FillRect(Canvas.ClipRect);
Canvas.Font.Color:= clWindowText;
Canvas.Font.Size := FThumbBitmapSize.cy div 16;
// Estimate max visible characters per line from thumbnail width
MaxChars := FThumbBitmapSize.cx div Max(Canvas.TextWidth('M') div 2, 1);
MaxRead := 8192;
try
Stream:= TFileStreamEx.Create(FFileName, fmOpenRead or fmShareDenyNone);
try
Y:= 0;
Reader:= TStreamReader.Create(Stream, BUFFER_SIZE, True);
repeat
S:= Reader.ReadLine;
if Stream.Size < MaxRead then MaxRead := Stream.Size;
SetLength(Buf, MaxRead);
Stream.Read(Pointer(Buf)^, MaxRead);
finally
Stream.Free;
end;
Y:= 0;
LineStart := 1;
P := 1;
while (Y < FThumbBitmapSize.cy) and (P <= Length(Buf)) do
begin
if Buf[P] in [#10, #13] then
begin
S := Copy(Buf, LineStart, Min(P - LineStart, MaxChars));
Canvas.TextOut(0, Y, S);
Y += Canvas.TextHeight(S) + 2;
until (Y >= FThumbBitmapSize.cy) or Reader.Eof;
finally
Reader.Free;
// Skip CR+LF pair
if (P < Length(Buf)) and (Buf[P] = #13) and (Buf[P + 1] = #10) then
Inc(P);
LineStart := P + 1;
end;
Inc(P);
end;
// Handle last line (or single-line file)
if (Y < FThumbBitmapSize.cy) and (LineStart <= Length(Buf)) then
begin
S := Copy(Buf, LineStart, Min(Length(Buf) - LineStart + 1, MaxChars));
Canvas.TextOut(0, Y, S);
end;
except
// Ignore