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

« back to all changes in this revision

Viewing changes to subversion/tests/svn_test_fs.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:
75
75
               apr_pool_t *pool)
76
76
{
77
77
  apr_hash_t *fs_config = apr_hash_make(pool);
78
 
  apr_hash_set(fs_config, SVN_FS_CONFIG_BDB_TXN_NOSYNC,
79
 
               APR_HASH_KEY_STRING, "1");
80
 
  apr_hash_set(fs_config, SVN_FS_CONFIG_FS_TYPE,
81
 
               APR_HASH_KEY_STRING,
82
 
               fs_type);
 
78
 
 
79
  svn_hash_sets(fs_config, SVN_FS_CONFIG_BDB_TXN_NOSYNC, "1");
 
80
  svn_hash_sets(fs_config, SVN_FS_CONFIG_BDB_LOG_AUTOREMOVE, "1");
 
81
  svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, fs_type);
83
82
  if (server_minor_version)
84
83
    {
 
84
      svn_hash_sets(fs_config, SVN_FS_CONFIG_COMPATIBLE_VERSION,
 
85
                    apr_psprintf(pool, "1.%d.0", server_minor_version));
85
86
      if (server_minor_version == 6 || server_minor_version == 7)
86
87
        svn_hash_sets(fs_config, SVN_FS_CONFIG_PRE_1_8_COMPATIBLE, "1");
87
88
      else if (server_minor_version == 5)
103
104
          const char *name,
104
105
          const char *fs_type,
105
106
          int server_minor_version,
 
107
          apr_hash_t *overlay_fs_config,
106
108
          apr_pool_t *pool)
107
109
{
108
 
  apr_finfo_t finfo;
109
110
  apr_hash_t *fs_config = make_fs_config(fs_type, server_minor_version, pool);
110
111
 
 
112
  if (overlay_fs_config)
 
113
    fs_config = apr_hash_overlay(pool, overlay_fs_config, fs_config);
 
114
 
111
115
  /* If there's already a repository named NAME, delete it.  Doing
112
116
     things this way means that repositories stick around after a
113
117
     failure for postmortem analysis, but also that tests can be
114
118
     re-run without cleaning out the repositories created by prior
115
119
     runs.  */
116
 
  if (apr_stat(&finfo, name, APR_FINFO_TYPE, pool) == APR_SUCCESS)
117
 
    {
118
 
      if (finfo.filetype == APR_DIR)
119
 
        SVN_ERR_W(svn_io_remove_dir2(name, TRUE, NULL, NULL, pool),
120
 
                  apr_psprintf(pool,
121
 
                               "cannot create fs '%s' there is already "
122
 
                               "a directory of that name", name));
123
 
      else
124
 
        return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
125
 
                                 "cannot create fs '%s' there is already "
126
 
                                 "a file of that name", name);
127
 
    }
 
120
  SVN_ERR(svn_io_remove_dir2(name, TRUE, NULL, NULL, pool));
128
121
 
129
122
  SVN_ERR(svn_fs_create(fs_p, name, fs_config, pool));
130
123
  if (! *fs_p)
144
137
 * copy that file into the filesystem FS and set *MUST_REOPEN to TRUE, else
145
138
 * set *MUST_REOPEN to FALSE. */
146
139
static svn_error_t *
147
 
maybe_install_fsfs_conf(svn_fs_t *fs,
148
 
                        const svn_test_opts_t *opts,
149
 
                        svn_boolean_t *must_reopen,
150
 
                        apr_pool_t *pool)
 
140
maybe_install_fs_conf(svn_fs_t *fs,
 
141
                      const svn_test_opts_t *opts,
 
142
                      svn_boolean_t *must_reopen,
 
143
                      apr_pool_t *pool)
151
144
{
152
145
  *must_reopen = FALSE;
153
 
  if (strcmp(opts->fs_type, "fsfs") != 0 || ! opts->config_file)
 
146
  if (! opts->config_file)
154
147
    return SVN_NO_ERROR;
155
148
 
156
 
  *must_reopen = TRUE;
157
 
  return svn_io_copy_file(opts->config_file,
158
 
                          svn_path_join(svn_fs_path(fs, pool),
159
 
                                        "fsfs.conf", pool),
160
 
                          FALSE /* copy_perms */,
161
 
                          pool);
 
149
  if (strcmp(opts->fs_type, "fsfs") == 0)
 
150
    {
 
151
      *must_reopen = TRUE;
 
152
      return svn_io_copy_file(opts->config_file,
 
153
                              svn_path_join(svn_fs_path(fs, pool),
 
154
                                            "fsfs.conf", pool),
 
155
                              FALSE /* copy_perms */,
 
156
                              pool);
 
157
    }
 
158
 
 
159
  if (strcmp(opts->fs_type, "fsx") == 0)
 
160
    {
 
161
      *must_reopen = TRUE;
 
162
      return svn_io_copy_file(opts->config_file,
 
163
                              svn_path_join(svn_fs_path(fs, pool),
 
164
                                            "fsx.conf", pool),
 
165
                              FALSE /* copy_perms */,
 
166
                              pool);
 
167
    }
 
168
 
 
169
  return SVN_NO_ERROR;
162
170
}
163
171
 
164
172
 
168
176
                        const svn_test_opts_t *opts,
169
177
                        apr_pool_t *pool)
170
178
{
171
 
  return create_fs(fs_p, name, "bdb", opts->server_minor_version, pool);
172
 
}
173
 
 
 
179
  return create_fs(fs_p, name, "bdb", opts->server_minor_version, NULL, pool);
 
180
}
 
181
 
 
182
 
 
183
svn_error_t *
 
184
svn_test__create_fs2(svn_fs_t **fs_p,
 
185
                     const char *name,
 
186
                     const svn_test_opts_t *opts,
 
187
                     apr_hash_t *fs_config,
 
188
                     apr_pool_t *pool)
 
189
{
 
190
  svn_boolean_t must_reopen;
 
191
 
 
192
  SVN_ERR(create_fs(fs_p, name, opts->fs_type, opts->server_minor_version,
 
193
                    fs_config, pool));
 
194
 
 
195
  SVN_ERR(maybe_install_fs_conf(*fs_p, opts, &must_reopen, pool));
 
196
  if (must_reopen)
 
197
    {
 
198
      SVN_ERR(svn_fs_open2(fs_p, name, NULL, pool, pool));
 
199
      svn_fs_set_warning_func(*fs_p, fs_warning_handler, NULL);
 
200
    }
 
201
 
 
202
  return SVN_NO_ERROR;
 
203
}
174
204
 
175
205
svn_error_t *
176
206
svn_test__create_fs(svn_fs_t **fs_p,
178
208
                    const svn_test_opts_t *opts,
179
209
                    apr_pool_t *pool)
180
210
{
 
211
  return svn_test__create_fs2(fs_p, name, opts, NULL, pool);
 
212
}
 
213
 
 
214
svn_error_t *
 
215
svn_test__create_repos2(svn_repos_t **repos_p,
 
216
                        const char **repos_url,
 
217
                        const char **repos_dirent,
 
218
                        const char *name,
 
219
                        const svn_test_opts_t *opts,
 
220
                        apr_pool_t *result_pool,
 
221
                        apr_pool_t *scratch_pool)
 
222
{
 
223
  svn_repos_t *repos;
181
224
  svn_boolean_t must_reopen;
182
 
 
183
 
  SVN_ERR(create_fs(fs_p, name, opts->fs_type,
184
 
                    opts->server_minor_version, pool));
185
 
 
186
 
  SVN_ERR(maybe_install_fsfs_conf(*fs_p, opts, &must_reopen, pool));
 
225
  const char *repos_abspath;
 
226
  apr_pool_t *repos_pool = repos_p ? result_pool : scratch_pool;
 
227
  svn_boolean_t init_svnserve = FALSE;
 
228
  apr_hash_t *fs_config = make_fs_config(opts->fs_type,
 
229
                                         opts->server_minor_version,
 
230
                                         repos_pool);
 
231
 
 
232
  if (repos_url && opts->repos_dir && opts->repos_url)
 
233
    {
 
234
      name = apr_psprintf(scratch_pool, "%s-%s", opts->prog_name,
 
235
                          svn_dirent_basename(name, NULL));
 
236
 
 
237
      repos_abspath = svn_dirent_join(opts->repos_dir, name, scratch_pool);
 
238
 
 
239
      SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath,
 
240
                                      scratch_pool));
 
241
 
 
242
      SVN_ERR(svn_io_make_dir_recursively(repos_abspath, scratch_pool));
 
243
 
 
244
      *repos_url = svn_path_url_add_component2(opts->repos_url, name,
 
245
                                               result_pool);
 
246
 
 
247
      if (strstr(opts->repos_url, "svn://"))
 
248
        init_svnserve = TRUE;
 
249
    }
 
250
  else
 
251
    {
 
252
      SVN_ERR(svn_dirent_get_absolute(&repos_abspath, name, scratch_pool));
 
253
 
 
254
      if (repos_url)
 
255
        SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_abspath,
 
256
                                                 result_pool));
 
257
    }
 
258
 
 
259
  /* If there's already a repository named NAME, delete it.  Doing
 
260
     things this way means that repositories stick around after a
 
261
     failure for postmortem analysis, but also that tests can be
 
262
     re-run without cleaning out the repositories created by prior
 
263
     runs.  */
 
264
  SVN_ERR(svn_io_remove_dir2(repos_abspath, TRUE, NULL, NULL, scratch_pool));
 
265
 
 
266
  SVN_ERR(svn_repos_create(&repos, repos_abspath, NULL, NULL, NULL,
 
267
                           fs_config, repos_pool));
 
268
 
 
269
  /* Register this repo for cleanup. */
 
270
  svn_test_add_dir_cleanup(repos_abspath);
 
271
 
 
272
  SVN_ERR(maybe_install_fs_conf(svn_repos_fs(repos), opts, &must_reopen,
 
273
                                scratch_pool));
187
274
  if (must_reopen)
188
275
    {
189
 
      SVN_ERR(svn_fs_open(fs_p, name, NULL, pool));
190
 
      svn_fs_set_warning_func(*fs_p, fs_warning_handler, NULL);
191
 
    }
 
276
      SVN_ERR(svn_repos_open3(&repos, repos_abspath, NULL, repos_pool,
 
277
                              scratch_pool));
 
278
    }
 
279
 
 
280
  svn_fs_set_warning_func(svn_repos_fs(repos), fs_warning_handler, NULL);
 
281
 
 
282
  if (init_svnserve)
 
283
    {
 
284
      const char *cfg;
 
285
      const char *pwd;
 
286
 
 
287
      cfg = svn_dirent_join(repos_abspath, "conf/svnserve.conf", scratch_pool);
 
288
      SVN_ERR(svn_io_remove_file2(cfg, FALSE, scratch_pool));
 
289
      SVN_ERR(svn_io_file_create(cfg,
 
290
                                 "[general]\n"
 
291
                                 "auth-access = write\n"
 
292
                                 "password-db = passwd\n",
 
293
                                 scratch_pool));
 
294
 
 
295
      pwd = svn_dirent_join(repos_abspath, "conf/passwd", scratch_pool);
 
296
      SVN_ERR(svn_io_remove_file2(pwd, FALSE, scratch_pool));
 
297
      SVN_ERR(svn_io_file_create(pwd,
 
298
                                 "[users]\n"
 
299
                                 "jrandom = rayjandom\n"
 
300
                                 "jconstant = rayjandom\n",
 
301
                                 scratch_pool));
 
302
    }
 
303
 
 
304
  if (repos_p)
 
305
    *repos_p = repos;
 
306
  if (repos_dirent)
 
307
    *repos_dirent = apr_pstrdup(result_pool, repos_abspath);
192
308
 
193
309
  return SVN_NO_ERROR;
194
310
}
195
311
 
196
 
 
197
312
svn_error_t *
198
313
svn_test__create_repos(svn_repos_t **repos_p,
199
314
                       const char *name,
200
315
                       const svn_test_opts_t *opts,
201
316
                       apr_pool_t *pool)
202
317
{
203
 
  apr_finfo_t finfo;
204
 
  svn_repos_t *repos;
205
 
  svn_boolean_t must_reopen;
206
 
  apr_hash_t *fs_config = make_fs_config(opts->fs_type,
207
 
                                         opts->server_minor_version, pool);
208
 
 
209
 
  /* If there's already a repository named NAME, delete it.  Doing
210
 
     things this way means that repositories stick around after a
211
 
     failure for postmortem analysis, but also that tests can be
212
 
     re-run without cleaning out the repositories created by prior
213
 
     runs.  */
214
 
  if (apr_stat(&finfo, name, APR_FINFO_TYPE, pool) == APR_SUCCESS)
215
 
    {
216
 
      if (finfo.filetype == APR_DIR)
217
 
        SVN_ERR_W(svn_io_remove_dir2(name, TRUE, NULL, NULL, pool),
218
 
                  apr_psprintf(pool,
219
 
                               "cannot create repos '%s' there is already "
220
 
                               "a directory of that name", name));
221
 
      else
222
 
        return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
223
 
                                 "there is already a file named '%s'", name);
224
 
    }
225
 
 
226
 
  SVN_ERR(svn_repos_create(&repos, name, NULL, NULL, NULL,
227
 
                           fs_config, pool));
228
 
 
229
 
  /* Register this repo for cleanup. */
230
 
  svn_test_add_dir_cleanup(name);
231
 
 
232
 
  SVN_ERR(maybe_install_fsfs_conf(svn_repos_fs(repos), opts, &must_reopen,
233
 
                                  pool));
234
 
  if (must_reopen)
235
 
    {
236
 
      SVN_ERR(svn_repos_open2(&repos, name, NULL, pool));
237
 
      svn_fs_set_warning_func(svn_repos_fs(repos), fs_warning_handler, NULL);
238
 
    }
239
 
 
240
 
  *repos_p = repos;
241
 
  return SVN_NO_ERROR;
 
318
  return svn_error_trace(
 
319
            svn_test__create_repos2(repos_p, NULL, NULL, name,
 
320
                                    opts, pool, pool));
242
321
}
243
322
 
244
323
svn_error_t *
264
343
  do
265
344
    {
266
345
      len = sizeof(buf);
267
 
      SVN_ERR(svn_stream_read(stream, buf, &len));
 
346
      SVN_ERR(svn_stream_read_full(stream, buf, &len));
268
347
 
269
348
      /* Now copy however many bytes were *actually* read into str. */
270
349
      svn_stringbuf_appendbytes(str, buf, len);
355
434
}
356
435
 
357
436
 
 
437
/* Verify that PATH under ROOT is: a directory if contents is NULL;
 
438
   a file with contents CONTENTS otherwise. */
358
439
static svn_error_t *
359
440
validate_tree_entry(svn_fs_root_t *root,
360
441
                    const char *path,
363
444
{
364
445
  svn_stream_t *rstream;
365
446
  svn_stringbuf_t *rstring;
366
 
  svn_boolean_t is_dir;
 
447
  svn_node_kind_t kind;
 
448
  svn_boolean_t is_dir, is_file;
 
449
 
 
450
  /* Verify that node types are reported consistently. */
 
451
  SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
 
452
  SVN_ERR(svn_fs_is_dir(&is_dir, root, path, pool));
 
453
  SVN_ERR(svn_fs_is_file(&is_file, root, path, pool));
 
454
 
 
455
  SVN_TEST_ASSERT(!is_dir || kind == svn_node_dir);
 
456
  SVN_TEST_ASSERT(!is_file || kind == svn_node_file);
 
457
  SVN_TEST_ASSERT(is_dir || is_file);
367
458
 
368
459
  /* Verify that this is the expected type of node */
369
 
  SVN_ERR(svn_fs_is_dir(&is_dir, root, path, pool));
370
460
  if ((!is_dir && !contents) || (is_dir && contents))
371
461
    return svn_error_createf
372
462
      (SVN_ERR_FS_GENERAL, NULL,
376
466
  /* Verify that the contents are as expected (files only) */
377
467
  if (! is_dir)
378
468
    {
 
469
      svn_stringbuf_t *expected = svn_stringbuf_create(contents, pool);
 
470
 
 
471
      /* File lengths. */
 
472
      svn_filesize_t length;
 
473
      SVN_ERR(svn_fs_file_length(&length, root, path, pool));
 
474
      SVN_TEST_ASSERT(expected->len == length);
 
475
 
 
476
      /* Text contents. */
379
477
      SVN_ERR(svn_fs_file_contents(&rstream, root, path, pool));
380
478
      SVN_ERR(svn_test__stream_to_string(&rstring, rstream, pool));
381
 
      if (! svn_stringbuf_compare(rstring,
382
 
                                  svn_stringbuf_create(contents, pool)))
 
479
      if (! svn_stringbuf_compare(rstring, expected))
383
480
        return svn_error_createf
384
481
          (SVN_ERR_FS_GENERAL, NULL,
385
482
           "node '%s' in tree had unexpected contents",
409
506
  apr_hash_index_t *hi;
410
507
  int i;
411
508
 
 
509
  /* There should be no entry with this name. */
 
510
  const char *na_name = "es-vee-en";
 
511
 
412
512
  /* Create a hash for storing our expected entries */
413
513
  expected_entries = apr_hash_make(subpool);
414
514
 
497
597
      svn_stringbuf_appendcstr(extra_entries, "\n");
498
598
    }
499
599
 
 
600
  /* Test that non-existent paths will not be found.
 
601
   * Skip this test if somebody sneakily added NA_NAME. */
 
602
  if (!svn_hash_gets(expected_entries, na_name))
 
603
    {
 
604
      svn_node_kind_t kind;
 
605
      svn_boolean_t is_dir, is_file;
 
606
 
 
607
      /* Verify that the node is reported as "n/a". */
 
608
      SVN_ERR(svn_fs_check_path(&kind, root, na_name, subpool));
 
609
      SVN_ERR(svn_fs_is_dir(&is_dir, root, na_name, subpool));
 
610
      SVN_ERR(svn_fs_is_file(&is_file, root, na_name, subpool));
 
611
 
 
612
      SVN_TEST_ASSERT(kind == svn_node_none);
 
613
      SVN_TEST_ASSERT(!is_file);
 
614
      SVN_TEST_ASSERT(!is_dir);
 
615
    }
 
616
 
500
617
  if (missing_entries || extra_entries || corrupt_entries)
501
618
    {
502
619
      return svn_error_createf
530
647
  {
531
648
    int i;
532
649
    for (i=0, hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi))
533
 
      SVN_DBG(("expected[%d] = '%s'\n", i++, svn__apr_hash_index_key(hi)));
 
650
      SVN_DBG(("expected[%d] = '%s'\n", i++, apr_hash_this_key(hi)));
534
651
    for (i=0, hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi))
535
 
      SVN_DBG(("actual[%d] = '%s'\n", i++, svn__apr_hash_index_key(hi)));
 
652
      SVN_DBG(("actual[%d] = '%s'\n", i++, apr_hash_this_key(hi)));
536
653
  }
537
654
#endif
538
655
 
539
656
  for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi))
540
 
    if (NULL == svn_hash_gets(actual, svn__apr_hash_index_key(hi)))
 
657
    if (NULL == svn_hash_gets(actual, apr_hash_this_key(hi)))
541
658
      return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
542
659
                               "Path '%s' missing from actual changed-paths",
543
 
                               svn__apr_hash_index_key(hi));
 
660
                               (const char *)apr_hash_this_key(hi));
544
661
 
545
662
  for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi))
546
 
    if (NULL == svn_hash_gets(expected, svn__apr_hash_index_key(hi)))
 
663
    if (NULL == svn_hash_gets(expected, apr_hash_this_key(hi)))
547
664
      return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
548
665
                               "Path '%s' missing from expected changed-paths",
549
 
                               svn__apr_hash_index_key(hi));
 
666
                               (const char *)apr_hash_this_key(hi));
550
667
 
551
668
  return SVN_NO_ERROR;
552
669
}