NAME
Text::Patch::Rred - Safely apply diff --ed style patches
VERSION
This is version 0.06
USAGE
Command Line:
rred file.old file.new file.patch1 [ file.patch2 ... ]
Functional Interface (preferred, faster, type checked)
my @lines = <ORIGINAL>;
my $edState = Text::Patch::Rred::Init(@lines);
# or &Text::Patch::Rred::Init(\@lines);
while (<EDSCRIPTS>) { Text::Patch::Rred::Do1($edState, $_); }
@lines = Text::Patch::Rred::Result($edState);
$edState = undef; # free memory
print PATCHED @lines;
Object Interface:
my @lines = <ORIGINAL>;
my $edState = Text::Patch::Rred->new(\@lines);
while (<EDSCRIPTS>) { $edState->Do1($_); }
@lines = $edState->Result;
$edState = undef; # free memory
print PATCHED @lines;
Example:
$ diff --ed file.v1 file.v2 >file.patch1
$ diff --ed file.v2 file.v3 >file.patch2
$ rred file.v1 file.new file.patch1 [ file.patch2 ... ]
$ # Now file.new is the same as file.v3
$ # Alternative:
$ cat file.patch1 file.patch2 | rred file.v1 file.new -
DESCRIPTION
This module and program safely and securely applies one or more ed-style patches as produced by the command diff --ed oldfile newfile
. It does exactly what you tell it to and no more, even with wildly bad or evil input.
Unlike the traditional programs patch, ed, red and sed, Rred does not allow the data in the patch to run arbitrary commands, read or write files or otherwise cause havoc. Only the handful of safe "commands" actually used by diff are recognized and processed.
Unlike the patch program and the perl modules Text::Patch, PatchReader and Meta::Development::Patch, this module does NOT try to doubleguess what kind of data it is given or which file to process.
(Note that the other perl modules just mentioned cannot actually apply an ed-style patch, though some can parse it).
The name rred is short for "Really Restricted ED" (as compared to red). This is the name given to a similar utility used inside the Debian projects apt facility.
REQUIRED ARGUMENTS
- file.old
-
Original file whose contents is to be patch. This file should be identical to the first file passed to
diff -e
when the patches were made. In this implementation, perl magics are supported for this file name. - file.new
-
Output file where the fully patched contents is to be written. This file will become identical to the last file passed to
diff -e
when the patches were made. This file can be the same file as any of the input files. In this implementation, perl magics are not supported for this file name. - file.patch1 [ file.patch2 ... ]
-
One or more --ed style patch files to be applied (in sequence) to the contents of file.old to produce file.new. These files should be identical to the output of one or more invocations of
diff -e
on file.old and file.new plus optionally any intermediary files. The patch files may optionally be concatenated before being passed to rred, the result will be the same as passing them individually. In this implementation, perl magics are supported for these file names.
EXPORT
Init, Do1, Do, Result and main can be exported. :all is short for Init, Do1 and Result. Nothing is exported by default.
FUNCTIONS and METHODS
- new \@lines
- Init @lines
-
Initializes a new patch state and sets the initial file content to a copy of the lines of text (each a string) supplied. Returns a new Text::Patch::Rred object if successful, undef on error (there are no current error scenarios).
Lines in
@lines
must use the same line endings (none or "\n") as lines passed to Do1 and Do - Result $edState
- $edState->Result
-
Returns the lines of the patched file as a list of strings, does not destroy
$edState
so you can apply more patches later. - Do1 $edState, $patchline
- $edState->Do1($patchline)
-
Applies one line from a patch file to
$edState
. Returns a true value if the line was understood. Carps and returnsundef
if an unsupported command is input. - Do $edState, @lines
- $edState->Do(@lines)
-
Simply calls Do1 for each element of
@lines
, returns a true value if all calls were successful or@lines
was empty. Otherwise returnsundef
. - main @ARGV
-
The main program code of rred as a function, accepting the command line syntax in the SYNOPSIS above. Returns the program exit code (0 ok, 1 error, 2 bad syntax). Running
rred args
is the same as runningperl -MText::Patch::Rred \ -e 'exit Text::Patch::Rred::main @ARGV' args
ED COMMANDS
Unfortunately, the GNU diff documentation (info -f diff -n 'Detailed ed'
or http://www.gnu.org/software/diffutils/manual/html_node/Detailed-ed.html) is sloppy about specifying exactly which subset of the ed editor command language might appear in diff --ed
output.
Currently the ed "commands" actually used by various versions of diff --ed
and diff -e
are believed to be (these are the ones supported by this module, and also the ones emitted by GNU diff according to a cursory inspection of its source code):
a
###a
###,###a
c
###c
###,###c
d
###d
###,###d
s/.//
w
OPTIONS
None.
CONFIGURATION AND ENVIRONMENT
None.
BUGS AND LIMITATIONS
There seems to be no formal specification for the subset of ed(1) commands used by diff -e
, thus this program is limited to the subset of ed(1) commands listed above, which may or may not be sufficient to apply the patch files you encounter in practice.
Although steps have been taken to limit memory consumption, perl still uses a lot of memory when running this module, as much as 5 times the file size has been observed in tests.
DIAGNOSTICS
- rred: Printing usage: error message
-
When running rred or Text::Patch::Rred::main with less than 3 args, it should have printed its usage help message to stderr, but this somehow failed.
- Loading 'file.old': error message
-
When loading the original unpatched file from file.old, something went wrong at the file I/O level.
- Saving 'file.new': error message
-
When saving the completely patched file to file.new, something went wrong at the file I/O level.
- Reading 'file.patch': error message
-
When loading one of the patch files from file.patch, something went wrong at the File I/O level.
- Unexpected non-patch ed command: 'text'
-
'text' was found in one of the patch files but is not an ed command supported by rred.
DEPENDENCIES
Text::Patch::Rred only needs perl itself (at least version 5.6) and the standard Carp, Exporter and base modules.
INCOMPATIBILITIES
None known.
SEE ALSO
diff(1), info -f diff -n 'Detailed ed'
, patch(1), ed(1), red(1), Text::Patch, http://www.gnu.org/software/diffutils/manual/html_node/Detailed-ed.html
AUTHOR
Jakob Bohm, <ehekikkeptiehewdur@jbohm.dk>
Always include the full module name (with double colons and all) in the subject line to get past my "spam" filters.
LICENSE AND COPYRIGHT
Copyright (C) ©2006-2009 by Jakob Bohm. All Rights Reserved.
This library and program is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.0 or, at your option, any later version of Perl 5 you may have available.