summaryrefslogtreecommitdiffstats
path: root/manifest_xml.py
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-02-25 18:26:31 -0500
committerMike Frysinger <vapier@google.com>2021-02-28 16:07:12 +0000
commita00c5f40e76fd520597013ae89823711212630b3 (patch)
tree44d9536431bc7e63e3855e3b628cbdf4ab6544fc /manifest_xml.py
parent6093d99d13deada12a2365e81e2bd148dbb423ad (diff)
downloadgit-repo-a00c5f40e76fd520597013ae89823711212630b3.tar.gz
manifest: refactor the filesystem checking logic for more reuse
This function is currently written with copyfile & linkfile in mind. Generalize the logic & function arguments slightly so we can reuse in more places that make sense. This changes the validation logic slightly too in that we no longer allow "." for the dest attribute with copyfile & linkfile, nor for the src attribute with copyfile. We already rejected those later on when checking against the active filesystem, but now we reject them a little sooner when parsing. The empty path check isn't a new requirement exactly -- repo used to crash on it, so it was effectively blocked, but now we diagnosis it. Bug: https://crbug.com/gerrit/14156 Change-Id: I0fdb42a3da60ed149ff1997c5dd4b85da70eec3d Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/298442 Reviewed-by: Michael Mortensen <mmortensen@google.com> Tested-by: Mike Frysinger <vapier@google.com>
Diffstat (limited to 'manifest_xml.py')
-rw-r--r--manifest_xml.py36
1 files changed, 31 insertions, 5 deletions
diff --git a/manifest_xml.py b/manifest_xml.py
index ff8e0612..d05f4d0a 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -1121,8 +1121,33 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1121 return relpath, worktree, gitdir, objdir 1121 return relpath, worktree, gitdir, objdir
1122 1122
1123 @staticmethod 1123 @staticmethod
1124 def _CheckLocalPath(path, symlink=False): 1124 def _CheckLocalPath(path, dir_ok=False, cwd_dot_ok=False):
1125 """Verify |path| is reasonable for use in <copyfile> & <linkfile>.""" 1125 """Verify |path| is reasonable for use in filesystem paths.
1126
1127 Used with <copyfile> & <linkfile> elements.
1128
1129 This only validates the |path| in isolation: it does not check against the
1130 current filesystem state. Thus it is suitable as a first-past in a parser.
1131
1132 It enforces a number of constraints:
1133 * No empty paths.
1134 * No "~" in paths.
1135 * No Unicode codepoints that filesystems might elide when normalizing.
1136 * No relative path components like "." or "..".
1137 * No absolute paths.
1138 * No ".git" or ".repo*" path components.
1139
1140 Args:
1141 path: The path name to validate.
1142 dir_ok: Whether |path| may force a directory (e.g. end in a /).
1143 cwd_dot_ok: Whether |path| may be just ".".
1144
1145 Returns:
1146 None if |path| is OK, a failure message otherwise.
1147 """
1148 if not path:
1149 return 'empty paths not allowed'
1150
1126 if '~' in path: 1151 if '~' in path:
1127 return '~ not allowed (due to 8.3 filenames on Windows filesystems)' 1152 return '~ not allowed (due to 8.3 filenames on Windows filesystems)'
1128 1153
@@ -1165,12 +1190,12 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1165 1190
1166 # Some people use src="." to create stable links to projects. Lets allow 1191 # Some people use src="." to create stable links to projects. Lets allow
1167 # that but reject all other uses of "." to keep things simple. 1192 # that but reject all other uses of "." to keep things simple.
1168 if parts != ['.']: 1193 if not cwd_dot_ok or parts != ['.']:
1169 for part in set(parts): 1194 for part in set(parts):
1170 if part in {'.', '..', '.git'} or part.startswith('.repo'): 1195 if part in {'.', '..', '.git'} or part.startswith('.repo'):
1171 return 'bad component: %s' % (part,) 1196 return 'bad component: %s' % (part,)
1172 1197
1173 if not symlink and resep.match(path[-1]): 1198 if not dir_ok and resep.match(path[-1]):
1174 return 'dirs not allowed' 1199 return 'dirs not allowed'
1175 1200
1176 # NB: The two abspath checks here are to handle platforms with multiple 1201 # NB: The two abspath checks here are to handle platforms with multiple
@@ -1202,7 +1227,8 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
1202 1227
1203 # |src| is the file we read from or path we point to for symlinks. 1228 # |src| is the file we read from or path we point to for symlinks.
1204 # It is relative to the top of the git project checkout. 1229 # It is relative to the top of the git project checkout.
1205 msg = cls._CheckLocalPath(src, symlink=element == 'linkfile') 1230 is_linkfile = element == 'linkfile'
1231 msg = cls._CheckLocalPath(src, dir_ok=is_linkfile, cwd_dot_ok=is_linkfile)
1206 if msg: 1232 if msg:
1207 raise ManifestInvalidPathError( 1233 raise ManifestInvalidPathError(
1208 '<%s> invalid "src": %s: %s' % (element, src, msg)) 1234 '<%s> invalid "src": %s: %s' % (element, src, msg))