mirror of
https://github.com/git/git.git
synced 2024-05-12 19:56:08 +02:00
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;
|
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()
|
=head2 in_array()
|
||||||
|
|
||||||
from Array::PAT - mimics the in_array() function
|
from Array::PAT - mimics the in_array() function
|
||||||
|
|
Loading…
Reference in New Issue