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

« back to all changes in this revision

Viewing changes to subversion/libsvn_fs_base/bdb/changes-table.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:
121
121
  return SVN_NO_ERROR;
122
122
}
123
123
 
 
124
/* Return a deep FS API type copy of SOURCE in internal format and allocate
 
125
 * the result in RESULT_POOL.
 
126
 */
 
127
static svn_fs_path_change2_t *
 
128
change_to_fs_change(const change_t *change,
 
129
                    apr_pool_t *result_pool)
 
130
{
 
131
  svn_fs_path_change2_t *result = svn_fs__path_change_create_internal(
 
132
                                    svn_fs_base__id_copy(change->noderev_id,
 
133
                                                         result_pool),
 
134
                                    change->kind,
 
135
                                    result_pool);
 
136
  result->text_mod = change->text_mod;
 
137
  result->prop_mod = change->prop_mod;
 
138
  result->node_kind = svn_node_unknown;
 
139
  result->copyfrom_known = FALSE;
 
140
 
 
141
  return result;
 
142
}
124
143
 
125
144
/* Merge the internal-use-only CHANGE into a hash of public-FS
126
145
   svn_fs_path_change2_t CHANGES, collapsing multiple changes into a
127
146
   single succinct change per path. */
128
147
static svn_error_t *
129
148
fold_change(apr_hash_t *changes,
 
149
            apr_hash_t *deletions,
130
150
            const change_t *change)
131
151
{
132
152
  apr_pool_t *pool = apr_hash_pool_get(changes);
185
205
        case svn_fs_path_change_reset:
186
206
          /* A reset here will simply remove the path change from the
187
207
             hash. */
188
 
          old_change = NULL;
 
208
          new_change = NULL;
189
209
          break;
190
210
 
191
211
        case svn_fs_path_change_delete:
194
214
              /* If the path was introduced in this transaction via an
195
215
                 add, and we are deleting it, just remove the path
196
216
                 altogether. */
197
 
              old_change = NULL;
 
217
              new_change = NULL;
 
218
            }
 
219
          else if (old_change->change_kind == svn_fs_path_change_replace)
 
220
            {
 
221
              /* A deleting a 'replace' restore the original deletion. */
 
222
              new_change = svn_hash_gets(deletions, path);
 
223
              SVN_ERR_ASSERT(new_change);
198
224
            }
199
225
          else
200
226
            {
201
227
              /* A deletion overrules all previous changes. */
202
 
              old_change->change_kind = svn_fs_path_change_delete;
203
 
              old_change->text_mod = change->text_mod;
204
 
              old_change->prop_mod = change->prop_mod;
 
228
              new_change = old_change;
 
229
              new_change->change_kind = svn_fs_path_change_delete;
 
230
              new_change->text_mod = change->text_mod;
 
231
              new_change->prop_mod = change->prop_mod;
205
232
            }
206
233
          break;
207
234
 
209
236
        case svn_fs_path_change_replace:
210
237
          /* An add at this point must be following a previous delete,
211
238
             so treat it just like a replace. */
212
 
          old_change->change_kind = svn_fs_path_change_replace;
213
 
          old_change->node_rev_id = svn_fs_base__id_copy(change->noderev_id,
214
 
                                                         pool);
215
 
          old_change->text_mod = change->text_mod;
216
 
          old_change->prop_mod = change->prop_mod;
 
239
 
 
240
          new_change = change_to_fs_change(change, pool);
 
241
          new_change->change_kind = svn_fs_path_change_replace;
 
242
 
 
243
          /* Remember the original deletion.
 
244
           * Make sure to allocate the hash key in a durable pool. */
 
245
          svn_hash_sets(deletions,
 
246
                        apr_pstrdup(apr_hash_pool_get(deletions), path),
 
247
                        old_change);
217
248
          break;
218
249
 
219
250
        case svn_fs_path_change_modify:
220
251
        default:
 
252
          new_change = old_change;
221
253
          if (change->text_mod)
222
 
            old_change->text_mod = TRUE;
 
254
            new_change->text_mod = TRUE;
223
255
          if (change->prop_mod)
224
 
            old_change->prop_mod = TRUE;
 
256
            new_change->prop_mod = TRUE;
225
257
          break;
226
258
        }
227
 
 
228
 
      /* Point our new_change to our (possibly modified) old_change. */
229
 
      new_change = old_change;
230
259
    }
231
260
  else
232
261
    {
233
262
      /* This change is new to the hash, so make a new public change
234
263
         structure from the internal one (in the hash's pool), and dup
235
264
         the path into the hash's pool, too. */
236
 
      new_change = svn_fs__path_change_create_internal(
237
 
                       svn_fs_base__id_copy(change->noderev_id, pool),
238
 
                       change->kind,
239
 
                       pool);
240
 
      new_change->text_mod = change->text_mod;
241
 
      new_change->prop_mod = change->prop_mod;
242
 
      new_change->node_kind = svn_node_unknown;
243
 
      new_change->copyfrom_known = FALSE;
 
265
      new_change = change_to_fs_change(change, pool);
244
266
      path = apr_pstrdup(pool, change->path);
245
267
    }
246
268
 
265
287
  svn_error_t *err = SVN_NO_ERROR;
266
288
  apr_hash_t *changes = apr_hash_make(pool);
267
289
  apr_pool_t *subpool = svn_pool_create(pool);
 
290
  apr_pool_t *iterpool = svn_pool_create(pool);
 
291
  apr_hash_t *deletions = apr_hash_make(subpool);
268
292
 
269
293
  /* Get a cursor on the first record matching KEY, and then loop over
270
294
     the records, adding them to the return array. */
286
310
      svn_skel_t *result_skel;
287
311
 
288
312
      /* Clear the per-iteration subpool. */
289
 
      svn_pool_clear(subpool);
 
313
      svn_pool_clear(iterpool);
290
314
 
291
315
      /* RESULT now contains a change record associated with KEY.  We
292
316
         need to parse that skel into an change_t structure ...  */
293
 
      result_skel = svn_skel__parse(result.data, result.size, subpool);
 
317
      result_skel = svn_skel__parse(result.data, result.size, iterpool);
294
318
      if (! result_skel)
295
319
        {
296
320
          err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
298
322
                                  key);
299
323
          goto cleanup;
300
324
        }
301
 
      err = svn_fs_base__parse_change_skel(&change, result_skel, subpool);
 
325
      err = svn_fs_base__parse_change_skel(&change, result_skel, iterpool);
302
326
      if (err)
303
327
        goto cleanup;
304
328
 
305
329
      /* ... and merge it with our return hash.  */
306
 
      err = fold_change(changes, change);
 
330
      err = fold_change(changes, deletions, change);
307
331
      if (err)
308
332
        goto cleanup;
309
333
 
319
343
        {
320
344
          apr_hash_index_t *hi;
321
345
 
322
 
          for (hi = apr_hash_first(subpool, changes);
 
346
          for (hi = apr_hash_first(iterpool, changes);
323
347
               hi;
324
348
               hi = apr_hash_next(hi))
325
349
            {
347
371
    }
348
372
 
349
373
  /* Destroy the per-iteration subpool. */
 
374
  svn_pool_destroy(iterpool);
350
375
  svn_pool_destroy(subpool);
351
376
 
352
377
  /* If there are no (more) change records for this KEY, we're