git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 13/20] cvsserver: define a tag name character escape mechanism

From
MOMatthew Ogilvie <mmogilvi_git@miniinfo.net>
Date
Oct 14, 2012, 05:42 UTC
Message-ID
<1350193353-19210-14-git-send-email-mmogilvi_git@miniinfo.net>
In-Reply-To
<1350193353-19210-1-git-send-email-mmogilvi_git@miniinfo.net>

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>
---
 git-cvsserver.perl | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 1d929df..4eecc0b 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -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
-- 
1.7.10.2.484.gcd07cc5
Previous: Matthew OgilvieNext: Matthew Ogilvie
Message 14 of 22 in “git-cvsserver: add support for cvs "-r" refs”
  1. 00/20 git-cvsserver: add support for cvs "-r" refsMatthew Ogilvie, Oct 14, 2012
  2. 01/20 cvsserver t9400: add basic 'cvs log' testMatthew Ogilvie, Oct 14, 2012
  3. 02/20 cvsserver: removed unused sha1Or-k mode from kopts_from_pathMatthew Ogilvie, Oct 14, 2012
  4. 03/20 cvsserver: add comments about database schema/usageMatthew Ogilvie, Oct 14, 2012
  5. 04/20 cvsserver update: comment about how we shouldn't remove a user-modified fileMatthew Ogilvie, Oct 14, 2012
  6. 05/20 cvsserver: remove unused functions _headrev and gethistoryMatthew Ogilvie, Oct 14, 2012
  7. 06/20 cvsserver: clean up client request handler map commentsMatthew Ogilvie, Oct 14, 2012
  8. 07/20 cvsserver: split up long lines in req_{status,diff,log}Matthew Ogilvie, Oct 14, 2012
  9. 08/20 cvsserver: use whole CVS rev number in-process; don't strip "1." prefixMatthew Ogilvie, Oct 14, 2012
  10. 09/20 cvsserver: cvs add: do not expand directory argumentsMatthew Ogilvie, Oct 14, 2012
  11. 10/20 cvsserver status: provide real sticky infoMatthew Ogilvie, Oct 14, 2012
  12. 11/20 cvsserver: factor out git-log parsing logicMatthew Ogilvie, Oct 14, 2012
  13. 12/20 cvsserver: cleanup extra slashes in filename argumentsMatthew Ogilvie, Oct 14, 2012
  14. 13/20 cvsserver: define a tag name character escape mechanismMatthew Ogilvie, Oct 14, 2012
  15. 14/20 cvsserver: add misc commit lookup, file meta data, and file listing functionsMatthew Ogilvie, Oct 14, 2012
  16. 15/20 cvsserver: implement req_Sticky and related utilitiesMatthew Ogilvie, Oct 14, 2012
  17. 16/20 cvsserver: generalize getmeta() to recognize commit refsMatthew Ogilvie, Oct 14, 2012
  18. 17/20 cvsserver: Add version awareness to argsfromdirMatthew Ogilvie, Oct 14, 2012
  19. 18/20 cvsserver: support -r and sticky tags for most operationsMatthew Ogilvie, Oct 14, 2012
  20. 19/20 cvsserver: add t9402 to test branch and tag refsMatthew Ogilvie, Oct 14, 2012
  21. 20/20 cvsserver Documentation: new cvs ... -r supportMatthew Ogilvie, Oct 14, 2012
  22. Junio C HamanoOct 16, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.