@@ -1245,17 +1245,22 @@ static void index_existing_and_best(
1245
1245
* it, then it will return an error **and also free the entry**. When
1246
1246
* it replaces an existing entry, it will update the entry_ptr with the
1247
1247
* actual entry in the index (and free the passed in one).
1248
+ *
1248
1249
* trust_path is whether we use the given path, or whether (on case
1249
1250
* insensitive systems only) we try to canonicalize the given path to
1250
1251
* be within an existing directory.
1252
+ *
1251
1253
* trust_mode is whether we trust the mode in entry_ptr.
1254
+ *
1255
+ * trust_id is whether we trust the id or it should be validated.
1252
1256
*/
1253
1257
static int index_insert (
1254
1258
git_index * index ,
1255
1259
git_index_entry * * entry_ptr ,
1256
1260
int replace ,
1257
1261
bool trust_path ,
1258
- bool trust_mode )
1262
+ bool trust_mode ,
1263
+ bool trust_id )
1259
1264
{
1260
1265
int error = 0 ;
1261
1266
size_t path_length , position ;
@@ -1288,6 +1293,15 @@ static int index_insert(
1288
1293
if (!trust_path )
1289
1294
error = canonicalize_directory_path (index , entry , best );
1290
1295
1296
+ /* ensure that the given id exists (unless it's a submodule) */
1297
+ if (!error && !trust_id && INDEX_OWNER (index ) &&
1298
+ (entry -> mode & GIT_FILEMODE_COMMIT ) != GIT_FILEMODE_COMMIT ) {
1299
+
1300
+ if (!git_object__is_valid (INDEX_OWNER (index ), & entry -> id ,
1301
+ git_object__type_from_filemode (entry -> mode )))
1302
+ error = -1 ;
1303
+ }
1304
+
1291
1305
/* look for tree / blob name collisions, removing conflicts if requested */
1292
1306
if (!error )
1293
1307
error = check_file_directory_collision (index , entry , position , replace );
@@ -1395,7 +1409,7 @@ int git_index_add_frombuffer(
1395
1409
git_oid_cpy (& entry -> id , & id );
1396
1410
entry -> file_size = len ;
1397
1411
1398
- if ((error = index_insert (index , & entry , 1 , true, true)) < 0 )
1412
+ if ((error = index_insert (index , & entry , 1 , true, true, true )) < 0 )
1399
1413
return error ;
1400
1414
1401
1415
/* Adding implies conflict was resolved, move conflict entries to REUC */
@@ -1454,7 +1468,7 @@ int git_index_add_bypath(git_index *index, const char *path)
1454
1468
assert (index && path );
1455
1469
1456
1470
if ((ret = index_entry_init (& entry , index , path )) == 0 )
1457
- ret = index_insert (index , & entry , 1 , false, false);
1471
+ ret = index_insert (index , & entry , 1 , false, false, true );
1458
1472
1459
1473
/* If we were given a directory, let's see if it's a submodule */
1460
1474
if (ret < 0 && ret != GIT_EDIRECTORY )
@@ -1480,7 +1494,7 @@ int git_index_add_bypath(git_index *index, const char *path)
1480
1494
if ((ret = add_repo_as_submodule (& entry , index , path )) < 0 )
1481
1495
return ret ;
1482
1496
1483
- if ((ret = index_insert (index , & entry , 1 , false, false)) < 0 )
1497
+ if ((ret = index_insert (index , & entry , 1 , false, false, true )) < 0 )
1484
1498
return ret ;
1485
1499
} else if (ret < 0 ) {
1486
1500
return ret ;
@@ -1569,7 +1583,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry)
1569
1583
}
1570
1584
1571
1585
if ((ret = index_entry_dup (& entry , index , source_entry )) < 0 ||
1572
- (ret = index_insert (index , & entry , 1 , true, true)) < 0 )
1586
+ (ret = index_insert (index , & entry , 1 , true, true, false )) < 0 )
1573
1587
return ret ;
1574
1588
1575
1589
git_tree_cache_invalidate_path (index -> tree , entry -> path );
@@ -1731,7 +1745,7 @@ int git_index_conflict_add(git_index *index,
1731
1745
/* Make sure stage is correct */
1732
1746
GIT_IDXENTRY_STAGE_SET (entries [i ], i + 1 );
1733
1747
1734
- if ((ret = index_insert (index , & entries [i ], 1 , true, true)) < 0 )
1748
+ if ((ret = index_insert (index , & entries [i ], 1 , true, true, false )) < 0 )
1735
1749
goto on_error ;
1736
1750
1737
1751
entries [i ] = NULL ; /* don't free if later entry fails */
0 commit comments