NUL cannot appear in paths. Even disregarding filesystem path limitations, the tree object format delimits with NUL, so such a path cannot be encoded by Git. When a quoted path is unquoted, it could possibly contain NUL from "\000". Forbid it so it isn't truncated. fast-import still has other issues with NUL, but those will be addressed later. Signed-off-by: Thalia Archibald <thalia@xxxxxxxxxxxxx> --- Documentation/git-fast-import.txt | 1 + builtin/fast-import.c | 2 ++ t/t9300-fast-import.sh | 1 + 3 files changed, 4 insertions(+) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 4aa8ccbefd..411413e8c3 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -657,6 +657,7 @@ and must be in canonical form. That is it must not: The root of the tree can be represented by a quoted empty string (`""`) as `<path>`. +`<path>` cannot contain NUL, either literally or escaped as `\000`. It is recommended that `<path>` always be encoded using UTF-8. `filedelete` diff --git a/builtin/fast-import.c b/builtin/fast-import.c index ae8494d0ac..e36f59084e 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -2283,6 +2283,8 @@ static void parse_path(struct strbuf *sb, const char *p, const char **endp, int if (*p == '"') { if (unquote_c_style(sb, p, endp)) die("Invalid %s: %s", field, command_buf.buf); + if (strlen(sb->buf) != sb->len) + die("NUL in %s: %s", field, command_buf.buf); } else { if (allow_spaces) *endp = p + strlen(p); diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index ef04b43f46..994a80e442 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -3285,6 +3285,7 @@ test_path_fail () { test_path_base_fail () { test_path_fail 'unclosed " in '"$field" '"hello.c' "Invalid $field" test_path_fail "invalid escape in quoted $field" '"hello\xff"' "Invalid $field" + test_path_fail "escaped NUL in quoted $field" '"hello\000"' "NUL in $field" } test_path_eol_quoted_fail () { test_path_base_fail -- 2.44.0