Skip to content

Commit

Permalink
Merge branch 'feature/22-add-check-for-max-file-size' into develop
Browse files Browse the repository at this point in the history
Fixes #22
  • Loading branch information
delphidabbler committed May 30, 2023
2 parents 592c1b8 + 56e6aa4 commit b77edec
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 8 deletions.
9 changes: 6 additions & 3 deletions Docs/BDiff.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ BDiff computes differences between two binary files. Text files are treated as a

BDiff handles insertion and deletion of data as well as changed bytes.

Files larger than 10MiB will not be processed unless the `--permit-large-files` option is specified (see _Options_ below).

## Options

| Short option | Long option | Description |
Expand All @@ -24,9 +26,10 @@ BDiff handles insertion and deletion of data as well as changed bytes.
| | `--format=FMT`| Select format by name: `FMT` is one of `binary`, `filtered` or `quoted`. |
|`-m N` | `--min-equal=N`| Two chunks of data are recognized as being identical if they are at least `N` bytes long, the default is `24`. |
| `-o FILENAME` | `--output=FILENAME`| Write diff to specified file instead of standard output. Specifying `--output=-` does nothing. Use as an alternative to shell redirection. |
| `-V` | `--verbose`| Print status messages while processing input. |
|`-h` | `--help` | Show help screen and exit. |
|`-v` | `--version`| Show version number and exit. |
| `-V` | `--verbose`| Print status messages while processing input. |
| | `--permit-large-files` | Ignore maximum file size limit and permit files larger than the limit to be processed. |
|`-h` | `--help` | Show help screen and exit. |
|`-v` | `--version`| Show version number and exit. |

## Algorithm

Expand Down
39 changes: 39 additions & 0 deletions Src/BDiff/BDiff.Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ interface
/// <summary>Class containing main BDiff program logic.</summary>
TMain = class(TObject)
strict private
const
/// <summary>Maximum file size for which diffs can be calculated.
/// </summary>
MaxFileSize = 10_485_760;
/// <summary>Displays the program help screen.</summary>
class procedure DisplayHelp;
/// <summary>Displays the program version information.</summary>
Expand All @@ -32,6 +36,14 @@ TMain = class(TObject)
/// <exception>Raises <c>EOSError</c> if file can't be redirected.
/// </exception>
class procedure RedirectStdOut(const FileName: string);
/// <summary>Checks that both input files are under the maximum supported
/// file size. Does nothing if <c>--permit-large-files</c> option
/// specified.</summary>
/// <param name="Params">[in] Command line parameters object containing
/// the old and new file names.</param>
/// <exception>Raises <c>Exception</c> if either file is larger than
/// maximum permitted.</exception>
class procedure CheckFileSizes(Params: TParams);
public
/// <summary>Runs the program.</summary>
class procedure Run;
Expand All @@ -44,6 +56,7 @@ implementation
uses
// Delphi
System.SysUtils,
System.IOUtils,
// Project
BDiff.Differ,
BDiff.InfoWriter,
Expand All @@ -55,6 +68,31 @@ implementation

{ TMain }

class procedure TMain.CheckFileSizes(Params: TParams);

procedure SizeError(const FileName: string);
begin
Error(
'"%s" is too large (> %.0n bytes)',
[FileName, Extended(MaxFileSize)],
TFormatSettings.Create
);
end;

function IsFileTooLarge(const FileName: string): Boolean;
begin
Result := TFile.GetSize(FileName) > MaxFileSize;
end;

begin
if Params.OverrideMaxSize then
Exit;
if IsFileTooLarge(Params.OldFileName) then
SizeError(Params.OldFileName);
if IsFileTooLarge(Params.NewFileName) then
SizeError(Params.NewFileName);
end;

class procedure TMain.CreateDiff(Params: TParams);
begin
var Logger := TLoggerFactory.CreateInstance(Params.Verbose);
Expand Down Expand Up @@ -103,6 +141,7 @@ class procedure TMain.Run;
DisplayVersion
else
begin
CheckFileSizes(Params);
if (Params.PatchFileName <> '') and (Params.PatchFileName <> '-') then
RedirectStdOut(Params.PatchFileName);
CreateDiff(Params);
Expand Down
14 changes: 14 additions & 0 deletions Src/BDiff/BDiff.Params.pas
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ TParams = class sealed(TBaseParams)
fPatchFileName: string;
fNewFileName: string;
fFormat: TFormat;
fOverrideMaxSize: Boolean;

/// <summary>Write accessor for <c>Format</c> property.</summary>
/// <remarks>Parses and validates property value <c>Value</c>.</remarks>
Expand Down Expand Up @@ -99,6 +100,10 @@ TParams = class sealed(TBaseParams)
/// <summary>Format of patch output.</summary>
property Format: TFormat read fFormat default FMT_QUOTED;

/// <summary>Flag indicating whether to override maximum file size limit to
/// permit oversize files to be diffed.</summary>
property OverrideMaxSize: Boolean read fOverrideMaxSize default False;

/// <summary>Flag indicating whether the program's help screen is to be
/// displayed or not.</summary>
property Help;
Expand Down Expand Up @@ -130,6 +135,7 @@ constructor TParams.Create;
fMinEqual := 24;
fVerbose := False;
fFormat := FMT_QUOTED;
fOverrideMaxSize := False;
end;

procedure TParams.Finalize;
Expand Down Expand Up @@ -160,8 +166,10 @@ function TParams.ParseLongOption(const Option: string; var ParamIdx: Integer;
if Result then
Exit;
Result := True;

if Option = '--verbose' then
fVerbose := True

else if Option = '--output' then
begin
Inc(ParamIdx);
Expand All @@ -171,20 +179,26 @@ function TParams.ParseLongOption(const Option: string; var ParamIdx: Integer;
end
else if AnsiStartsStr('--output=', Option) then
fPatchFileName := StripLeadingChars(Option, Length('--output='))

else if Option = '--format' then
begin
Inc(ParamIdx);
SetFormat(ParamStr(ParamIdx));
end
else if AnsiStartsStr('--format=', Option) then
SetFormat(StripLeadingChars(Option, Length('--format=')))

else if Option = '--min-equal' then
begin
Inc(ParamIdx);
SetMinEqual(ParamStr(ParamIdx));
end
else if AnsiStartsStr('--min-equal=', Option) then
SetMinEqual(StripLeadingChars(Option, Length('--min-equal=')))

else if AnsiStartsStr('--permit-large-files', Option) then
fOverrideMaxSize := True

else
Result := False;
end;
Expand Down
19 changes: 14 additions & 5 deletions Src/Common/Common.Errors.pas
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
interface


uses
// Delphi
System.Sysutils;


/// <summary>Raises an exception with given message.</summary>
procedure Error(const Msg: string); overload;

/// <summary>Raises an exception with message created from format string and
/// values.</summary>
procedure Error(const Fmt: string; const Args: array of const); overload;

procedure Error(const Fmt: string; const Args: array of const;
const FmtSettings: TFormatSettings); overload;

/// <summary>Raises exception determined by last operating system error.
/// </summary>
procedure OSError;
Expand All @@ -24,11 +32,6 @@ procedure OSError;
implementation


uses
// Delphi
System.Sysutils;


procedure Error(const Msg: string);
begin
raise Exception.Create(Msg);
Expand All @@ -39,6 +42,12 @@ procedure Error(const Fmt: string; const Args: array of const);
raise Exception.CreateFmt(Fmt, Args);
end;

procedure Error(const Fmt: string; const Args: array of const;
const FmtSettings: TFormatSettings);
begin
raise Exception.Create(Format(Fmt, Args, FmtSettings));
end;

procedure OSError;
begin
var Err: EOSError;
Expand Down

0 comments on commit b77edec

Please sign in to comment.