@@ -636,6 +636,8 @@ static int fsck_tree(const struct object_id *tree_oid,
636
636
retval += report (options , tree_oid , OBJ_TREE ,
637
637
FSCK_MSG_MAILMAP_SYMLINK ,
638
638
".mailmap is a symlink" );
639
+ oidset_insert (& options -> symlink_targets_found ,
640
+ entry_oid );
639
641
}
640
642
641
643
if ((backslash = strchr (name , '\\' ))) {
@@ -1228,6 +1230,56 @@ static int fsck_blob(const struct object_id *oid, const char *buf,
1228
1230
}
1229
1231
}
1230
1232
1233
+ if (oidset_contains (& options -> symlink_targets_found , oid )) {
1234
+ const char * ptr = buf ;
1235
+ const struct object_id * reported = NULL ;
1236
+
1237
+ oidset_insert (& options -> symlink_targets_done , oid );
1238
+
1239
+ if (!buf || size > PATH_MAX ) {
1240
+ /*
1241
+ * A missing buffer here is a sign that the caller found the
1242
+ * blob too gigantic to load into memory. Let's just consider
1243
+ * that an error.
1244
+ */
1245
+ return report (options , oid , OBJ_BLOB ,
1246
+ FSCK_MSG_SYMLINK_TARGET_LENGTH ,
1247
+ "symlink target too long" );
1248
+ }
1249
+
1250
+ while (!reported && ptr ) {
1251
+ const char * p = ptr ;
1252
+ char c , * slash = strchrnul (ptr , '/' );
1253
+ char * backslash = memchr (ptr , '\\' , slash - ptr );
1254
+
1255
+ c = * slash ;
1256
+ * slash = '\0' ;
1257
+
1258
+ while (!reported && backslash ) {
1259
+ * backslash = '\0' ;
1260
+ if (is_ntfs_dotgit (p ))
1261
+ ret |= report (options , reported = oid , OBJ_BLOB ,
1262
+ FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR ,
1263
+ "symlink target points to git dir" );
1264
+ * backslash = '\\' ;
1265
+ p = backslash + 1 ;
1266
+ backslash = memchr (p , '\\' , slash - p );
1267
+ }
1268
+ if (!reported && is_ntfs_dotgit (p ))
1269
+ ret |= report (options , reported = oid , OBJ_BLOB ,
1270
+ FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR ,
1271
+ "symlink target points to git dir" );
1272
+
1273
+ if (!reported && is_hfs_dotgit (ptr ))
1274
+ ret |= report (options , reported = oid , OBJ_BLOB ,
1275
+ FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR ,
1276
+ "symlink target points to git dir" );
1277
+
1278
+ * slash = c ;
1279
+ ptr = c ? slash + 1 : NULL ;
1280
+ }
1281
+ }
1282
+
1231
1283
return ret ;
1232
1284
}
1233
1285
@@ -1319,6 +1371,10 @@ int fsck_finish(struct fsck_options *options)
1319
1371
FSCK_MSG_GITATTRIBUTES_MISSING , FSCK_MSG_GITATTRIBUTES_BLOB ,
1320
1372
options , ".gitattributes" );
1321
1373
1374
+ ret |= fsck_blobs (& options -> symlink_targets_found , & options -> symlink_targets_done ,
1375
+ FSCK_MSG_SYMLINK_TARGET_MISSING , FSCK_MSG_SYMLINK_TARGET_BLOB ,
1376
+ options , "<symlink-target>" );
1377
+
1322
1378
return ret ;
1323
1379
}
1324
1380
0 commit comments