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

« back to all changes in this revision

Viewing changes to subversion/libsvn_wc/externals.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:
68
68
 * the revision if the revision is found.  Set REV_IDX to the index in
69
69
 * LINE_PARTS where the revision specification starts.  Remove from
70
70
 * LINE_PARTS the element(s) that specify the revision.
 
71
 * Set REV_STR to the element that specifies the revision.
71
72
 * PARENT_DIRECTORY_DISPLAY and LINE are given to return a nice error
72
73
 * string.
73
74
 *
76
77
 */
77
78
static svn_error_t *
78
79
find_and_remove_externals_revision(int *rev_idx,
 
80
                                   const char **rev_str,
79
81
                                   const char **line_parts,
80
82
                                   int num_line_parts,
81
83
                                   svn_wc_external_item2_t *item,
137
139
            line_parts[j] = line_parts[j+shift_count];
138
140
          line_parts[num_line_parts-shift_count] = NULL;
139
141
 
 
142
          *rev_str = apr_psprintf(pool, "-r%s", digits_ptr);
 
143
 
140
144
          /* Found the revision, so leave the function immediately, do
141
145
           * not continue looking for additional revisions. */
142
146
          return SVN_NO_ERROR;
158
162
}
159
163
 
160
164
svn_error_t *
161
 
svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
162
 
                                    const char *parent_directory,
 
165
svn_wc__parse_externals_description(apr_array_header_t **externals_p,
 
166
                                    apr_array_header_t **parser_infos_p,
 
167
                                    const char *defining_directory,
163
168
                                    const char *desc,
164
169
                                    svn_boolean_t canonicalize_url,
165
170
                                    apr_pool_t *pool)
166
171
{
167
172
  int i;
168
173
  apr_array_header_t *externals = NULL;
 
174
  apr_array_header_t *parser_infos = NULL;
169
175
  apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
170
 
  const char *parent_directory_display = svn_path_is_url(parent_directory) ?
171
 
    parent_directory : svn_dirent_local_style(parent_directory, pool);
 
176
  const char *defining_directory_display = svn_path_is_url(defining_directory) ?
 
177
    defining_directory : svn_dirent_local_style(defining_directory, pool);
172
178
 
173
179
  /* If an error occurs halfway through parsing, *externals_p should stay
174
180
   * untouched. So, store the list in a local var first. */
175
181
  if (externals_p)
176
182
    externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *));
177
183
 
 
184
  if (parser_infos_p)
 
185
    parser_infos =
 
186
      apr_array_make(pool, 1, sizeof(svn_wc__externals_parser_info_t *));
 
187
 
178
188
  for (i = 0; i < lines->nelts; i++)
179
189
    {
180
190
      const char *line = APR_ARRAY_IDX(lines, i, const char *);
186
196
      const char *token1;
187
197
      svn_boolean_t token0_is_url;
188
198
      svn_boolean_t token1_is_url;
 
199
      svn_wc__externals_parser_info_t *info = NULL;
189
200
 
190
201
      /* Index into line_parts where the revision specification
191
202
         started. */
192
203
      int rev_idx = -1;
 
204
      const char *rev_str = NULL;
193
205
 
194
206
      if ((! line) || (line[0] == '#'))
195
207
        continue;
209
221
      item->revision.kind = svn_opt_revision_unspecified;
210
222
      item->peg_revision.kind = svn_opt_revision_unspecified;
211
223
 
 
224
      if (parser_infos)
 
225
        info = apr_pcalloc(pool, sizeof(*info));
 
226
 
212
227
      /*
213
228
       * There are six different formats of externals:
214
229
       *
231
246
          (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
232
247
           _("Error parsing %s property on '%s': '%s'"),
233
248
           SVN_PROP_EXTERNALS,
234
 
           parent_directory_display,
 
249
           defining_directory_display,
235
250
           line);
236
251
 
237
252
      /* To make it easy to check for the forms, find and remove -r N
240
255
         set item->revision to the parsed revision. */
241
256
      /* ### ugh. stupid cast. */
242
257
      SVN_ERR(find_and_remove_externals_revision(&rev_idx,
 
258
                                                 &rev_str,
243
259
                                                 (const char **)line_parts,
244
260
                                                 num_line_parts, item,
245
 
                                                 parent_directory_display,
 
261
                                                 defining_directory_display,
246
262
                                                 line, pool));
247
263
 
248
264
      token0 = line_parts[0];
258
274
             "cannot use two absolute URLs ('%s' and '%s') in an external; "
259
275
             "one must be a path where an absolute or relative URL is "
260
276
             "checked out to"),
261
 
           SVN_PROP_EXTERNALS, parent_directory_display, token0, token1);
 
277
           SVN_PROP_EXTERNALS, defining_directory_display, token0, token1);
262
278
 
263
279
      if (0 == rev_idx && token1_is_url)
264
280
        return svn_error_createf
266
282
           _("Invalid %s property on '%s': "
267
283
             "cannot use a URL '%s' as the target directory for an external "
268
284
             "definition"),
269
 
           SVN_PROP_EXTERNALS, parent_directory_display, token1);
 
285
           SVN_PROP_EXTERNALS, defining_directory_display, token1);
270
286
 
271
287
      if (1 == rev_idx && token0_is_url)
272
288
        return svn_error_createf
274
290
           _("Invalid %s property on '%s': "
275
291
             "cannot use a URL '%s' as the target directory for an external "
276
292
             "definition"),
277
 
           SVN_PROP_EXTERNALS, parent_directory_display, token0);
 
293
           SVN_PROP_EXTERNALS, defining_directory_display, token0);
278
294
 
279
 
      /* The appearence of -r N or -rN forces the type of external.
 
295
      /* The appearance of -r N or -rN forces the type of external.
280
296
         If -r is at the beginning of the line or the first token is
281
297
         an absolute URL or if the second token is not an absolute
282
298
         URL, then the URL supports peg revisions. */
290
306
          SVN_ERR(svn_opt_parse_path(&item->peg_revision, &item->url,
291
307
                                     token0, pool));
292
308
          item->target_dir = token1;
 
309
 
 
310
          if (info)
 
311
            {
 
312
              info->format = svn_wc__external_description_format_2;
 
313
 
 
314
              if (rev_str)
 
315
                info->rev_str = apr_pstrdup(pool, rev_str);
 
316
 
 
317
              if (item->peg_revision.kind != svn_opt_revision_unspecified)
 
318
                info->peg_rev_str = strrchr(token0, '@');
 
319
            }
293
320
        }
294
321
      else
295
322
        {
296
323
          item->target_dir = token0;
297
324
          item->url = token1;
298
325
          item->peg_revision = item->revision;
 
326
 
 
327
          if (info)
 
328
            {
 
329
              info->format = svn_wc__external_description_format_1;
 
330
 
 
331
              if (rev_str)
 
332
                {
 
333
                  info->rev_str = apr_pstrdup(pool, rev_str);
 
334
                  info->peg_rev_str = info->rev_str;
 
335
                }
 
336
            }
299
337
        }
300
338
 
301
339
      SVN_ERR(svn_opt_resolve_revisions(&item->peg_revision,
316
354
           _("Invalid %s property on '%s': "
317
355
             "target '%s' is an absolute path or involves '..'"),
318
356
           SVN_PROP_EXTERNALS,
319
 
           parent_directory_display,
 
357
           defining_directory_display,
320
358
           item->target_dir);
321
359
 
322
360
      if (canonicalize_url)
333
371
 
334
372
      if (externals)
335
373
        APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
 
374
      if (parser_infos)
 
375
        APR_ARRAY_PUSH(parser_infos, svn_wc__externals_parser_info_t *) = info;
336
376
    }
337
377
 
338
378
  if (externals_p)
339
379
    *externals_p = externals;
 
380
  if (parser_infos_p)
 
381
    *parser_infos_p = parser_infos;
340
382
 
341
383
  return SVN_NO_ERROR;
342
384
}
343
385
 
344
386
svn_error_t *
 
387
svn_wc_parse_externals_description3(apr_array_header_t **externals_p,
 
388
                                    const char *defining_directory,
 
389
                                    const char *desc,
 
390
                                    svn_boolean_t canonicalize_url,
 
391
                                    apr_pool_t *pool)
 
392
{
 
393
  return svn_error_trace(svn_wc__parse_externals_description(externals_p,
 
394
                                                             NULL,
 
395
                                                             defining_directory,
 
396
                                                             desc,
 
397
                                                             canonicalize_url,
 
398
                                                             pool));
 
399
}
 
400
 
 
401
svn_error_t *
345
402
svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets,
346
403
                                   apr_array_header_t *externals,
347
404
                                   apr_pool_t *pool,
405
462
  const apr_array_header_t *ext_patterns;
406
463
  const char *diff3cmd;
407
464
 
408
 
  const char *url;
409
465
  const char *repos_root_url;
410
466
  const char *repos_uuid;
 
467
  const char *old_repos_relpath;
 
468
  const char *new_repos_relpath;
411
469
 
412
470
  const char *record_ancestor_abspath;
413
471
  const char *recorded_repos_relpath;
417
475
  /* Introducing a new file external */
418
476
  svn_boolean_t added;
419
477
 
420
 
  svn_wc_conflict_resolver_func2_t conflict_func;
421
 
  void *conflict_baton;
422
478
  svn_cancel_func_t cancel_func;
423
479
  void *cancel_baton;
424
480
  svn_wc_notify_func2_t notify_func;
431
487
  const svn_checksum_t *original_checksum;
432
488
 
433
489
  /* What we are installing now */
434
 
  const char *new_pristine_abspath;
 
490
  svn_wc__db_install_data_t *install_data;
435
491
  svn_checksum_t *new_sha1_checksum;
436
492
  svn_checksum_t *new_md5_checksum;
437
493
 
517
573
 
518
574
  *file_baton = eb;
519
575
  SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision,
520
 
                                   NULL, NULL, NULL, &eb->changed_rev,
 
576
                                   &eb->old_repos_relpath, NULL, NULL,
 
577
                                   &eb->changed_rev,
521
578
                                   &eb->changed_date, &eb->changed_author,
522
579
                                   NULL, &eb->original_checksum, NULL, NULL,
523
580
                                   &eb->had_props, NULL, NULL,
579
636
  else
580
637
    src_stream = svn_stream_empty(pool);
581
638
 
582
 
  SVN_ERR(svn_wc__open_writable_base(&dest_stream, &eb->new_pristine_abspath,
583
 
                                     &eb->new_md5_checksum,
584
 
                                     &eb->new_sha1_checksum,
585
 
                                     eb->db, eb->wri_abspath,
586
 
                                     eb->pool, pool));
 
639
  SVN_ERR(svn_wc__db_pristine_prepare_install(&dest_stream,
 
640
                                              &eb->install_data,
 
641
                                              &eb->new_sha1_checksum,
 
642
                                              &eb->new_md5_checksum,
 
643
                                              eb->db, eb->wri_abspath,
 
644
                                              eb->pool, pool));
587
645
 
588
646
  svn_txdelta_apply(src_stream, dest_stream, NULL, eb->local_abspath, pool,
589
647
                    handler, handler_baton);
603
661
 
604
662
  propchange = apr_array_push(eb->propchanges);
605
663
  propchange->name = apr_pstrdup(eb->pool, name);
606
 
  propchange->value = value ? svn_string_dup(value, eb->pool) : NULL;
 
664
  propchange->value = svn_string_dup(value, eb->pool);
607
665
 
608
666
  return SVN_NO_ERROR;
609
667
}
656
714
     behavior to the pristine store. */
657
715
  if (eb->new_sha1_checksum)
658
716
    {
659
 
      SVN_ERR(svn_wc__db_pristine_install(eb->db, eb->new_pristine_abspath,
 
717
      SVN_ERR(svn_wc__db_pristine_install(eb->install_data,
660
718
                                          eb->new_sha1_checksum,
661
719
                                          eb->new_md5_checksum, pool));
662
720
 
663
 
      eb->new_pristine_abspath = NULL;
 
721
      eb->install_data = NULL;
664
722
    }
665
723
 
666
724
  /* Merge the changes */
677
735
    const svn_checksum_t *original_checksum = NULL;
678
736
 
679
737
    svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision);
680
 
    const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
681
 
                                                      eb->url, pool);
682
738
 
683
739
    if (! added)
684
740
      {
767
823
      {
768
824
        svn_node_kind_t disk_kind;
769
825
        svn_boolean_t install_pristine = FALSE;
770
 
        const char *install_from = NULL;
771
826
 
772
827
        SVN_ERR(svn_io_check_path(eb->local_abspath, &disk_kind, pool));
773
828
 
832
887
          {
833
888
            SVN_ERR(svn_wc__wq_build_file_install(&work_item, eb->db,
834
889
                                            eb->local_abspath,
835
 
                                            install_from,
 
890
                                            NULL,
836
891
                                            eb->use_commit_times, TRUE,
837
892
                                            pool, pool));
838
893
 
853
908
                            svn_wc_conflict_version_create2(
854
909
                                    eb->repos_root_url,
855
910
                                    eb->repos_uuid,
856
 
                                    repos_relpath,
 
911
                                    eb->old_repos_relpath,
857
912
                                    eb->original_revision,
858
913
                                    svn_node_file,
859
914
                                    pool),
860
915
                            svn_wc_conflict_version_create2(
861
916
                                    eb->repos_root_url,
862
917
                                    eb->repos_uuid,
863
 
                                    repos_relpath,
 
918
                                    eb->new_repos_relpath,
864
919
                                    *eb->target_revision,
865
920
                                    svn_node_file,
866
921
                                    pool),
878
933
                        eb->db,
879
934
                        eb->local_abspath,
880
935
                        eb->wri_abspath,
881
 
                        repos_relpath,
 
936
                        eb->new_repos_relpath,
882
937
                        eb->repos_root_url,
883
938
                        eb->repos_uuid,
884
939
                        *eb->target_revision,
947
1002
 
948
1003
  if (!eb->file_closed)
949
1004
    {
 
1005
      apr_hash_t *wcroot_iprops = NULL;
950
1006
      /* The file wasn't updated, but its url or revision might have...
951
1007
         e.g. switch between branches for relative externals.
952
1008
 
954
1010
         investigating when we should and shouldn't update it...
955
1011
         and avoid hard to debug edge cases */
956
1012
 
957
 
      svn_node_kind_t kind;
958
 
      const char *old_repos_relpath;
959
 
      svn_revnum_t changed_rev;
960
 
      apr_time_t changed_date;
961
 
      const char *changed_author;
962
 
      const svn_checksum_t *checksum;
963
 
      apr_hash_t *pristine_props;
964
 
      const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
965
 
                                                        eb->url, pool);
966
 
 
967
 
      SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
968
 
                                       NULL, NULL, &changed_rev, &changed_date,
969
 
                                       &changed_author, NULL, &checksum, NULL,
970
 
                                       NULL, NULL, &pristine_props, NULL,
971
 
                                       eb->db, eb->local_abspath,
972
 
                                       pool, pool));
973
 
 
974
 
      if (kind != svn_node_file)
975
 
        return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
976
 
                                   _("Node '%s' is no existing file external"),
977
 
                                   svn_dirent_local_style(eb->local_abspath,
978
 
                                                          pool));
979
 
 
980
 
      SVN_ERR(svn_wc__db_external_add_file(
981
 
                    eb->db,
982
 
                    eb->local_abspath,
983
 
                    eb->wri_abspath,
984
 
                    repos_relpath,
985
 
                    eb->repos_root_url,
986
 
                    eb->repos_uuid,
987
 
                    *eb->target_revision,
988
 
                    pristine_props,
989
 
                    eb->iprops,
990
 
                    eb->changed_rev,
991
 
                    eb->changed_date,
992
 
                    eb->changed_author,
993
 
                    checksum,
994
 
                    NULL /* clear dav props */,
995
 
                    eb->record_ancestor_abspath,
996
 
                    eb->recorded_repos_relpath,
997
 
                    eb->recorded_peg_revision,
998
 
                    eb->recorded_revision,
999
 
                    FALSE, NULL,
1000
 
                    TRUE /* keep_recorded_info */,
1001
 
                    NULL /* conflict_skel */,
1002
 
                    NULL /* work_items */,
1003
 
                    pool));
 
1013
      if (eb->iprops)
 
1014
        {
 
1015
          wcroot_iprops = apr_hash_make(pool);
 
1016
          svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
 
1017
        }
 
1018
 
 
1019
      SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
 
1020
                                                       eb->local_abspath,
 
1021
                                                       svn_depth_infinity,
 
1022
                                                       eb->new_repos_relpath,
 
1023
                                                       eb->repos_root_url,
 
1024
                                                       eb->repos_uuid,
 
1025
                                                       *eb->target_revision,
 
1026
                                                       apr_hash_make(pool)
 
1027
                                                       /* exclude_relpaths */,
 
1028
                                                       wcroot_iprops,
 
1029
                                                       TRUE /* empty update */,
 
1030
                                                       eb->notify_func,
 
1031
                                                       eb->notify_baton,
 
1032
                                                       pool));
1004
1033
    }
1005
1034
 
1006
1035
  return SVN_NO_ERROR;
1024
1053
                                 const char *recorded_url,
1025
1054
                                 const svn_opt_revision_t *recorded_peg_rev,
1026
1055
                                 const svn_opt_revision_t *recorded_rev,
1027
 
                                 svn_wc_conflict_resolver_func2_t conflict_func,
1028
 
                                 void *conflict_baton,
1029
1056
                                 svn_cancel_func_t cancel_func,
1030
1057
                                 void *cancel_baton,
1031
1058
                                 svn_wc_notify_func2_t notify_func,
1048
1075
  eb->name = svn_dirent_basename(eb->local_abspath, NULL);
1049
1076
  eb->target_revision = target_revision;
1050
1077
 
1051
 
  eb->url = apr_pstrdup(edit_pool, url);
1052
1078
  eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
1053
1079
  eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
 
1080
  eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url, edit_pool);
 
1081
  eb->old_repos_relpath = eb->new_repos_relpath;
 
1082
 
 
1083
  eb->original_revision = SVN_INVALID_REVNUM;
1054
1084
 
1055
1085
  eb->iprops = iprops;
1056
1086
 
1074
1104
  else
1075
1105
    eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */
1076
1106
 
1077
 
  eb->conflict_func = conflict_func;
1078
 
  eb->conflict_baton = conflict_baton;
1079
1107
  eb->cancel_func = cancel_func;
1080
1108
  eb->cancel_baton = cancel_baton;
1081
1109
  eb->notify_func = notify_func;
1445
1473
  else
1446
1474
    {
1447
1475
      SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
1448
 
                                     FALSE /* keep_as_working */,
1449
 
                                     TRUE /* queue_deletes */,
1450
 
                                     FALSE /* remove_locks */,
1451
 
                                     SVN_INVALID_REVNUM,
 
1476
                                     FALSE, TRUE, FALSE,
 
1477
                                     0,
1452
1478
                                     NULL, NULL, scratch_pool));
1453
1479
      SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
1454
1480
                             cancel_func, cancel_baton,
1591
1617
                        apr_pstrndup(scratch_pool, url, num_leading_slashes),
1592
1618
                        svn_relpath_canonicalize(url + num_leading_slashes,
1593
1619
                                                 scratch_pool),
1594
 
                        (char*)NULL);
 
1620
                        SVN_VA_NULL);
1595
1621
    }
1596
1622
  else
1597
1623
    {
1698
1724
 
1699
1725
      SVN_ERR(uri_scheme(&scheme, repos_root_url, scratch_pool));
1700
1726
      *resolved_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool, scheme,
1701
 
                                                       ":", url, (char *)NULL),
 
1727
                                                       ":", url, SVN_VA_NULL),
1702
1728
                                           result_pool);
1703
1729
      return SVN_NO_ERROR;
1704
1730
    }