~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_fs_base/tree.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
543
543
  parent_copy_id = svn_fs_base__id_copy_id(parent_id);
544
544
 
545
545
  /* Easy out: if this child is already mutable, we have nothing to do. */
546
 
  if (svn_fs_base__key_compare(svn_fs_base__id_txn_id(child_id), txn_id) == 0)
 
546
  if (strcmp(svn_fs_base__id_txn_id(child_id), txn_id) == 0)
547
547
    return SVN_NO_ERROR;
548
548
 
549
549
  /* If the child and its parent are on the same branch, then the
560
560
     target of any copy, and therefore must be on the same branch as
561
561
     its parent.  */
562
562
  if ((strcmp(child_copy_id, "0") == 0)
563
 
      || (svn_fs_base__key_compare(child_copy_id, parent_copy_id) == 0))
 
563
      || (strcmp(child_copy_id, parent_copy_id) == 0))
564
564
    {
565
565
      *inherit_p = copy_id_inherit_parent;
566
566
      return SVN_NO_ERROR;
569
569
    {
570
570
      copy_t *copy;
571
571
      SVN_ERR(svn_fs_bdb__get_copy(&copy, fs, child_copy_id, trail, pool));
572
 
      if (svn_fs_base__id_compare(copy->dst_noderev_id, child_id) == -1)
 
572
      if (   svn_fs_base__id_compare(copy->dst_noderev_id, child_id)
 
573
          == svn_fs_node_unrelated)
573
574
        {
574
575
          *inherit_p = copy_id_inherit_parent;
575
576
          return SVN_NO_ERROR;
1027
1028
  return SVN_NO_ERROR;
1028
1029
}
1029
1030
 
 
1031
static svn_error_t *
 
1032
base_node_relation(svn_fs_node_relation_t *relation,
 
1033
                   svn_fs_root_t *root_a, const char *path_a,
 
1034
                   svn_fs_root_t *root_b, const char *path_b,
 
1035
                   apr_pool_t *pool)
 
1036
{
 
1037
  const svn_fs_id_t *id_a, *id_b;
 
1038
 
 
1039
  /* Paths from different repository are never related. */
 
1040
  if (root_a->fs != root_b->fs)
 
1041
    {
 
1042
      *relation = svn_fs_node_unrelated;
 
1043
      return SVN_NO_ERROR;
 
1044
    }
 
1045
 
 
1046
  /* Naive implementation. */
 
1047
  SVN_ERR(base_node_id(&id_a, root_a, path_a, pool));
 
1048
  SVN_ERR(base_node_id(&id_b, root_b, path_b, pool));
 
1049
 
 
1050
  *relation = svn_fs_base__id_compare(id_a, id_b);
 
1051
 
 
1052
  return SVN_NO_ERROR;
 
1053
}
 
1054
 
1030
1055
 
1031
1056
struct node_created_rev_args {
1032
1057
  svn_revnum_t revision;
1212
1237
  args.propname = propname;
1213
1238
  SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_node_prop, &args,
1214
1239
                                 FALSE, scratch_pool));
1215
 
  *value_p = value ? svn_string_dup(value, pool) : NULL;
 
1240
  *value_p = svn_string_dup(value, pool);
1216
1241
  svn_pool_destroy(scratch_pool);
1217
1242
  return SVN_NO_ERROR;
1218
1243
}
1260
1285
  return SVN_NO_ERROR;
1261
1286
}
1262
1287
 
 
1288
static svn_error_t *
 
1289
base_node_has_props(svn_boolean_t *has_props,
 
1290
                    svn_fs_root_t *root,
 
1291
                    const char *path,
 
1292
                    apr_pool_t *scratch_pool)
 
1293
{
 
1294
  apr_hash_t *props;
 
1295
 
 
1296
  SVN_ERR(base_node_proplist(&props, root, path, scratch_pool));
 
1297
 
 
1298
  *has_props = (0 < apr_hash_count(props));
 
1299
 
 
1300
  return SVN_NO_ERROR;
 
1301
}
 
1302
 
1263
1303
 
1264
1304
struct change_node_prop_args {
1265
1305
  svn_fs_root_t *root;
1369
1409
  svn_fs_root_t *root2;
1370
1410
  const char *path1;
1371
1411
  const char *path2;
 
1412
  svn_boolean_t strict;
1372
1413
  apr_pool_t *pool;
1373
1414
};
1374
1415
 
1378
1419
{
1379
1420
  struct things_changed_args *args = baton;
1380
1421
  dag_node_t *node1, *node2;
 
1422
  apr_hash_t *proplist1, *proplist2;
1381
1423
 
1382
1424
  SVN_ERR(get_dag(&node1, args->root1, args->path1, trail, trail->pool));
1383
1425
  SVN_ERR(get_dag(&node2, args->root2, args->path2, trail, trail->pool));
1384
 
  return svn_fs_base__things_different(args->changed_p, NULL,
1385
 
                                       node1, node2, trail, trail->pool);
 
1426
  SVN_ERR(svn_fs_base__things_different(args->changed_p, NULL,
 
1427
                                        node1, node2, trail, trail->pool));
 
1428
 
 
1429
  /* Is there a potential false positive and do we want to correct it? */
 
1430
  if (!args->strict || !*args->changed_p)
 
1431
    return SVN_NO_ERROR;
 
1432
 
 
1433
  /* Different representations. They might still have equal contents. */
 
1434
  SVN_ERR(svn_fs_base__dag_get_proplist(&proplist1, node1,
 
1435
                                        trail, trail->pool));
 
1436
  SVN_ERR(svn_fs_base__dag_get_proplist(&proplist2, node2,
 
1437
                                        trail, trail->pool));
 
1438
 
 
1439
  *args->changed_p = !svn_fs__prop_lists_equal(proplist1, proplist2,
 
1440
                                               trail->pool);
 
1441
  return SVN_NO_ERROR;
1386
1442
}
1387
1443
 
1388
1444
 
1392
1448
                   const char *path1,
1393
1449
                   svn_fs_root_t *root2,
1394
1450
                   const char *path2,
 
1451
                   svn_boolean_t strict,
1395
1452
                   apr_pool_t *pool)
1396
1453
{
1397
1454
  struct things_changed_args args;
1408
1465
  args.path2      = path2;
1409
1466
  args.changed_p  = changed_p;
1410
1467
  args.pool       = pool;
 
1468
  args.strict     = strict;
1411
1469
 
1412
1470
  return svn_fs_base__retry_txn(root1->fs, txn_body_props_changed, &args,
1413
1471
                                TRUE, pool);
1561
1619
  return SVN_NO_ERROR;
1562
1620
}
1563
1621
 
 
1622
static svn_error_t *
 
1623
base_dir_optimal_order(apr_array_header_t **ordered_p,
 
1624
                       svn_fs_root_t *root,
 
1625
                       apr_hash_t *entries,
 
1626
                       apr_pool_t *result_pool,
 
1627
                       apr_pool_t *scratch_pool)
 
1628
{
 
1629
  /* 1:1 copy of entries with no differnce in ordering */
 
1630
  apr_hash_index_t *hi;
 
1631
  apr_array_header_t *result
 
1632
    = apr_array_make(result_pool, apr_hash_count(entries),
 
1633
                     sizeof(svn_fs_dirent_t *));
 
1634
  for (hi = apr_hash_first(scratch_pool, entries); hi; hi = apr_hash_next(hi))
 
1635
    APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = apr_hash_this_val(hi);
 
1636
 
 
1637
  *ordered_p = result;
 
1638
  return SVN_NO_ERROR;
 
1639
}
 
1640
 
1564
1641
 
1565
1642
 
1566
1643
/* Merges and commits. */
3104
3181
  if ((to_parent_path->node)
3105
3182
      && (svn_fs_base__id_compare(svn_fs_base__dag_get_id(from_node),
3106
3183
                                  svn_fs_base__dag_get_id
3107
 
                                  (to_parent_path->node)) == 0))
 
3184
                                  (to_parent_path->node))
 
3185
          == svn_fs_node_unchanged))
3108
3186
    return SVN_NO_ERROR;
3109
3187
 
3110
3188
  if (! from_root->is_txn_root)
3292
3370
    return SVN_NO_ERROR;
3293
3371
 
3294
3372
  /* If NODE's copy-ID is the same as that of its predecessor... */
3295
 
  if (svn_fs_base__key_compare(svn_fs_base__id_copy_id(node_id),
3296
 
                               svn_fs_base__id_copy_id(pred_id)) != 0)
 
3373
  if (strcmp(svn_fs_base__id_copy_id(node_id),
 
3374
             svn_fs_base__id_copy_id(pred_id)) != 0)
3297
3375
    {
3298
3376
      /* ... then NODE was either the target of a copy operation,
3299
3377
         a copied subtree item.  We examine the actual copy record
3942
4020
{
3943
4021
  struct things_changed_args *args = baton;
3944
4022
  dag_node_t *node1, *node2;
 
4023
  svn_checksum_t *checksum1, *checksum2;
 
4024
  svn_stream_t *stream1, *stream2;
 
4025
  svn_boolean_t same;
3945
4026
 
3946
4027
  SVN_ERR(get_dag(&node1, args->root1, args->path1, trail, trail->pool));
3947
4028
  SVN_ERR(get_dag(&node2, args->root2, args->path2, trail, trail->pool));
3948
 
  return svn_fs_base__things_different(NULL, args->changed_p,
3949
 
                                       node1, node2, trail, trail->pool);
 
4029
  SVN_ERR(svn_fs_base__things_different(NULL, args->changed_p,
 
4030
                                        node1, node2, trail, trail->pool));
 
4031
 
 
4032
  /* Is there a potential false positive and do we want to correct it? */
 
4033
  if (!args->strict || !*args->changed_p)
 
4034
    return SVN_NO_ERROR;
 
4035
 
 
4036
  /* Different representations. They might still have equal contents. */
 
4037
 
 
4038
  /* Compare MD5 checksums.  These should be readily accessible. */
 
4039
  SVN_ERR(svn_fs_base__dag_file_checksum(&checksum1, svn_checksum_md5,
 
4040
                                         node1, trail, trail->pool));
 
4041
  SVN_ERR(svn_fs_base__dag_file_checksum(&checksum2, svn_checksum_md5,
 
4042
                                         node2, trail, trail->pool));
 
4043
 
 
4044
  /* Different MD5 checksums -> different contents */
 
4045
  if (!svn_checksum_match(checksum1, checksum2))
 
4046
    return SVN_NO_ERROR;
 
4047
 
 
4048
  /* Paranoia. Compare SHA1 checksums because that's the level of
 
4049
     confidence we require for e.g. the working copy. */
 
4050
  SVN_ERR(svn_fs_base__dag_file_checksum(&checksum1, svn_checksum_sha1,
 
4051
                                         node1, trail, trail->pool));
 
4052
  SVN_ERR(svn_fs_base__dag_file_checksum(&checksum2, svn_checksum_sha1,
 
4053
                                         node2, trail, trail->pool));
 
4054
 
 
4055
  /* Different SHA1 checksums -> different contents */
 
4056
  if (checksum1 && checksum2)
 
4057
    {
 
4058
      *args->changed_p = !svn_checksum_match(checksum1, checksum2);
 
4059
      return SVN_NO_ERROR;
 
4060
    }
 
4061
 
 
4062
  /* SHA1 checksums are not available for very old reps / repositories. */
 
4063
  SVN_ERR(svn_fs_base__dag_get_contents(&stream1, node1, trail, trail->pool));
 
4064
  SVN_ERR(svn_fs_base__dag_get_contents(&stream2, node2, trail, trail->pool));
 
4065
  SVN_ERR(svn_stream_contents_same2(&same, stream1, stream2, trail->pool));
 
4066
 
 
4067
  /* Now, it's definitive. */
 
4068
  *args->changed_p = !same;
 
4069
  return SVN_NO_ERROR;
3950
4070
}
3951
4071
 
3952
4072
 
3958
4078
                      const char *path1,
3959
4079
                      svn_fs_root_t *root2,
3960
4080
                      const char *path2,
 
4081
                      svn_boolean_t strict,
3961
4082
                      apr_pool_t *pool)
3962
4083
{
3963
4084
  struct things_changed_args args;
3989
4110
  args.path2      = path2;
3990
4111
  args.changed_p  = changed_p;
3991
4112
  args.pool       = pool;
 
4113
  args.strict     = strict;
3992
4114
 
3993
4115
  return svn_fs_base__retry_txn(root1->fs, txn_body_contents_changed, &args,
3994
4116
                                TRUE, pool);
4108
4230
base_node_history(svn_fs_history_t **history_p,
4109
4231
                  svn_fs_root_t *root,
4110
4232
                  const char *path,
4111
 
                  apr_pool_t *pool)
 
4233
                  apr_pool_t *result_pool,
 
4234
                  apr_pool_t *scratch_pool)
4112
4235
{
4113
4236
  svn_node_kind_t kind;
4114
4237
 
4117
4240
    return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL);
4118
4241
 
4119
4242
  /* And we require that the path exist in the root. */
4120
 
  SVN_ERR(base_check_path(&kind, root, path, pool));
 
4243
  SVN_ERR(base_check_path(&kind, root, path, scratch_pool));
4121
4244
  if (kind == svn_node_none)
4122
4245
    return SVN_FS__NOT_FOUND(root, path);
4123
4246
 
4124
4247
  /* Okay, all seems well.  Build our history object and return it. */
4125
4248
  *history_p = assemble_history(root->fs,
4126
 
                                svn_fs__canonicalize_abspath(path, pool),
 
4249
                                svn_fs__canonicalize_abspath(path,
 
4250
                                                             result_pool),
4127
4251
                                root->rev, FALSE, NULL,
4128
 
                                SVN_INVALID_REVNUM, pool);
 
4252
                                SVN_INVALID_REVNUM, result_pool);
4129
4253
  return SVN_NO_ERROR;
4130
4254
}
4131
4255
 
4298
4422
     (which is either a real predecessor, or is the node itself
4299
4423
     playing the predecessor role to an imaginary mutable successor),
4300
4424
     then we need to report a copy.  */
4301
 
  if (svn_fs_base__key_compare(svn_fs_base__id_copy_id(node_id),
4302
 
                               end_copy_id) != 0)
 
4425
  if (strcmp(svn_fs_base__id_copy_id(node_id), end_copy_id) != 0)
4303
4426
    {
4304
4427
      const char *remainder;
4305
4428
      dag_node_t *dst_node;
4376
4499
base_history_prev(svn_fs_history_t **prev_history_p,
4377
4500
                  svn_fs_history_t *history,
4378
4501
                  svn_boolean_t cross_copies,
4379
 
                  apr_pool_t *pool)
 
4502
                  apr_pool_t *result_pool,
 
4503
                  apr_pool_t *scratch_pool)
4380
4504
{
4381
4505
  svn_fs_history_t *prev_history = NULL;
4382
4506
  base_history_data_t *bhd = history->fsap_data;
4390
4514
    {
4391
4515
      if (! bhd->is_interesting)
4392
4516
        prev_history = assemble_history(fs, "/", bhd->revision,
4393
 
                                        1, NULL, SVN_INVALID_REVNUM, pool);
 
4517
                                        1, NULL, SVN_INVALID_REVNUM,
 
4518
                                        result_pool);
4394
4519
      else if (bhd->revision > 0)
4395
4520
        prev_history = assemble_history(fs, "/", bhd->revision - 1,
4396
 
                                        1, NULL, SVN_INVALID_REVNUM, pool);
 
4521
                                        1, NULL, SVN_INVALID_REVNUM,
 
4522
                                        result_pool);
4397
4523
    }
4398
4524
  else
4399
4525
    {
4407
4533
          args.prev_history_p = &prev_history;
4408
4534
          args.history = prev_history;
4409
4535
          args.cross_copies = cross_copies;
4410
 
          args.pool = pool;
 
4536
          args.pool = result_pool;
4411
4537
          SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_history_prev, &args,
4412
 
                                         FALSE, pool));
 
4538
                                         FALSE, result_pool));
4413
4539
          if (! prev_history)
4414
4540
            break;
4415
4541
          bhd = prev_history->fsap_data;
5370
5496
  base_check_path,
5371
5497
  base_node_history,
5372
5498
  base_node_id,
 
5499
  base_node_relation,
5373
5500
  base_node_created_rev,
5374
5501
  base_node_origin_rev,
5375
5502
  base_node_created_path,
5376
5503
  base_delete_node,
 
5504
  base_copy,
 
5505
  base_revision_link,
5377
5506
  base_copied_from,
5378
5507
  base_closest_copy,
5379
5508
  base_node_prop,
5380
5509
  base_node_proplist,
 
5510
  base_node_has_props,
5381
5511
  base_change_node_prop,
5382
5512
  base_props_changed,
5383
5513
  base_dir_entries,
 
5514
  base_dir_optimal_order,
5384
5515
  base_make_dir,
5385
 
  base_copy,
5386
 
  base_revision_link,
5387
5516
  base_file_length,
5388
5517
  base_file_checksum,
5389
5518
  base_file_contents,