Fossil SCM
It turns out that filenames in git-fast-export format can be quoted, if they contain special characters. Update the importer to dequote those names before trying to use them.
Commit
77cbe38af027ae728980622cf7a797088dfd0b79
Parent
f02946aa8b4e271…
1 file changed
+19
+19
| --- src/import.c | ||
| +++ src/import.c | ||
| @@ -452,10 +452,27 @@ | ||
| 452 | 452 | i++; |
| 453 | 453 | } |
| 454 | 454 | return 0; |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | +/* | |
| 458 | +** Dequote a fast-export filename. Filenames are normally unquoted. But | |
| 459 | +** if the contain some obscure special characters, quotes might be added. | |
| 460 | +*/ | |
| 461 | +static dequote_git_filename(char *zName){ | |
| 462 | + int n, i, j; | |
| 463 | + if( zName==0 || zName[0]!='"' ) return; | |
| 464 | + n = (int)strlen(zName); | |
| 465 | + if( zName[n-1]!='"' ) return; | |
| 466 | + for(i=0, j=1; j<n-1; j++){ | |
| 467 | + char c = zName[j]; | |
| 468 | + if( c=='\\' ) c = zName[++j]; | |
| 469 | + zName[i++] = c; | |
| 470 | + } | |
| 471 | + zName[i] = 0; | |
| 472 | +} | |
| 473 | + | |
| 457 | 474 | |
| 458 | 475 | /* |
| 459 | 476 | ** Read the git-fast-import format from pIn and insert the corresponding |
| 460 | 477 | ** content into the database. |
| 461 | 478 | */ |
| @@ -596,10 +613,11 @@ | ||
| 596 | 613 | import_prior_files(); |
| 597 | 614 | z = &zLine[2]; |
| 598 | 615 | zPerm = next_token(&z); |
| 599 | 616 | zUuid = next_token(&z); |
| 600 | 617 | zName = rest_of_line(&z); |
| 618 | + dequote_git_filename(zName); | |
| 601 | 619 | i = 0; |
| 602 | 620 | pFile = import_find_file(zName, &i, gg.nFile); |
| 603 | 621 | if( pFile==0 ){ |
| 604 | 622 | pFile = import_add_file(); |
| 605 | 623 | pFile->zName = fossil_strdup(zName); |
| @@ -612,10 +630,11 @@ | ||
| 612 | 630 | }else |
| 613 | 631 | if( memcmp(zLine, "D ", 2)==0 ){ |
| 614 | 632 | import_prior_files(); |
| 615 | 633 | z = &zLine[2]; |
| 616 | 634 | zName = rest_of_line(&z); |
| 635 | + dequote_git_filename(zName); | |
| 617 | 636 | i = 0; |
| 618 | 637 | while( (pFile = import_find_file(zName, &i, gg.nFile))!=0 ){ |
| 619 | 638 | if( pFile->isFrom==0 ) continue; |
| 620 | 639 | fossil_free(pFile->zName); |
| 621 | 640 | fossil_free(pFile->zPrior); |
| 622 | 641 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -452,10 +452,27 @@ | |
| 452 | i++; |
| 453 | } |
| 454 | return 0; |
| 455 | } |
| 456 | |
| 457 | |
| 458 | /* |
| 459 | ** Read the git-fast-import format from pIn and insert the corresponding |
| 460 | ** content into the database. |
| 461 | */ |
| @@ -596,10 +613,11 @@ | |
| 596 | import_prior_files(); |
| 597 | z = &zLine[2]; |
| 598 | zPerm = next_token(&z); |
| 599 | zUuid = next_token(&z); |
| 600 | zName = rest_of_line(&z); |
| 601 | i = 0; |
| 602 | pFile = import_find_file(zName, &i, gg.nFile); |
| 603 | if( pFile==0 ){ |
| 604 | pFile = import_add_file(); |
| 605 | pFile->zName = fossil_strdup(zName); |
| @@ -612,10 +630,11 @@ | |
| 612 | }else |
| 613 | if( memcmp(zLine, "D ", 2)==0 ){ |
| 614 | import_prior_files(); |
| 615 | z = &zLine[2]; |
| 616 | zName = rest_of_line(&z); |
| 617 | i = 0; |
| 618 | while( (pFile = import_find_file(zName, &i, gg.nFile))!=0 ){ |
| 619 | if( pFile->isFrom==0 ) continue; |
| 620 | fossil_free(pFile->zName); |
| 621 | fossil_free(pFile->zPrior); |
| 622 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -452,10 +452,27 @@ | |
| 452 | i++; |
| 453 | } |
| 454 | return 0; |
| 455 | } |
| 456 | |
| 457 | /* |
| 458 | ** Dequote a fast-export filename. Filenames are normally unquoted. But |
| 459 | ** if the contain some obscure special characters, quotes might be added. |
| 460 | */ |
| 461 | static dequote_git_filename(char *zName){ |
| 462 | int n, i, j; |
| 463 | if( zName==0 || zName[0]!='"' ) return; |
| 464 | n = (int)strlen(zName); |
| 465 | if( zName[n-1]!='"' ) return; |
| 466 | for(i=0, j=1; j<n-1; j++){ |
| 467 | char c = zName[j]; |
| 468 | if( c=='\\' ) c = zName[++j]; |
| 469 | zName[i++] = c; |
| 470 | } |
| 471 | zName[i] = 0; |
| 472 | } |
| 473 | |
| 474 | |
| 475 | /* |
| 476 | ** Read the git-fast-import format from pIn and insert the corresponding |
| 477 | ** content into the database. |
| 478 | */ |
| @@ -596,10 +613,11 @@ | |
| 613 | import_prior_files(); |
| 614 | z = &zLine[2]; |
| 615 | zPerm = next_token(&z); |
| 616 | zUuid = next_token(&z); |
| 617 | zName = rest_of_line(&z); |
| 618 | dequote_git_filename(zName); |
| 619 | i = 0; |
| 620 | pFile = import_find_file(zName, &i, gg.nFile); |
| 621 | if( pFile==0 ){ |
| 622 | pFile = import_add_file(); |
| 623 | pFile->zName = fossil_strdup(zName); |
| @@ -612,10 +630,11 @@ | |
| 630 | }else |
| 631 | if( memcmp(zLine, "D ", 2)==0 ){ |
| 632 | import_prior_files(); |
| 633 | z = &zLine[2]; |
| 634 | zName = rest_of_line(&z); |
| 635 | dequote_git_filename(zName); |
| 636 | i = 0; |
| 637 | while( (pFile = import_find_file(zName, &i, gg.nFile))!=0 ){ |
| 638 | if( pFile->isFrom==0 ) continue; |
| 639 | fossil_free(pFile->zName); |
| 640 | fossil_free(pFile->zPrior); |
| 641 |