Re: [fossil-users] Branch and Tag names in export

2017-02-09 Thread Roy Marples
On 09/02/2017 15:06, Joerg Sonnenberger wrote:
> On Thu, Feb 09, 2017 at 01:47:43PM +, Roy Marples wrote:
>> Hi List!
>>
>> In fossil I have this: branch-1.7, tag-1.2
>> But when I export I get this: branch_1_7, tag_1_2
>>
>> Why is the name mangled like so? Surely the original names should be
>> preserved.
> 
> It's currently preserving only alphanumeric characters. Noone ever
> implemented the full sanitation requirement of git.

Attached is a patch with implements sanity checking as per
https://git-scm.com/docs/git-check-ref-format

Applies with my prior patch.

Roy
Index: src/export.c
==
--- src/export.c
+++ src/export.c
@@ -161,10 +161,68 @@
   printf(" %s <%s>", zName, zEmail);
   free(zName);
   free(zEmail);
   db_reset();
 }
+
+#define REFREPLACEMENT '_'
+
+/*
+** Output a sanitized git named reference.
+** https://git-scm.com/docs/git-check-ref-format
+** This implementation assumes we are only printing
+** the branch or tag part of the reference.
+*/
+static void print_ref(const char *zRef){
+  char *zEncoded = mprintf("%s", zRef);
+  int i, w;
+  if (zEncoded[0]=='@' && zEncoded[1]=='\0'){
+putchar(REFREPLACEMENT);
+return;
+  }
+  for(i=0, w=0; zEncoded[i]; i++, w++){
+if( i!=0 ){ /* Two letter tests */
+  if( (zEncoded[i-1]=='.' && zEncoded[i]=='.') ||
+  (zEncoded[i-1]=='@' && zEncoded[i]=='{') ){
+zEncoded[w]=zEncoded[w-1]=REFREPLACEMENT;
+continue;
+  }
+  if( zEncoded[i-1]=='/' && zEncoded[i]=='/' ){
+w--; /* Normalise to a single / by rolling back w */
+continue;
+  }
+}
+/* No control characters */
+if( (unsigned)zEncoded[i]<0x20 || zEncoded[i]==0x7f ){
+  zEncoded[w]=REFREPLACEMENT;
+  continue;
+}
+switch( zEncoded[i] ){
+  case ' ':
+  case '^':
+  case ':':
+  case '?':
+  case '*':
+  case '[':
+  case '\\':
+zEncoded[w]=REFREPLACEMENT;
+   break;
+}
+  }
+  /* Cannot begin with a . or / */
+  if( zEncoded[0]=='.' || zEncoded[0] == '/' ) zEncoded[0]=REFREPLACEMENT;
+  if( i>0 ){
+i--; w--;
+/* Or end with a . or / */
+if( zEncoded[i]=='.' || zEncoded[i] == '/' ) zEncoded[w]=REFREPLACEMENT;
+/* Cannot end with .lock */
+if ( i>4 && strcmp((zEncoded+i)-5, ".lock")==0 )
+  memset((zEncoded+w)-5, REFREPLACEMENT, 5);
+  }
+  printf("%s", zEncoded);
+  free(zEncoded);
+}
 
 #define BLOBMARK(rid)   ((rid) * 2)
 #define COMMITMARK(rid) ((rid) * 2 + 1)
 
 /*
@@ -547,26 +605,22 @@
 const char *zSecondsSince1970 = db_column_text(, 0);
 int ckinId = db_column_int(, 1);
 const char *zComment = db_column_text(, 2);
 const char *zUser = db_column_text(, 3);
 const char *zBranch = db_column_text(, 4);
-char *zBr;
 char *zMark;
 
 bag_insert(, ckinId);
 db_bind_int(, ":rid", ckinId);
 db_step();
 db_reset();
 if( zBranch==0 ) zBranch = "trunk";
-zBr = mprintf("%s", zBranch);
-for(i=0; zBr[i]; i++){
-  if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_';
-}
 zMark = mark_name_from_rid(ckinId, _mark);
-printf("commit refs/heads/%s\nmark %s\n", zBr, zMark);
+printf("commit refs/heads/");
+print_ref(zBranch);
+printf("\nmark %s\n", zMark);
 free(zMark);
-free(zBr);
 printf("committer");
 print_person(zUser);
 printf(" %s +\n", zSecondsSince1970);
 if( zComment==0 ) zComment = "null comment";
 printf("data %d\n%s\n", (int)strlen(zComment), zComment);
@@ -637,30 +691,24 @@
  "  FROM tagxref JOIN tag USING(tagid)"
  " WHERE tagtype=1 AND tagname GLOB 'sym-*'"
   );
   while( db_step()==SQLITE_ROW ){
 const char *zTagname = db_column_text(, 0);
-char *zEncoded = 0;
 int rid = db_column_int(, 1);
 char *zMark = mark_name_from_rid(rid, _mark);
 const char *zSecSince1970 = db_column_text(, 2);
 const char *zUser = db_column_text(, 3);
-int i;
 if( rid==0 || !bag_find(, rid) ) continue;
 zTagname += 4;
-zEncoded = mprintf("%s", zTagname);
-for(i=0; zEncoded[i]; i++){
-  if( !fossil_isalnum(zEncoded[i]) ) zEncoded[i] = '_';
-}
-printf("tag %s\n", zEncoded);
-printf("from %s\n", zMark);
+printf("tag ");
+print_ref(zTagname);
+printf("\nfrom %s\n", zMark);
 free(zMark);
 printf("tagger");
 print_person(zUser);
 printf(" %s +\n", zSecSince1970);
 printf("data 0\n");
-fossil_free(zEncoded);
   }
   db_finalize();
 
   if( markfile_out!=0 ){
 FILE *f;

___
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users


Re: [fossil-users] Branch and Tag names in export

2017-02-09 Thread Joerg Sonnenberger
On Thu, Feb 09, 2017 at 01:47:43PM +, Roy Marples wrote:
> Hi List!
> 
> In fossil I have this: branch-1.7, tag-1.2
> But when I export I get this: branch_1_7, tag_1_2
> 
> Why is the name mangled like so? Surely the original names should be
> preserved.

It's currently preserving only alphanumeric characters. Noone ever
implemented the full sanitation requirement of git.

Joerg
___
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users


Re: [fossil-users] Branch and Tag names in export

2017-02-09 Thread Warren Young
On Feb 9, 2017, at 6:47 AM, Roy Marples  wrote:
> 
> In fossil I have this: branch-1.7, tag-1.2
> But when I export I get this: branch_1_7, tag_1_2
> 
> Why is the name mangled like so? Surely the original names should be
> preserved.

I assume it’s a “feature” of fossil export --git because Git itself doesn’t 
seem to care, evidenced by:

$ git check-ref-format --normalize tags/branch-1.7

Please verify this there, too, in case there is a relevant version or 
configuration difference between our sites.

If your site allows that tag name, I propose that Fossil use the same rules 
check-ref-format does.
___
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users