summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-02-27 21:27:04 -0500
committerMike Frysinger <vapier@google.com>2021-02-28 16:07:24 +0000
commit6d1faa1db35439b267a7b10725ab0876f027ecb6 (patch)
treeef27ef693f564a8f342d22450c22fe564e0edf48
parent4510be51c1e4852258dd97fb043a250a6e3abfc7 (diff)
downloadgit-repo-6d1faa1db35439b267a7b10725ab0876f027ecb6.tar.gz
git_refs: fix crash with binary . files in .git/refs/
On macOS, the Finder app likes to poop .DS_Store files in every path that the user browses. If the user pokes around the .git/ tree, it could generate a .DS_Store file in there too. When repo goes to read all the local refs, it tries to decode this binary file as UTF-8 and subsequently crashes. Since paths that begin with . are not valid refs, ignore them like we already do with paths that end in .lock. Also bump the check up to ignore dirs that match since that follows the git rules: they apply to any component in its path, not just the final path (name). We don't implement the full valid ref algorithm that git employs as it's a bit complicated, and we only really need to focus on what will practically show up locally. Bug: https://crbug.com/gerrit/14162 Change-Id: I6519f990e33cc58a72fcb00c0f983ad3285ace3d Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/298662 Tested-by: Mike Frysinger <vapier@google.com> Reviewed-by: Michael Mortensen <mmortensen@google.com>
-rw-r--r--git_refs.py11
1 files changed, 7 insertions, 4 deletions
diff --git a/git_refs.py b/git_refs.py
index 3c8a9867..2d4a8090 100644
--- a/git_refs.py
+++ b/git_refs.py
@@ -131,11 +131,14 @@ class GitRefs(object):
131 base = os.path.join(self._gitdir, prefix) 131 base = os.path.join(self._gitdir, prefix)
132 for name in platform_utils.listdir(base): 132 for name in platform_utils.listdir(base):
133 p = os.path.join(base, name) 133 p = os.path.join(base, name)
134 if platform_utils.isdir(p): 134 # We don't implement the full ref validation algorithm, just the simple
135 # rules that would show up in local filesystems.
136 # https://git-scm.com/docs/git-check-ref-format
137 if name.startswith('.') or name.endswith('.lock'):
138 pass
139 elif platform_utils.isdir(p):
135 self._mtime[prefix] = os.path.getmtime(base) 140 self._mtime[prefix] = os.path.getmtime(base)
136 self._ReadLoose(prefix + name + '/') 141 self._ReadLoose(prefix + name + '/')
137 elif name.endswith('.lock'):
138 pass
139 else: 142 else:
140 self._ReadLoose1(p, prefix + name) 143 self._ReadLoose1(p, prefix + name)
141 144
@@ -144,7 +147,7 @@ class GitRefs(object):
144 with open(path) as fd: 147 with open(path) as fd:
145 mtime = os.path.getmtime(path) 148 mtime = os.path.getmtime(path)
146 ref_id = fd.readline() 149 ref_id = fd.readline()
147 except (IOError, OSError): 150 except (OSError, UnicodeError):
148 return 151 return
149 152
150 try: 153 try: