cvsserver: define a tag name character escape mechanism
CVS tags are officially only allowed to use [-_0-9A-Za-f]. Git refs commonly uses other characters, especially [./]. Such characters need to be escaped from CVS in order to be referenced. This just defines functions to escape/unescape names. The functions are not used yet. Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
1899cbc5b2
commit
51a7e6dbc9
@ -3807,6 +3807,97 @@ sub gethistorydense
|
||||
return $result;
|
||||
}
|
||||
|
||||
=head2 escapeRefName
|
||||
|
||||
Apply an escape mechanism to compensate for characters that
|
||||
git ref names can have that CVS tags can not.
|
||||
|
||||
=cut
|
||||
sub escapeRefName
|
||||
{
|
||||
my($self,$refName)=@_;
|
||||
|
||||
# CVS officially only allows [-_A-Za-z0-9] in tag names (or in
|
||||
# many contexts it can also be a CVS revision number).
|
||||
#
|
||||
# Git tags commonly use '/' and '.' as well, but also handle
|
||||
# anything else just in case:
|
||||
#
|
||||
# = "_-s-" For '/'.
|
||||
# = "_-p-" For '.'.
|
||||
# = "_-u-" For underscore, in case someone wants a literal "_-" in
|
||||
# a tag name.
|
||||
# = "_-xx-" Where "xx" is the hexadecimal representation of the
|
||||
# desired ASCII character byte. (for anything else)
|
||||
|
||||
if(! $refName=~/^[1-9][0-9]*(\.[1-9][0-9]*)*$/)
|
||||
{
|
||||
$refName=~s/_-/_-u--/g;
|
||||
$refName=~s/\./_-p-/g;
|
||||
$refName=~s%/%_-s-%g;
|
||||
$refName=~s/[^-_a-zA-Z0-9]/sprintf("_-%02x-",$1)/eg;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 unescapeRefName
|
||||
|
||||
Undo an escape mechanism to compensate for characters that
|
||||
git ref names can have that CVS tags can not.
|
||||
|
||||
=cut
|
||||
sub unescapeRefName
|
||||
{
|
||||
my($self,$refName)=@_;
|
||||
|
||||
# see escapeRefName() for description of escape mechanism.
|
||||
|
||||
$refName=~s/_-([spu]|[0-9a-f][0-9a-f])-/unescapeRefNameChar($1)/eg;
|
||||
|
||||
# allowed tag names
|
||||
# TODO: Perhaps use git check-ref-format, with an in-process cache of
|
||||
# validated names?
|
||||
if( !( $refName=~m%^[^-][-a-zA-Z0-9_/.]*$% ) ||
|
||||
( $refName=~m%[/.]$% ) ||
|
||||
( $refName=~/\.lock$/ ) ||
|
||||
( $refName=~m%\.\.|/\.|[[\\:?*~]|\@\{% ) ) # matching }
|
||||
{
|
||||
# Error:
|
||||
$log->warn("illegal refName: $refName");
|
||||
$refName=undef;
|
||||
}
|
||||
return $refName;
|
||||
}
|
||||
|
||||
sub unescapeRefNameChar
|
||||
{
|
||||
my($char)=@_;
|
||||
|
||||
if($char eq "s")
|
||||
{
|
||||
$char="/";
|
||||
}
|
||||
elsif($char eq "p")
|
||||
{
|
||||
$char=".";
|
||||
}
|
||||
elsif($char eq "u")
|
||||
{
|
||||
$char="_";
|
||||
}
|
||||
elsif($char=~/^[0-9a-f][0-9a-f]$/)
|
||||
{
|
||||
$char=chr(hex($char));
|
||||
}
|
||||
else
|
||||
{
|
||||
# Error case: Maybe it has come straight from user, and
|
||||
# wasn't supposed to be escaped? Restore it the way we got it:
|
||||
$char="_-$char-";
|
||||
}
|
||||
|
||||
return $char;
|
||||
}
|
||||
|
||||
=head2 in_array()
|
||||
|
||||
from Array::PAT - mimics the in_array() function
|
||||
|
Loading…
Reference in New Issue
Block a user