Skip to content

Commit

Permalink
Item13432: can of worms. The low-level functions in the RCS stores tr…
Browse files Browse the repository at this point in the history
…eat binary attachments and topics the same, and there's no way to know the opprpriate encoding. Fixed that, and developed the StoreTestCases to cover different charsets for the {Store}{Encoding}, which revealed a number of other subtle problems, also fixed.
  • Loading branch information
Comment committed May 28, 2015
1 parent 03ecc6c commit 5a85267
Show file tree
Hide file tree
Showing 13 changed files with 663 additions and 541 deletions.
277 changes: 163 additions & 114 deletions PlainFileStoreContrib/lib/Foswiki/Store/PlainFile.pm

Large diffs are not rendered by default.

170 changes: 88 additions & 82 deletions RCSStoreContrib/lib/Foswiki/Store/Rcs/Handler.pm

Large diffs are not rendered by default.

41 changes: 18 additions & 23 deletions RCSStoreContrib/lib/Foswiki/Store/Rcs/RcsLiteHandler.pm
Expand Up @@ -87,6 +87,7 @@ package Foswiki::Store::Rcs::RcsLiteHandler;
use strict;
use warnings;

use Foswiki::Store::Rcs::Store ();
use Foswiki::Store::Rcs::Handler ();
our @ISA = ('Foswiki::Store::Rcs::Handler');

Expand Down Expand Up @@ -122,6 +123,16 @@ use constant CAN_IGNORE_COMMENT => 0; # 1
# If the parse was successful this will be 'parsed'.
#

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
require locale;
import locale();
}

*_decode = \&Foswiki::Store::Rcs::Store::_decode;
*_encode = \&Foswiki::Store::Rcs::Store::_encode;
}

# implements Rcs::Handler
sub new {
my $class = shift;
Expand Down Expand Up @@ -257,12 +268,7 @@ sub _ensureRead {
}

my $fh;
unless (
open(
$fh, '<', Foswiki::Store::Rcs::Handler::fn2b( $this->{rcsFile} )
)
)
{
unless ( open( $fh, '<', _encode( $this->{rcsFile} ) ) ) {

#warn( 'Failed to open ' . $this->{rcsFile} . ': ' . $!);
$this->{state} = 'nocommav';
Expand Down Expand Up @@ -546,16 +552,8 @@ sub _writeMe {
my ($this) = @_;
my $out;

chmod(
$Foswiki::cfg{Store}{filePermission},
Foswiki::Store::Rcs::Handler::fn2b( $this->{rcsFile} )
);
unless (
open(
$out, '>', Foswiki::Store::Rcs::Handler::fn2b( $this->{rcsFile} )
)
)
{
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{rcsFile} ) );
unless ( open( $out, '>', _encode( $this->{rcsFile} ) ) ) {
throw Error::Simple(
'Cannot open ' . $this->{rcsFile} . ' for write: ' . $! );
}
Expand All @@ -564,10 +562,7 @@ sub _writeMe {
_write( $this, $out );
close($out);
}
chmod(
$Foswiki::cfg{Store}{filePermission},
Foswiki::Store::Rcs::Handler::fn2b( $this->{rcsFile} )
);
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{rcsFile} ) );
}

# implements Rcs::Handler
Expand Down Expand Up @@ -849,7 +844,7 @@ sub getRevisionAtTime {

$this->_ensureRead( -1, 1 ); # read history only
if ( $this->{state} eq 'nocommav' ) {
return ( $date >= ( stat( $this->{file} ) )[9] ) ? 1 : undef;
return ( $date >= ( stat( _encode( $this->{file} ) ) )[9] ) ? 1 : undef;
}

my $version = $this->{head};
Expand All @@ -861,7 +856,7 @@ sub getRevisionAtTime {
if ( $version == $this->{head} && !$this->noCheckinPending() ) {

# Check the file date
$version++ if ( $date >= ( stat( $this->{file} ) )[9] );
$version++ if ( $date >= ( stat( _encode( $this->{file} ) ) )[9] );
}
return $version;
}
Expand All @@ -888,7 +883,7 @@ sub stringify {
1;
__END__
Copyright (C) 2008-2009 Foswiki Contributors. All Rights Reserved.
Copyright (C) 2008-2015 Foswiki Contributors. All Rights Reserved.
Foswiki Contributors are listed in the AUTHORS file in the root of
this distribution. NOTE: Please extend that file, not this notice.
Expand Down
71 changes: 42 additions & 29 deletions RCSStoreContrib/lib/Foswiki/Store/Rcs/RcsWrapHandler.pm
Expand Up @@ -25,6 +25,16 @@ our @ISA = ('Foswiki::Store::Rcs::Handler');

use Foswiki::Sandbox ();

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
require locale;
import locale();
}

*_decode = \&Foswiki::Store::Rcs::Store::_decode;
*_encode = \&Foswiki::Store::Rcs::Store::_encode;
}

sub new {
return shift->SUPER::new(@_);
}
Expand Down Expand Up @@ -55,9 +65,10 @@ sub initBinary {

return if $this->revisionHistoryExists();

my ( $rcsOutput, $exit ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{initBinaryCmd},
FILENAME => $this->{file} );
my ( $rcsOutput, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{initBinaryCmd},
FILENAME => _encode( $this->{file} )
);
if ($exit) {
throw Error::Simple( $Foswiki::cfg{RCS}{initBinaryCmd} . ' of '
. $this->hidePath( $this->{file} )
Expand All @@ -82,9 +93,9 @@ sub initText {

return if $this->revisionHistoryExists();

my ( $rcsOutput, $exit ) =
my ( $rcsOutput, $exit, $stdErr ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{initTextCmd},
FILENAME => $this->{file} );
FILENAME => _encode( $this->{file} ) );
if ($exit) {
$rcsOutput ||= '';
throw Error::Simple( $Foswiki::cfg{RCS}{initTextCmd} . ' of '
Expand Down Expand Up @@ -125,7 +136,7 @@ sub ci {
( $rcsOutput, $exit, $stderr ) = Foswiki::Sandbox->sysCommand(
$cmd,
USERNAME => $user,
FILENAME => $this->{file},
FILENAME => _encode( $this->{file} ),
COMMENT => $comment,
DATE => $date
);
Expand All @@ -135,7 +146,7 @@ sub ci {
( $rcsOutput, $exit, $stderr ) = Foswiki::Sandbox->sysCommand(
$cmd,
USERNAME => $user,
FILENAME => $this->{file},
FILENAME => _encode( $this->{file} ),
COMMENT => $comment
);
}
Expand All @@ -149,7 +160,7 @@ sub ci {
. $rcsOutput
. ( (DEBUG) ? $stderr : '' ) );
}
chmod( $Foswiki::cfg{Store}{filePermission}, $this->{file} );
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{file} ) );
}

# implements Rcs::Handler
Expand Down Expand Up @@ -179,14 +190,14 @@ sub repRev {
$Foswiki::cfg{RCS}{ciDateCmd},
DATE => $date,
USERNAME => $user,
FILENAME => $this->{file},
FILENAME => _encode( $this->{file} ),
COMMENT => $comment
);
if ($exit) {
$rcsOut = $Foswiki::cfg{RCS}{ciDateCmd} . "\n" . $rcsOut;
return $rcsOut;
}
chmod( $Foswiki::cfg{Store}{filePermission}, $this->{file} );
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{file} ) );
}

# implements Rcs::Handler
Expand All @@ -203,18 +214,18 @@ sub _deleteRevision {
# delete latest revision (unlock (may not be needed), delete revision)
my ( $rcsOut, $exit ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{unlockCmd},
FILENAME => $this->{file} );
FILENAME => _encode( $this->{file} ) );
if ($exit) {
throw Error::Simple(
$Foswiki::cfg{RCS}{unlockCmd} . ' failed: ' . $rcsOut );
}

chmod( $Foswiki::cfg{Store}{filePermission}, $this->{file} );
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{file} ) );

( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{delRevCmd},
REVISION => '1.' . $rev,
FILENAME => $this->{file}
FILENAME => _encode( $this->{file} )
);

if ($exit) {
Expand All @@ -229,7 +240,7 @@ sub _deleteRevision {
( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{coCmd},
REVISION => '1.' . $rev,
FILENAME => $this->{file}
FILENAME => _encode( $this->{file} )
);

if ($exit) {
Expand Down Expand Up @@ -268,7 +279,7 @@ sub getRevision {
my $tmpfile;
my $tmpRevFile;
my $coCmd = $Foswiki::cfg{RCS}{coCmd};
my $file = $this->{file};
my $file = _encode( $this->{file} );
if ( $Foswiki::cfg{RCS}{coMustCopy} ) {

# Need to take temporary copy of topic, check it out to file,
Expand Down Expand Up @@ -310,7 +321,7 @@ sub getRevision {
# is required.

if ($tmpfile) {
$text = Foswiki::Store::Rcs::Handler::readFile( $this, $tmpfile );
$text = $this->readFile($tmpfile);
for ( $tmpfile, $tmpRevFile ) {
my $f = Foswiki::Sandbox::untaintUnchecked($_);
unlink $f or warn "Could not delete $f: $!";
Expand All @@ -337,7 +348,7 @@ sub getInfo {
my ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{infoCmd},
REVISION => '1.' . $version,
FILENAME => $this->{rcsFile}
FILENAME => _encode( $this->{rcsFile} )
);
if ( !$exit ) {
if ( $rcsOut =~
Expand Down Expand Up @@ -373,7 +384,7 @@ sub _numRevisions {

my ( $rcsOutput, $exit ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{histCmd},
FILENAME => $this->{rcsFile} );
FILENAME => _encode( $this->{rcsFile} ) );
if ($exit) {
throw Error::Simple( 'RCS: '
. $Foswiki::cfg{RCS}{histCmd} . ' of '
Expand Down Expand Up @@ -409,7 +420,7 @@ sub revisionDiff {
$Foswiki::cfg{RCS}{diffCmd},
REVISION1 => '1.' . $rev1,
REVISION2 => '1.' . $rev2,
FILENAME => $this->{rcsFile},
FILENAME => _encode( $this->{rcsFile} ),
CONTEXT => $contextLines
);

Expand Down Expand Up @@ -503,20 +514,22 @@ sub _lock {
# Try and get a lock on the file
my ( $rcsOutput, $exit ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{lockCmd},
FILENAME => $this->{file} );
FILENAME => _encode( $this->{file} ) );

if ($exit) {

# if the lock has been set more than 24h ago, let's try to break it
# and then retry. Should not happen unless in Cairo upgrade
# scenarios - see Item2102
if ( ( time - ( stat( $this->{rcsFile} ) )[9] ) > 3600 ) {
if ( ( time - ( stat( _encode( $this->{rcsFile} ) ) )[9] ) > 3600 ) {
warn 'Automatic recovery: breaking lock for ' . $this->{file};
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{breaklockCmd},
FILENAME => $this->{file} );
Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{breaklockCmd},
FILENAME => _encode( $this->{file} )
);
( $rcsOutput, $exit ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{lockCmd},
FILENAME => $this->{file} );
FILENAME => _encode( $this->{file} ) );
}
if ($exit) {

Expand All @@ -528,23 +541,23 @@ sub _lock {
. $rcsOutput );
}
}
chmod( $Foswiki::cfg{Store}{filePermission}, $this->{file} );
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{file} ) );
}

# implements Rcs::Handler
sub getRevisionAtTime {
my ( $this, $date ) = @_;

unless ( $this->revisionHistoryExists() ) {
return ( $date >= ( stat( $this->{file} ) )[9] ) ? 1 : undef;
return ( $date >= ( stat( _encode( $this->{file} ) ) )[9] ) ? 1 : undef;
}

require Foswiki::Time;
my $sdate = Foswiki::Time::formatTime( $date, '$rcs', 'gmtime' );
my ( $rcsOutput, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{rlogDateCmd},
DATE => $sdate,
FILENAME => $this->{file}
FILENAME => _encode( $this->{file} )
);

my $version = undef;
Expand All @@ -555,15 +568,15 @@ sub getRevisionAtTime {
if ( $version && !$this->noCheckinPending() ) {

# Check the file date
$version++ if ( $date >= ( stat( $this->{file} ) )[9] );
$version++ if ( $date >= ( stat( _encode( $this->{file} ) ) )[9] );
}
return $version;
}

1;
__END__
Copyright (C) 2008-2009 Foswiki Contributors. All Rights Reserved.
Copyright (C) 2008-2015 Foswiki Contributors. All Rights Reserved.
Foswiki Contributors are listed in the AUTHORS file in the root of
this distribution. NOTE: Please extend that file, not this notice.
Expand Down

0 comments on commit 5a85267

Please sign in to comment.