Fossil SCM

Show short UUID collisions also for tickets and not just ticket changes. Reported on ML.

andybradford 2014-04-06 04:51 trunk
Commit 0066d6c6a9afe510e3b26ae4c123e692b1717496
2 files changed +17 -15 +70 -1
+17 -15
--- src/info.c
+++ src/info.c
@@ -1893,31 +1893,33 @@
18931893
int rid;
18941894
int rc;
18951895
18961896
zName = P("name");
18971897
if( zName==0 ) fossil_redirect_home();
1898
- if( validate16(zName, strlen(zName)) ){
1899
- if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
1900
- tktview_page();
1901
- return;
1902
- }
1903
- if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){
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) ){
19041904
event_page();
19051905
return;
1906
- }
1907
- }
1908
- blob_set(&uuid, zName);
1909
- rc = name_to_uuid(&uuid, -1, "*");
1910
- if( rc==1 ){
1911
- style_header("No Such Object");
1912
- @ <p>No such object: %h(zName)</p>
1913
- style_footer();
1914
- return;
1906
+ }else{
1907
+ style_header("No Such Object");
1908
+ @ <p>No such object: %h(zName)</p>
1909
+ style_footer();
1910
+ return;
1911
+ }
19151912
}else if( rc==2 ){
19161913
cgi_set_parameter("src","info");
19171914
ambiguous_page();
19181915
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
+ }
19191921
}
19201922
zName = blob_str(&uuid);
19211923
rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
19221924
if( rid==0 ){
19231925
style_header("Broken Link");
19241926
--- src/info.c
+++ src/info.c
@@ -1893,31 +1893,33 @@
1893 int rid;
1894 int rc;
1895
1896 zName = P("name");
1897 if( zName==0 ) fossil_redirect_home();
1898 if( validate16(zName, strlen(zName)) ){
1899 if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
1900 tktview_page();
1901 return;
1902 }
1903 if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){
1904 event_page();
1905 return;
1906 }
1907 }
1908 blob_set(&uuid, zName);
1909 rc = name_to_uuid(&uuid, -1, "*");
1910 if( rc==1 ){
1911 style_header("No Such Object");
1912 @ <p>No such object: %h(zName)</p>
1913 style_footer();
1914 return;
1915 }else if( rc==2 ){
1916 cgi_set_parameter("src","info");
1917 ambiguous_page();
1918 return;
 
 
 
 
 
1919 }
1920 zName = blob_str(&uuid);
1921 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
1922 if( rid==0 ){
1923 style_header("Broken Link");
1924
--- src/info.c
+++ src/info.c
@@ -1893,31 +1893,33 @@
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
+70 -1
--- src/name.c
+++ src/name.c
@@ -266,10 +266,30 @@
266266
}
267267
}
268268
return rid;
269269
}
270270
271
+/*
272
+** Return the ticket id from the ticket table if found. If more than one
273
+** is found, return -1 to indicate ambiguity.
274
+*/
275
+int symbolic_name_to_tktid(const char *zTag){
276
+ int tktid = 0;
277
+ Stmt q;
278
+
279
+ if( strlen(zTag)>=4 &&
280
+ strlen(zTag)<=UUID_SIZE && validate16(zTag, strlen(zTag)) ) {
281
+ db_prepare(&q, "SELECT tkt_id FROM ticket"
282
+ " WHERE tkt_uuid GLOB '%s*'", zTag );
283
+ if( db_step(&q)==SQLITE_ROW ){
284
+ tktid = db_column_int(&q, 0);
285
+ if( db_step(&q)==SQLITE_ROW ) tktid = -1;
286
+ }
287
+ db_finalize(&q);
288
+ }
289
+ return tktid;
290
+}
271291
272292
/*
273293
** This routine takes a user-entered UUID which might be in mixed
274294
** case and might only be a prefix of the full UUID and converts it
275295
** into the full-length UUID in canonical form.
@@ -318,11 +338,38 @@
318338
*pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
319339
}
320340
return rid;
321341
}
322342
323
-
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
+}
324371
325372
/*
326373
** COMMAND: test-name-to-id
327374
**
328375
** Convert a name to a full artifact ID.
@@ -406,10 +453,32 @@
406453
int rid = db_column_int(&q, 1);
407454
@ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)">
408455
@ %s(zUuid)</a> -
409456
object_description(rid, 0, 0);
410457
@ </p></li>
458
+ }
459
+ db_finalize(&q);
460
+ db_prepare(&q, " SELECT tkt_rid, tkt_uuid, title"
461
+ " FROM ticket, ticketchng"
462
+ " WHERE ticket.tkt_id = ticketchng.tkt_id"
463
+ " AND tkt_uuid GLOB '%q*'"
464
+ " GROUP BY tkt_uuid"
465
+ " ORDER BY tkt_ctime DESC", z);
466
+ while( db_step(&q)==SQLITE_ROW ){
467
+ int rid = db_column_int(&q, 0);
468
+ const char *zUuid = db_column_text(&q, 1);
469
+ const char *zTitle = db_column_text(&q, 2);
470
+ @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)">
471
+ @ %s(zUuid)</a> -
472
+ @ <ul></ul>
473
+ @ Ticket
474
+ hyperlink_to_uuid(zUuid);
475
+ @ - %s(zTitle).
476
+ @ <ul><li>
477
+ object_description(rid, 0, 0);
478
+ @ </li></ul>
479
+ @ </p></li>
411480
}
412481
@ </ol>
413482
db_finalize(&q);
414483
style_footer();
415484
}
416485
--- src/name.c
+++ src/name.c
@@ -266,10 +266,30 @@
266 }
267 }
268 return rid;
269 }
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
272 /*
273 ** This routine takes a user-entered UUID which might be in mixed
274 ** case and might only be a prefix of the full UUID and converts it
275 ** into the full-length UUID in canonical form.
@@ -318,11 +338,38 @@
318 *pUuid = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
319 }
320 return rid;
321 }
322
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
325 /*
326 ** COMMAND: test-name-to-id
327 **
328 ** Convert a name to a full artifact ID.
@@ -406,10 +453,32 @@
406 int rid = db_column_int(&q, 1);
407 @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)">
408 @ %s(zUuid)</a> -
409 object_description(rid, 0, 0);
410 @ </p></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411 }
412 @ </ol>
413 db_finalize(&q);
414 style_footer();
415 }
416
--- src/name.c
+++ src/name.c
@@ -266,10 +266,30 @@
266 }
267 }
268 return rid;
269 }
270
271 /*
272 ** Return the ticket id from the ticket table if found. If more than one
273 ** is found, return -1 to indicate ambiguity.
274 */
275 int symbolic_name_to_tktid(const char *zTag){
276 int tktid = 0;
277 Stmt q;
278
279 if( strlen(zTag)>=4 &&
280 strlen(zTag)<=UUID_SIZE && validate16(zTag, strlen(zTag)) ) {
281 db_prepare(&q, "SELECT tkt_id FROM ticket"
282 " WHERE tkt_uuid GLOB '%s*'", zTag );
283 if( db_step(&q)==SQLITE_ROW ){
284 tktid = db_column_int(&q, 0);
285 if( db_step(&q)==SQLITE_ROW ) tktid = -1;
286 }
287 db_finalize(&q);
288 }
289 return tktid;
290 }
291
292 /*
293 ** This routine takes a user-entered UUID which might be in mixed
294 ** case and might only be a prefix of the full UUID and converts it
295 ** into the full-length UUID in canonical form.
@@ -318,11 +338,38 @@
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 ** Convert a name to a full artifact ID.
@@ -406,10 +453,32 @@
453 int rid = db_column_int(&q, 1);
454 @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)">
455 @ %s(zUuid)</a> -
456 object_description(rid, 0, 0);
457 @ </p></li>
458 }
459 db_finalize(&q);
460 db_prepare(&q, " SELECT tkt_rid, tkt_uuid, title"
461 " FROM ticket, ticketchng"
462 " WHERE ticket.tkt_id = ticketchng.tkt_id"
463 " AND tkt_uuid GLOB '%q*'"
464 " GROUP BY tkt_uuid"
465 " ORDER BY tkt_ctime DESC", z);
466 while( db_step(&q)==SQLITE_ROW ){
467 int rid = db_column_int(&q, 0);
468 const char *zUuid = db_column_text(&q, 1);
469 const char *zTitle = db_column_text(&q, 2);
470 @ <li><p><a href="%s(g.zTop)/%T(zSrc)/%s(zUuid)">
471 @ %s(zUuid)</a> -
472 @ <ul></ul>
473 @ Ticket
474 hyperlink_to_uuid(zUuid);
475 @ - %s(zTitle).
476 @ <ul><li>
477 object_description(rid, 0, 0);
478 @ </li></ul>
479 @ </p></li>
480 }
481 @ </ol>
482 db_finalize(&q);
483 style_footer();
484 }
485

Keyboard Shortcuts

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