3486
return 0;
3487
}
3488
3489
+/*
3490
+ * We need to keep track of how symlinks in the preimage are
3491
+ * manipulated by the patches. A patch to add a/b/c where a/b
3492
+ * is a symlink should not be allowed to affect the directory
3493
+ * the symlink points at, but if the same patch removes a/b,
3494
+ * it is perfectly fine, as the patch removes a/b to make room
3495
+ * to create a directory a/b so that a/b/c can be created.
3496
+ */
3497
+static struct string_list symlink_changes;
3498
+#define SYMLINK_GOES_AWAY 01
3499
+#define SYMLINK_IN_RESULT 02
3500
+
3501
+static uintptr_t register_symlink_changes(const char *path, uintptr_t what)
3502
+{
3503
+ struct string_list_item *ent;
3504
+
3505
+ ent = string_list_lookup(&symlink_changes, path);
3506
+ if (!ent) {
3507
+ ent = string_list_insert(&symlink_changes, path);
3508
+ ent->util = (void *)0;
3509
+ }
3510
+ ent->util = (void *)(what | ((uintptr_t)ent->util));
3511
+ return (uintptr_t)ent->util;
3512
+}
3513
+
3514
+static uintptr_t check_symlink_changes(const char *path)
3515
+{
3516
+ struct string_list_item *ent;
3517
+
3518
+ ent = string_list_lookup(&symlink_changes, path);
3519
+ if (!ent)
3520
+ return 0;
3521
+ return (uintptr_t)ent->util;
3522
+}
3523
+
3524
+static void prepare_symlink_changes(struct patch *patch)
3525
+{
3526
+ for ( ; patch; patch = patch->next) {
3527
+ if ((patch->old_name && S_ISLNK(patch->old_mode)) &&
3528
+ (patch->is_rename || patch->is_delete))
3529
+ /* the symlink at patch->old_name is removed */
3530
+ register_symlink_changes(patch->old_name, SYMLINK_GOES_AWAY);
3531
+
3532
+ if (patch->new_name && S_ISLNK(patch->new_mode))
3533
+ /* the symlink at patch->new_name is created or remains */
3534
+ register_symlink_changes(patch->new_name, SYMLINK_IN_RESULT);
3535
+ }
3536
+}
3537
+
3538
+static int path_is_beyond_symlink_1(struct strbuf *name)
3539
+{
3540
+ do {
3541
+ unsigned int change;
3542
+
3543
+ while (--name->len && name->buf[name->len] != '/')
3544
+ ; /* scan backwards */
3545
+ if (!name->len)
3546
+ break;
3547
+ name->buf[name->len] = '\0';
3548
+ change = check_symlink_changes(name->buf);
3549
+ if (change & SYMLINK_IN_RESULT)
3550
+ return 1;
3551
+ if (change & SYMLINK_GOES_AWAY)
3552
+ /*
3553
+ * This cannot be "return 0", because we may
3554
+ * see a new one created at a higher level.
3555
+ */
3556
+ continue;
3557
+
3558
+ /* otherwise, check the preimage */
3559
+ if (check_index) {
3560
+ struct cache_entry *ce;
3561
+
3562
+ ce = cache_file_exists(name->buf, name->len, ignore_case);
3563
+ if (ce && S_ISLNK(ce->ce_mode))
3564
+ return 1;
3565
+ } else {
3566
+ struct stat st;
3567
+ if (!lstat(name->buf, &st) && S_ISLNK(st.st_mode))
3568
+ return 1;
3569
+ }
3570
+ } while (1);
3571
+ return 0;
3572
+}
3573
+
3574
+static int path_is_beyond_symlink(const char *name_)
3575
+{
3576
+ int ret;
3577
+ struct strbuf name = STRBUF_INIT;
3578
+
3579
+ assert(*name_ != '\0');
3580
+ strbuf_addstr(&name, name_);
3581
+ ret = path_is_beyond_symlink_1(&name);
3582
+ strbuf_release(&name);
3583
+
3584
+ return ret;
3585
+}
3586
+
3587
static void die_on_unsafe_path(struct patch *patch)
3588
{
3589
const char *old_name = NULL;
3691
if (!unsafe_paths)
3692
die_on_unsafe_path(patch);
3693
3694
+ /*
3695
+ * An attempt to read from or delete a path that is beyond a
3696
+ * symbolic link will be prevented by load_patch_target() that
3697
+ * is called at the beginning of apply_data() so we do not
3698
+ * have to worry about a patch marked with "is_delete" bit
3699
+ * here. We however need to make sure that the patch result
3700
+ * is not deposited to a path that is beyond a symbolic link
3701
+ * here.
3702
+ */
3703
+ if (!patch->is_delete && path_is_beyond_symlink(patch->new_name))
3704
+ return error(_("affected file '%s' is beyond a symbolic link"),
3705
+ patch->new_name);
3706
+
3707
if (apply_data(patch, &st, ce) < 0)
3708
return error(_("%s: patch does not apply"), name);
3709
patch->rejected = 0;
3714
{
3715
int err = 0;
3716
3717
+ prepare_symlink_changes(patch);
3718
prepare_fn_table(patch);
3719
while (patch) {
3720
if (apply_verbosely)