]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Sync with Git 2.31.6
authorJunio C Hamano <gitster@pobox.com>
Tue, 13 Dec 2022 12:09:40 +0000 (21:09 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Dec 2022 12:09:40 +0000 (21:09 +0900)
1  2 
attr.c
attr.h
git-compat-util.h
pretty.c
t/t0003-attributes.sh
t/t4205-log-pretty-formats.sh
t/test-lib.sh
utf8.c
utf8.h

diff --cc attr.c
index 9e897e43f53196c238d152822f54b37b3ce91288,f826ba21deb74cd4a678055811cc8515eb544035..d7b8f60e7b414db9bf3f398183d1de851367164f
--- 1/attr.c
--- 2/attr.c
+++ b/attr.c
@@@ -335,10 -331,9 +335,9 @@@ static const char *parse_attr(const cha
  }
  
  static struct match_attr *parse_attr_line(const char *line, const char *src,
 -                                        int lineno, int macro_ok)
 +                                        int lineno, unsigned flags)
  {
-       int namelen;
-       int num_attr, i;
+       size_t namelen, num_attr, i;
        const char *cp, *name, *states;
        struct match_attr *res = NULL;
        int is_macro;
@@@ -661,11 -661,11 +665,11 @@@ static void handle_attr_line(struct att
  {
        struct match_attr *a;
  
 -      a = parse_attr_line(line, src, lineno, macro_ok);
 +      a = parse_attr_line(line, src, lineno, flags);
        if (!a)
                return;
-       ALLOC_GROW(res->attrs, res->num_matches + 1, res->alloc);
-       res->attrs[res->num_matches++] = a;
+       ALLOC_GROW_BY(res->attrs, res->num_matches, 1, res->alloc);
+       res->attrs[res->num_matches - 1] = a;
  }
  
  static struct attr_stack *read_attr_from_array(const char **list)
@@@ -703,33 -702,39 +707,45 @@@ void git_attr_set_direction(enum git_at
        direction = new_direction;
  }
  
 -static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
 +static struct attr_stack *read_attr_from_file(const char *path, unsigned flags)
  {
 -      FILE *fp = fopen_or_warn(path, "r");
+       struct strbuf buf = STRBUF_INIT;
 +      int fd;
 +      FILE *fp;
        struct attr_stack *res;
-       char buf[2048];
        int lineno = 0;
 -      int fd;
+       struct stat st;
  
 -      if (!fp)
 -              return NULL;
 +      if (flags & READ_ATTR_NOFOLLOW)
 +              fd = open_nofollow(path, O_RDONLY);
 +      else
 +              fd = open(path, O_RDONLY);
  
 -      fd = fileno(fp);
 +      if (fd < 0) {
 +              warn_on_fopen_errors(path);
 +              return NULL;
 +      }
 +      fp = xfdopen(fd, "r");
+       if (fstat(fd, &st)) {
+               warning_errno(_("cannot fstat gitattributes file '%s'"), path);
+               fclose(fp);
+               return NULL;
+       }
+       if (st.st_size >= ATTR_MAX_FILE_SIZE) {
+               warning(_("ignoring overly large gitattributes file '%s'"), path);
+               fclose(fp);
+               return NULL;
+       }
  
        CALLOC_ARRAY(res, 1);
-       while (fgets(buf, sizeof(buf), fp)) {
-               char *bufp = buf;
-               if (!lineno)
-                       skip_utf8_bom(&bufp, strlen(bufp));
-               handle_attr_line(res, bufp, path, ++lineno, flags);
+       while (strbuf_getline(&buf, fp) != EOF) {
+               if (!lineno && starts_with(buf.buf, utf8_bom))
+                       strbuf_remove(&buf, 0, strlen(utf8_bom));
 -              handle_attr_line(res, buf.buf, path, ++lineno, macro_ok);
++              handle_attr_line(res, buf.buf, path, ++lineno, flags);
        }
        fclose(fp);
+       strbuf_release(&buf);
        return res;
  }
  
diff --cc attr.h
Simple merge
Simple merge
diff --cc pretty.c
index b1ecd039cef29ecc77edd894c500dfadf49058c8,ae0f696d8ec2f4ea3d75df51d2fab8e7b3d83849..a9e90ea53bbc4f7d957f5ef325c32b3026e6b05a
+++ b/pretty.c
  #include "reflog-walk.h"
  #include "gpg-interface.h"
  #include "trailer.h"
 +#include "run-command.h"
  
+ /*
+  * The limit for formatting directives, which enable the caller to append
+  * arbitrarily many bytes to the formatted buffer. This includes padding
+  * and wrapping formatters.
+  */
+ #define FORMATTING_LIMIT (16 * 1024)
  static char *user_format;
  static struct cmt_fmt_map {
        const char *name;
index 1e4c672b84aa366de04969b3c3f073c1f02ce92f,9d9aa2855d226feed852bfe968d8d1a27fcf447e..89d5a0f67fa87d62ea9907a6f11990712b852857
@@@ -342,31 -339,63 +342,90 @@@ test_expect_success 'query binary macr
        test_cmp expect actual
  '
  
 +test_expect_success SYMLINKS 'set up symlink tests' '
 +      echo "* test" >attr &&
 +      rm -f .gitattributes
 +'
 +
 +test_expect_success SYMLINKS 'symlinks respected in core.attributesFile' '
 +      test_when_finished "rm symlink" &&
 +      ln -s attr symlink &&
 +      test_config core.attributesFile "$(pwd)/symlink" &&
 +      attr_check file set
 +'
 +
 +test_expect_success SYMLINKS 'symlinks respected in info/attributes' '
 +      test_when_finished "rm .git/info/attributes" &&
 +      ln -s ../../attr .git/info/attributes &&
 +      attr_check file set
 +'
 +
 +test_expect_success SYMLINKS 'symlinks not respected in-tree' '
 +      test_when_finished "rm -rf .gitattributes subdir" &&
 +      ln -s attr .gitattributes &&
 +      mkdir subdir &&
 +      ln -s ../attr subdir/.gitattributes &&
 +      attr_check_basic subdir/file unspecified &&
 +      test_i18ngrep "unable to access.*gitattributes" err
 +'
 +
+ test_expect_success 'large attributes line ignored in tree' '
+       test_when_finished "rm .gitattributes" &&
+       printf "path %02043d" 1 >.gitattributes &&
+       git check-attr --all path >actual 2>err &&
+       echo "warning: ignoring overly long attributes line 1" >expect &&
+       test_cmp expect err &&
+       test_must_be_empty actual
+ '
+ test_expect_success 'large attributes line ignores trailing content in tree' '
+       test_when_finished "rm .gitattributes" &&
+       # older versions of Git broke lines at 2048 bytes; the 2045 bytes
+       # of 0-padding here is accounting for the three bytes of "a 1", which
+       # would knock "trailing" to the "next" line, where it would be
+       # erroneously parsed.
+       printf "a %02045dtrailing attribute\n" 1 >.gitattributes &&
+       git check-attr --all trailing >actual 2>err &&
+       echo "warning: ignoring overly long attributes line 1" >expect &&
+       test_cmp expect err &&
+       test_must_be_empty actual
+ '
+ test_expect_success EXPENSIVE 'large attributes file ignored in tree' '
+       test_when_finished "rm .gitattributes" &&
+       dd if=/dev/zero of=.gitattributes bs=101M count=1 2>/dev/null &&
+       git check-attr --all path >/dev/null 2>err &&
+       echo "warning: ignoring overly large gitattributes file ${SQ}.gitattributes${SQ}" >expect &&
+       test_cmp expect err
+ '
+ test_expect_success 'large attributes line ignored in index' '
+       test_when_finished "git update-index --remove .gitattributes" &&
+       blob=$(printf "path %02043d" 1 | git hash-object -w --stdin) &&
+       git update-index --add --cacheinfo 100644,$blob,.gitattributes &&
+       git check-attr --cached --all path >actual 2>err &&
+       echo "warning: ignoring overly long attributes line 1" >expect &&
+       test_cmp expect err &&
+       test_must_be_empty actual
+ '
+ test_expect_success 'large attributes line ignores trailing content in index' '
+       test_when_finished "git update-index --remove .gitattributes" &&
+       blob=$(printf "a %02045dtrailing attribute\n" 1 | git hash-object -w --stdin) &&
+       git update-index --add --cacheinfo 100644,$blob,.gitattributes &&
+       git check-attr --cached --all trailing >actual 2>err &&
+       echo "warning: ignoring overly long attributes line 1" >expect &&
+       test_cmp expect err &&
+       test_must_be_empty actual
+ '
+ test_expect_success EXPENSIVE 'large attributes file ignored in index' '
+       test_when_finished "git update-index --remove .gitattributes" &&
+       blob=$(dd if=/dev/zero bs=101M count=1 2>/dev/null | git hash-object -w --stdin) &&
+       git update-index --add --cacheinfo 100644,$blob,.gitattributes &&
+       git check-attr --cached --all path >/dev/null 2>err &&
+       echo "warning: ignoring overly large gitattributes blob ${SQ}.gitattributes${SQ}" >expect &&
+       test_cmp expect err
+ '
  test_done
index 8272d94ce6b464f7b5a7e3bba8c58037af5a2f16,10e36e3b1dbe544663a311366df8693d4af48f9c..13c06fa1dcfe198a8b56e4c32823558c80a5d5ec
@@@ -967,39 -962,80 +967,115 @@@ test_expect_success 'log --pretty=refer
        test_cmp expect actual
  '
  
 +test_expect_success '%(describe) vs git describe' '
 +      git log --format="%H" | while read hash
 +      do
 +              if desc=$(git describe $hash)
 +              then
 +                      : >expect-contains-good
 +              else
 +                      : >expect-contains-bad
 +              fi &&
 +              echo "$hash $desc"
 +      done >expect &&
 +      test_path_exists expect-contains-good &&
 +      test_path_exists expect-contains-bad &&
 +
 +      git log --format="%H %(describe)" >actual 2>err &&
 +      test_cmp expect actual &&
 +      test_must_be_empty err
 +'
 +
 +test_expect_success '%(describe:match=...) vs git describe --match ...' '
 +      test_when_finished "git tag -d tag-match" &&
 +      git tag -a -m tagged tag-match&&
 +      git describe --match "*-match" >expect &&
 +      git log -1 --format="%(describe:match=*-match)" >actual &&
 +      test_cmp expect actual
 +'
 +
 +test_expect_success '%(describe:exclude=...) vs git describe --exclude ...' '
 +      test_when_finished "git tag -d tag-exclude" &&
 +      git tag -a -m tagged tag-exclude &&
 +      git describe --exclude "*-exclude" >expect &&
 +      git log -1 --format="%(describe:exclude=*-exclude)" >actual &&
 +      test_cmp expect actual
 +'
 +
+ test_expect_success 'log --pretty with space stealing' '
+       printf mm0 >expect &&
+       git log -1 --pretty="format:mm%>>|(1)%x30" >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'log --pretty with invalid padding format' '
+       printf "%s%%<(20" "$(git rev-parse HEAD)" >expect &&
+       git log -1 --pretty="format:%H%<(20" >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'log --pretty with magical wrapping directives' '
+       commit_id=$(git commit-tree HEAD^{tree} -m "describe me") &&
+       git tag describe-me $commit_id &&
+       printf "\n(tag:\ndescribe-me)%%+w(2)" >expect &&
+       git log -1 --pretty="format:%w(1)%+d%+w(2)" $commit_id >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success SIZE_T_IS_64BIT 'log --pretty with overflowing wrapping directive' '
+       printf "%%w(2147483649,1,1)0" >expect &&
+       git log -1 --pretty="format:%w(2147483649,1,1)%x30" >actual &&
+       test_cmp expect actual &&
+       printf "%%w(1,2147483649,1)0" >expect &&
+       git log -1 --pretty="format:%w(1,2147483649,1)%x30" >actual &&
+       test_cmp expect actual &&
+       printf "%%w(1,1,2147483649)0" >expect &&
+       git log -1 --pretty="format:%w(1,1,2147483649)%x30" >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success SIZE_T_IS_64BIT 'log --pretty with overflowing padding directive' '
+       printf "%%<(2147483649)0" >expect &&
+       git log -1 --pretty="format:%<(2147483649)%x30" >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'log --pretty with padding and preceding control chars' '
+       printf "\20\20   0" >expect &&
+       git log -1 --pretty="format:%x10%x10%>|(4)%x30" >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'log --pretty truncation with control chars' '
+       test_commit "$(printf "\20\20\20\20xxxx")" file contents commit-with-control-chars &&
+       printf "\20\20\20\20x.." >expect &&
+       git log -1 --pretty="format:%<(3,trunc)%s" commit-with-control-chars >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' '
+       # We only assert that this command does not crash. This needs to be
+       # executed with the address sanitizer to demonstrate failure.
+       git log -1 --pretty="format:%>(2147483646)%x41%41%>(2147483646)%x41" >/dev/null
+ '
+ test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'set up huge commit' '
+       test-tool genzeros 2147483649 | tr "\000" "1" >expect &&
+       huge_commit=$(git commit-tree -F expect HEAD^{tree})
+ '
+ test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' '
+       git log -1 --format="%B%<(1)%x30" $huge_commit >actual &&
+       echo 0 >>expect &&
+       test_cmp expect actual
+ '
+ test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message does not cause allocation failure' '
+       test_must_fail git log -1 --format="%<(1)%B" $huge_commit 2>error &&
+       cat >expect <<-EOF &&
+       fatal: number too large to represent as int on this platform: 2147483649
+       EOF
+       test_cmp expect error
+ '
  test_done
diff --cc t/test-lib.sh
Simple merge
diff --cc utf8.c
Simple merge
diff --cc utf8.h
Simple merge