Fossil

Check-in [ae6f2700]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use function more specific to detecting collisions to catch events, tickets and other types in blob.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | short-uuid
Files: files | file ages | folders
SHA1:ae6f27004b4210dc6cb60fae806efa11acebccac
User & Date: andybradford 2014-04-08 04:32:39
Context
2014-04-08
04:34
This function also is no longer needed at this point. check-in: 8b9b4451 user: andybradford tags: short-uuid
04:32
Use function more specific to detecting collisions to catch events, tickets and other types in blob. check-in: ae6f2700 user: andybradford tags: short-uuid
2014-04-06
04:51
Show short UUID collisions also for tickets and not just ticket changes. Reported on ML. check-in: 0066d6c6 user: andybradford tags: short-uuid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/info.c.

  1888   1888   ** Figure out what the artifact ID is and jump to it.
  1889   1889   */
  1890   1890   void info_page(void){
  1891   1891     const char *zName;
  1892   1892     Blob uuid;
  1893   1893     int rid;
  1894   1894     int rc;
         1895  +  int nLen;
  1895   1896   
  1896   1897     zName = P("name");
  1897   1898     if( zName==0 ) fossil_redirect_home();
         1899  +  nLen = strlen(zName);
  1898   1900     blob_set(&uuid, zName);
  1899         -  rc = name_to_uuid3(&uuid, -1, "*");
         1901  +  if( name_collisions(zName) ){
         1902  +    cgi_set_parameter("src","info");
         1903  +    ambiguous_page();
         1904  +    return;
         1905  +  }
         1906  +  rc = name_to_uuid(&uuid, -1, "*");
  1900   1907     if( rc==1 ){
  1901         -    if( validate16(zName, strlen(zName)) &&
  1902         -        db_exists("SELECT 1 FROM tag"
  1903         -                  " WHERE tagname GLOB 'event-%q*'", zName) ){
  1904         -      event_page();
  1905         -      return;
  1906         -    }else{
  1907         -      style_header("No Such Object");
  1908         -      @ <p>No such object: %h(zName)</p>
  1909         -      style_footer();
  1910         -      return;
         1908  +    if( validate16(zName, nLen) ){
         1909  +      if( db_exists("SELECT 1 FROM tag"
         1910  +                    " WHERE tagname GLOB 'event-%q*'", zName) ){
         1911  +        event_page();
         1912  +        return;
         1913  +      }
         1914  +      if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
         1915  +        tktview_page();
         1916  +        return;
         1917  +      }
  1911   1918       }
         1919  +    style_header("No Such Object");
         1920  +    @ <p>No such object of length %d(nLen): %h(zName)</p>
         1921  +    style_footer();
         1922  +    return;
  1912   1923     }else if( rc==2 ){
  1913   1924       cgi_set_parameter("src","info");
  1914   1925       ambiguous_page();
  1915   1926       return;
  1916         -  }else if( rc==3 && validate16(zName, strlen(zName)) ){
  1917         -    if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
  1918         -      tktview_page();
  1919         -      return;
  1920         -    }
  1921   1927     }
  1922   1928     zName = blob_str(&uuid);
  1923   1929     rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
  1924   1930     if( rid==0 ){
  1925   1931       style_header("Broken Link");
  1926   1932       @ <p>No such object: %h(zName)</p>
  1927   1933       style_footer();

Changes to src/name.c.

   335    335   int name_to_uuid2(char const *zName, const char *zType, char **pUuid){
   336    336     int rid = symbolic_name_to_rid(zName, zType);
   337    337     if((rid>0) && pUuid){
   338    338       *pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
   339    339     }
   340    340     return rid;
   341    341   }
          342  +
   342    343   
   343    344   /*
   344         -** This routine is similar to name_to_uuid() except it also accounts for
   345         -** collisions in tickets which don't have an entry in blob (only associated
   346         -** ticket changes).
   347         -** Return 0 if rid is found.  Return 1 if neither rid nor tkt_id is found.
   348         -** Return 2 if name is ambiguous.  Return 3 if tkt_id is found.
          345  +** name_collisions searches through events, blobs, and tickets for
          346  +** collisions of a given UUID based on its length on UUIDs no shorter
          347  +** than 4 characters in length.
   349    348   */
   350         -int name_to_uuid3(Blob *pName, int iErrPriority, const char *zType){
   351         -  char *zName = blob_str(pName);
   352         -  int tkt_id = 0;
   353         -  int rid = symbolic_name_to_rid(zName, zType);
   354         -  if( zType && zType[0]=='*' ){
   355         -    tkt_id = symbolic_name_to_tktid(zName);
   356         -  }
   357         -  if( rid<0 || tkt_id<0 || (rid>0 && tkt_id>0) ){
   358         -    fossil_error(iErrPriority, "ambiguous name: %s", zName);
   359         -    return 2;
   360         -  }else if( rid==0 && tkt_id==0 ){
   361         -    fossil_error(iErrPriority, "not found: %s", zName);
   362         -    return 1;
   363         -  }else if( tkt_id>0 ){
   364         -    return 3;
   365         -  }else{
   366         -    blob_reset(pName);
   367         -    db_blob(pName, "SELECT uuid FROM blob WHERE rid=%d", rid);
   368         -    return 0;
   369         -  }
          349  +int name_collisions(const char *zName){
          350  +  Stmt q;
          351  +  int c = 0;         /* count of collisions for zName */
          352  +  int nLen;          /* length of zName */
          353  +  nLen = strlen(zName);
          354  +  if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
          355  +    db_prepare(&q,
          356  +      "SELECT count(uuid) FROM"
          357  +      "  (SELECT substr(tkt_uuid, 1, %d) AS uuid FROM ticket"
          358  +      "   UNION ALL SELECT * FROM"
          359  +      "     (SELECT substr(tagname, 7, %d) FROM"
          360  +      "       tag WHERE tagname GLOB 'event-*')"
          361  +      "   UNION ALL SELECT * FROM"
          362  +      "     (SELECT substr(uuid, 1, %d) FROM blob))"
          363  +      "  WHERE uuid GLOB '%q*'"
          364  +      "  GROUP BY uuid HAVING count(uuid) > 1;",
          365  +      nLen, nLen, nLen, zName);
          366  +    if( db_step(&q)==SQLITE_ROW ){
          367  +      c = db_column_int(&q, 0);
          368  +    }
          369  +    db_finalize(&q);
          370  +  }
          371  +  return c;
   370    372   }
   371    373   
   372    374   /*
   373    375   ** COMMAND:  test-name-to-id
   374    376   **
   375    377   ** Convert a name to a full artifact ID.
   376    378   */