Fossil SCM

Use function more specific to detecting collisions to catch events, tickets and other types in blob.

andybradford 2014-04-08 04:32 short-uuid
Commit ae6f27004b4210dc6cb60fae806efa11acebccac
2 files changed +23 -17 +27 -25
+23 -17
--- src/info.c
+++ src/info.c
@@ -1890,36 +1890,42 @@
18901890
void info_page(void){
18911891
const char *zName;
18921892
Blob uuid;
18931893
int rid;
18941894
int rc;
1895
+ int nLen;
18951896
18961897
zName = P("name");
18971898
if( zName==0 ) fossil_redirect_home();
1899
+ nLen = strlen(zName);
18981900
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, "*");
19001907
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;
1911
- }
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
+ }
1918
+ }
1919
+ style_header("No Such Object");
1920
+ @ <p>No such object of length %d(nLen): %h(zName)</p>
1921
+ style_footer();
1922
+ return;
19121923
}else if( rc==2 ){
19131924
cgi_set_parameter("src","info");
19141925
ambiguous_page();
19151926
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
- }
19211927
}
19221928
zName = blob_str(&uuid);
19231929
rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
19241930
if( rid==0 ){
19251931
style_header("Broken Link");
19261932
--- src/info.c
+++ src/info.c
@@ -1890,36 +1890,42 @@
1890 void info_page(void){
1891 const char *zName;
1892 Blob uuid;
1893 int rid;
1894 int rc;
 
1895
1896 zName = P("name");
1897 if( zName==0 ) fossil_redirect_home();
 
1898 blob_set(&uuid, zName);
1899 rc = name_to_uuid3(&uuid, -1, "*");
 
 
 
 
 
1900 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;
1911 }
 
 
 
 
1912 }else if( rc==2 ){
1913 cgi_set_parameter("src","info");
1914 ambiguous_page();
1915 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 }
1922 zName = blob_str(&uuid);
1923 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
1924 if( rid==0 ){
1925 style_header("Broken Link");
1926
--- src/info.c
+++ src/info.c
@@ -1890,36 +1890,42 @@
1890 void info_page(void){
1891 const char *zName;
1892 Blob uuid;
1893 int rid;
1894 int rc;
1895 int nLen;
1896
1897 zName = P("name");
1898 if( zName==0 ) fossil_redirect_home();
1899 nLen = strlen(zName);
1900 blob_set(&uuid, zName);
1901 if( name_collisions(zName) ){
1902 cgi_set_parameter("src","info");
1903 ambiguous_page();
1904 return;
1905 }
1906 rc = name_to_uuid(&uuid, -1, "*");
1907 if( rc==1 ){
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 }
1918 }
1919 style_header("No Such Object");
1920 @ <p>No such object of length %d(nLen): %h(zName)</p>
1921 style_footer();
1922 return;
1923 }else if( rc==2 ){
1924 cgi_set_parameter("src","info");
1925 ambiguous_page();
1926 return;
 
 
 
 
 
1927 }
1928 zName = blob_str(&uuid);
1929 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
1930 if( rid==0 ){
1931 style_header("Broken Link");
1932
+27 -25
--- src/name.c
+++ src/name.c
@@ -337,38 +337,40 @@
337337
if((rid>0) && pUuid){
338338
*pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
339339
}
340340
return rid;
341341
}
342
+
342343
343344
/*
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.
349348
*/
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;
370372
}
371373
372374
/*
373375
** COMMAND: test-name-to-id
374376
**
375377
--- src/name.c
+++ src/name.c
@@ -337,38 +337,40 @@
337 if((rid>0) && pUuid){
338 *pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
339 }
340 return rid;
341 }
 
342
343 /*
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.
349 */
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 }
 
 
 
370 }
371
372 /*
373 ** COMMAND: test-name-to-id
374 **
375
--- src/name.c
+++ src/name.c
@@ -337,38 +337,40 @@
337 if((rid>0) && pUuid){
338 *pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
339 }
340 return rid;
341 }
342
343
344 /*
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.
 
 
348 */
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;
372 }
373
374 /*
375 ** COMMAND: test-name-to-id
376 **
377

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button