@@ -1005,6 +1005,9 @@ static int submodule_has_commits(struct repository *r,
1005
1005
.super_oid = super_oid
1006
1006
};
1007
1007
1008
+ if (validate_submodule_path (path ) < 0 )
1009
+ exit (128 );
1010
+
1008
1011
oid_array_for_each_unique (commits , check_has_commit , & has_commit );
1009
1012
1010
1013
if (has_commit .result ) {
@@ -1127,6 +1130,9 @@ static int push_submodule(const char *path,
1127
1130
const struct string_list * push_options ,
1128
1131
int dry_run )
1129
1132
{
1133
+ if (validate_submodule_path (path ) < 0 )
1134
+ exit (128 );
1135
+
1130
1136
if (for_each_remote_ref_submodule (path , has_remote , NULL ) > 0 ) {
1131
1137
struct child_process cp = CHILD_PROCESS_INIT ;
1132
1138
strvec_push (& cp .args , "push" );
@@ -1176,6 +1182,9 @@ static void submodule_push_check(const char *path, const char *head,
1176
1182
struct child_process cp = CHILD_PROCESS_INIT ;
1177
1183
int i ;
1178
1184
1185
+ if (validate_submodule_path (path ) < 0 )
1186
+ exit (128 );
1187
+
1179
1188
strvec_push (& cp .args , "submodule--helper" );
1180
1189
strvec_push (& cp .args , "push-check" );
1181
1190
strvec_push (& cp .args , head );
@@ -1507,6 +1516,9 @@ static struct fetch_task *fetch_task_create(struct submodule_parallel_fetch *spf
1507
1516
struct fetch_task * task = xmalloc (sizeof (* task ));
1508
1517
memset (task , 0 , sizeof (* task ));
1509
1518
1519
+ if (validate_submodule_path (path ) < 0 )
1520
+ exit (128 );
1521
+
1510
1522
task -> sub = submodule_from_path (spf -> r , treeish_name , path );
1511
1523
1512
1524
if (!task -> sub ) {
@@ -1879,6 +1891,9 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
1879
1891
const char * git_dir ;
1880
1892
int ignore_cp_exit_code = 0 ;
1881
1893
1894
+ if (validate_submodule_path (path ) < 0 )
1895
+ exit (128 );
1896
+
1882
1897
strbuf_addf (& buf , "%s/.git" , path );
1883
1898
git_dir = read_gitfile (buf .buf );
1884
1899
if (!git_dir )
@@ -1955,6 +1970,9 @@ int submodule_uses_gitfile(const char *path)
1955
1970
struct strbuf buf = STRBUF_INIT ;
1956
1971
const char * git_dir ;
1957
1972
1973
+ if (validate_submodule_path (path ) < 0 )
1974
+ exit (128 );
1975
+
1958
1976
strbuf_addf (& buf , "%s/.git" , path );
1959
1977
git_dir = read_gitfile (buf .buf );
1960
1978
if (!git_dir ) {
@@ -1994,6 +2012,9 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
1994
2012
struct strbuf buf = STRBUF_INIT ;
1995
2013
int ret = 0 ;
1996
2014
2015
+ if (validate_submodule_path (path ) < 0 )
2016
+ exit (128 );
2017
+
1997
2018
if (!file_exists (path ) || is_empty_dir (path ))
1998
2019
return 0 ;
1999
2020
@@ -2044,6 +2065,9 @@ void submodule_unset_core_worktree(const struct submodule *sub)
2044
2065
{
2045
2066
struct strbuf config_path = STRBUF_INIT ;
2046
2067
2068
+ if (validate_submodule_path (sub -> path ) < 0 )
2069
+ exit (128 );
2070
+
2047
2071
submodule_name_to_gitdir (& config_path , the_repository , sub -> name );
2048
2072
strbuf_addstr (& config_path , "/config" );
2049
2073
@@ -2066,6 +2090,9 @@ static int submodule_has_dirty_index(const struct submodule *sub)
2066
2090
{
2067
2091
struct child_process cp = CHILD_PROCESS_INIT ;
2068
2092
2093
+ if (validate_submodule_path (sub -> path ) < 0 )
2094
+ exit (128 );
2095
+
2069
2096
prepare_submodule_repo_env (& cp .env );
2070
2097
2071
2098
cp .git_cmd = 1 ;
@@ -2083,6 +2110,10 @@ static int submodule_has_dirty_index(const struct submodule *sub)
2083
2110
static void submodule_reset_index (const char * path )
2084
2111
{
2085
2112
struct child_process cp = CHILD_PROCESS_INIT ;
2113
+
2114
+ if (validate_submodule_path (path ) < 0 )
2115
+ exit (128 );
2116
+
2086
2117
prepare_submodule_repo_env (& cp .env );
2087
2118
2088
2119
cp .git_cmd = 1 ;
@@ -2287,6 +2318,34 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
2287
2318
return 0 ;
2288
2319
}
2289
2320
2321
+ int validate_submodule_path (const char * path )
2322
+ {
2323
+ char * p = xstrdup (path );
2324
+ struct stat st ;
2325
+ int i , ret = 0 ;
2326
+ char sep ;
2327
+
2328
+ for (i = 0 ; !ret && p [i ]; i ++ ) {
2329
+ if (!is_dir_sep (p [i ]))
2330
+ continue ;
2331
+
2332
+ sep = p [i ];
2333
+ p [i ] = '\0' ;
2334
+ /* allow missing components, but no symlinks */
2335
+ ret = lstat (p , & st ) || !S_ISLNK (st .st_mode ) ? 0 : -1 ;
2336
+ p [i ] = sep ;
2337
+ if (ret )
2338
+ error (_ ("expected '%.*s' in submodule path '%s' not to "
2339
+ "be a symbolic link" ), i , p , p );
2340
+ }
2341
+ if (!lstat (p , & st ) && S_ISLNK (st .st_mode ))
2342
+ ret = error (_ ("expected submodule path '%s' not to be a "
2343
+ "symbolic link" ), p );
2344
+ free (p );
2345
+ return ret ;
2346
+ }
2347
+
2348
+
2290
2349
/*
2291
2350
* Embeds a single submodules git directory into the superprojects git dir,
2292
2351
* non recursively.
@@ -2297,6 +2356,9 @@ static void relocate_single_git_dir_into_superproject(const char *path)
2297
2356
struct strbuf new_gitdir = STRBUF_INIT ;
2298
2357
const struct submodule * sub ;
2299
2358
2359
+ if (validate_submodule_path (path ) < 0 )
2360
+ exit (128 );
2361
+
2300
2362
if (submodule_uses_worktrees (path ))
2301
2363
die (_ ("relocate_gitdir for submodule '%s' with "
2302
2364
"more than one worktree not supported" ), path );
@@ -2337,6 +2399,9 @@ static void absorb_git_dir_into_superproject_recurse(const char *path)
2337
2399
2338
2400
struct child_process cp = CHILD_PROCESS_INIT ;
2339
2401
2402
+ if (validate_submodule_path (path ) < 0 )
2403
+ exit (128 );
2404
+
2340
2405
cp .dir = path ;
2341
2406
cp .git_cmd = 1 ;
2342
2407
cp .no_stdin = 1 ;
@@ -2359,6 +2424,10 @@ void absorb_git_dir_into_superproject(const char *path)
2359
2424
int err_code ;
2360
2425
const char * sub_git_dir ;
2361
2426
struct strbuf gitdir = STRBUF_INIT ;
2427
+
2428
+ if (validate_submodule_path (path ) < 0 )
2429
+ exit (128 );
2430
+
2362
2431
strbuf_addf (& gitdir , "%s/.git" , path );
2363
2432
sub_git_dir = resolve_gitdir_gently (gitdir .buf , & err_code );
2364
2433
@@ -2501,6 +2570,9 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
2501
2570
const char * git_dir ;
2502
2571
int ret = 0 ;
2503
2572
2573
+ if (validate_submodule_path (submodule ) < 0 )
2574
+ exit (128 );
2575
+
2504
2576
strbuf_reset (buf );
2505
2577
strbuf_addstr (buf , submodule );
2506
2578
strbuf_complete (buf , '/' );
0 commit comments