-
Notifications
You must be signed in to change notification settings - Fork 141
Harden the sparse-checkout builtin #513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1cc8254
b7a6ad1
5497ad8
4991a51
ae78c30
2ad4d3e
aace064
66caabe
4c86d01
0b9346f
9f682e6
e2c6f85
54be8e8
3dd8f97
5e9fcce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
#include "resolve-undo.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
|
||
#include "unpack-trees.h" | ||
#include "wt-status.h" | ||
#include "quote.h" | ||
|
||
static const char *empty_base = ""; | ||
|
||
|
@@ -77,8 +78,10 @@ static int sparse_checkout_list(int argc, const char **argv) | |
|
||
string_list_sort(&sl); | ||
|
||
for (i = 0; i < sl.nr; i++) | ||
printf("%s\n", sl.items[i].string); | ||
for (i = 0; i < sl.nr; i++) { | ||
quote_c_style(sl.items[i].string, NULL, stdout, 0); | ||
printf("\n"); | ||
} | ||
|
||
return 0; | ||
} | ||
|
@@ -140,6 +143,22 @@ static int update_working_directory(struct pattern_list *pl) | |
return result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
|
||
} | ||
|
||
static char *escaped_pattern(char *pattern) | ||
{ | ||
char *p = pattern; | ||
struct strbuf final = STRBUF_INIT; | ||
|
||
while (*p) { | ||
if (is_glob_special(*p)) | ||
strbuf_addch(&final, '\\'); | ||
|
||
strbuf_addch(&final, *p); | ||
p++; | ||
} | ||
|
||
return strbuf_detach(&final, NULL); | ||
} | ||
|
||
static void write_cone_to_file(FILE *fp, struct pattern_list *pl) | ||
{ | ||
int i; | ||
|
@@ -164,10 +183,11 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl) | |
fprintf(fp, "/*\n!/*/\n"); | ||
|
||
for (i = 0; i < sl.nr; i++) { | ||
char *pattern = sl.items[i].string; | ||
char *pattern = escaped_pattern(sl.items[i].string); | ||
|
||
if (strlen(pattern)) | ||
fprintf(fp, "%s/\n!%s/*/\n", pattern, pattern); | ||
free(pattern); | ||
} | ||
|
||
string_list_clear(&sl, 0); | ||
|
@@ -185,8 +205,9 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl) | |
string_list_remove_duplicates(&sl, 0); | ||
|
||
for (i = 0; i < sl.nr; i++) { | ||
char *pattern = sl.items[i].string; | ||
char *pattern = escaped_pattern(sl.items[i].string); | ||
fprintf(fp, "%s/\n", pattern); | ||
free(pattern); | ||
} | ||
} | ||
|
||
|
@@ -199,6 +220,10 @@ static int write_patterns_and_update(struct pattern_list *pl) | |
int result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Junio C Hamano wrote (reply to this):
|
||
|
||
sparse_filename = get_sparse_checkout_filename(); | ||
|
||
if (safe_create_leading_directories(sparse_filename)) | ||
die(_("failed to create directory for sparse-checkout file")); | ||
|
||
fd = hold_lock_file_for_update(&lk, sparse_filename, | ||
LOCK_DIE_ON_ERROR); | ||
|
||
|
@@ -419,8 +444,21 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) | |
pl.use_cone_patterns = 1; | ||
|
||
if (set_opts.use_stdin) { | ||
while (!strbuf_getline(&line, stdin)) | ||
struct strbuf unquoted = STRBUF_INIT; | ||
while (!strbuf_getline(&line, stdin)) { | ||
if (line.buf[0] == '"') { | ||
strbuf_reset(&unquoted); | ||
if (unquote_c_style(&unquoted, line.buf, NULL)) | ||
die(_("unable to unquote C-style string '%s'"), | ||
line.buf); | ||
|
||
strbuf_swap(&unquoted, &line); | ||
} | ||
|
||
strbuf_to_cone_pattern(&line, &pl); | ||
} | ||
|
||
strbuf_release(&unquoted); | ||
} else { | ||
for (i = 0; i < argc; i++) { | ||
strbuf_setlen(&line, 0); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -630,11 +630,42 @@ int pl_hashmap_cmp(const void *unused_cmp_data, | |
return strncmp(ee1->pattern, ee2->pattern, min_len); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this):
|
||
} | ||
|
||
static char *dup_and_filter_pattern(const char *pattern) | ||
{ | ||
char *set, *read; | ||
size_t count = 0; | ||
char *result = xstrdup(pattern); | ||
|
||
set = result; | ||
read = result; | ||
|
||
while (*read) { | ||
/* skip escape characters (once) */ | ||
if (*read == '\\') | ||
read++; | ||
|
||
*set = *read; | ||
|
||
set++; | ||
read++; | ||
count++; | ||
} | ||
*set = 0; | ||
|
||
if (count > 2 && | ||
*(set - 1) == '*' && | ||
*(set - 2) == '/') | ||
*(set - 2) = 0; | ||
|
||
return result; | ||
} | ||
|
||
static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern *given) | ||
{ | ||
struct pattern_entry *translated; | ||
char *truncated; | ||
char *data = NULL; | ||
const char *prev, *cur, *next; | ||
|
||
if (!pl->use_cone_patterns) | ||
return; | ||
|
@@ -651,17 +682,57 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern | |
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Jeff King wrote (reply to this):
|
||
} | ||
|
||
if (given->patternlen <= 2 || | ||
*given->pattern == '*' || | ||
strstr(given->pattern, "**")) { | ||
/* Not a cone pattern. */ | ||
warning(_("unrecognized pattern: '%s'"), given->pattern); | ||
goto clear_hashmaps; | ||
} | ||
|
||
prev = given->pattern; | ||
cur = given->pattern + 1; | ||
next = given->pattern + 2; | ||
|
||
while (*cur) { | ||
/* Watch for glob characters '*', '\', '[', '?' */ | ||
if (!is_glob_special(*cur)) | ||
goto increment; | ||
|
||
/* But only if *prev != '\\' */ | ||
if (*prev == '\\') | ||
goto increment; | ||
|
||
/* But allow the initial '\' */ | ||
if (*cur == '\\' && | ||
is_glob_special(*next)) | ||
goto increment; | ||
|
||
/* But a trailing '/' then '*' is fine */ | ||
if (*prev == '/' && | ||
*cur == '*' && | ||
*next == 0) | ||
goto increment; | ||
|
||
/* Not a cone pattern. */ | ||
warning(_("unrecognized pattern: '%s'"), given->pattern); | ||
goto clear_hashmaps; | ||
|
||
increment: | ||
prev++; | ||
cur++; | ||
next++; | ||
} | ||
|
||
if (given->patternlen > 2 && | ||
!strcmp(given->pattern + given->patternlen - 2, "/*")) { | ||
if (!(given->flags & PATTERN_FLAG_NEGATIVE)) { | ||
/* Not a cone pattern. */ | ||
pl->use_cone_patterns = 0; | ||
warning(_("unrecognized pattern: '%s'"), given->pattern); | ||
goto clear_hashmaps; | ||
} | ||
|
||
truncated = xstrdup(given->pattern); | ||
truncated[given->patternlen - 2] = 0; | ||
truncated = dup_and_filter_pattern(given->pattern); | ||
|
||
translated = xmalloc(sizeof(struct pattern_entry)); | ||
translated->pattern = truncated; | ||
|
@@ -695,7 +766,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern | |
|
||
translated = xmalloc(sizeof(struct pattern_entry)); | ||
|
||
translated->pattern = xstrdup(given->pattern); | ||
translated->pattern = dup_and_filter_pattern(given->pattern); | ||
translated->patternlen = given->patternlen; | ||
hashmap_entry_init(&translated->ent, | ||
ignore_case ? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Taylor Blau wrote (reply to this):