View | Details | Raw Unified | Return to bug 60610
Collapse All | Expand All

(-)subversion/mod_dav_svn/log.c (-9 / +19 lines)
Lines 32-37 Link Here
32
32
33
#include "dav_svn.h"
33
#include "dav_svn.h"
34
34
35
/* Private header included just for 1.0.7 get_logs() security fix. */
36
#include "../libsvn_repos/repos.h"
35
37
36
struct log_receiver_baton
38
struct log_receiver_baton
37
{
39
{
Lines 208-213 Link Here
208
  dav_error *derr = NULL;
210
  dav_error *derr = NULL;
209
  apr_xml_elem *child;
211
  apr_xml_elem *child;
210
  struct log_receiver_baton lrb;
212
  struct log_receiver_baton lrb;
213
  dav_svn_authz_read_baton arb;
211
  const dav_svn_repos *repos = resource->info->repos;
214
  const dav_svn_repos *repos = resource->info->repos;
212
  const char *target = NULL;
215
  const char *target = NULL;
213
  int ns;
216
  int ns;
Lines 279-284 Link Here
279
      /* else unknown element; skip it */
282
      /* else unknown element; skip it */
280
    }
283
    }
281
284
285
  /* Build authz read baton */
286
  arb.r = resource->info->r;
287
  arb.repos = resource->info->repos;
288
289
  /* Build log receiver baton */
282
  lrb.bb = apr_brigade_create(resource->pool,  /* not the subpool! */
290
  lrb.bb = apr_brigade_create(resource->pool,  /* not the subpool! */
283
                              output->c->bucket_alloc);
291
                              output->c->bucket_alloc);
284
  lrb.output = output;
292
  lrb.output = output;
Lines 290-304 Link Here
290
     flag in our log_receiver_baton structure). */
298
     flag in our log_receiver_baton structure). */
291
299
292
  /* Send zero or more log items. */
300
  /* Send zero or more log items. */
293
  serr = svn_repos_get_logs(repos->repos,
301
  serr = svn_repos__get_logs2(repos->repos,
294
                            paths,
302
                              paths,
295
                            start,
303
                              start,
296
                            end,
304
                              end,
297
                            discover_changed_paths,
305
                              discover_changed_paths,
298
                            strict_node_history,
306
                              strict_node_history,
299
                            log_receiver,
307
                              dav_svn_authz_read,
300
                            &lrb,
308
                              &arb,
301
                            resource->pool);
309
                              log_receiver,
310
                              &lrb,
311
                              resource->pool);
302
  if (serr)
312
  if (serr)
303
    {
313
    {
304
      derr = dav_svn_convert_err(serr, HTTP_BAD_REQUEST, serr->message,
314
      derr = dav_svn_convert_err(serr, HTTP_BAD_REQUEST, serr->message,
(-)subversion/libsvn_repos/log.c (-22 / +149 lines)
Lines 40-55 Link Here
40
 * the value is (void *) 'U', 'A', 'D', or 'R', for modified, added,
40
 * the value is (void *) 'U', 'A', 'D', or 'R', for modified, added,
41
 * deleted, or replaced, respectively.
41
 * deleted, or replaced, respectively.
42
 * 
42
 * 
43
 * If optional AUTHZ_READ_FUNC is non-NULL, then use it (with
44
 * AUTHZ_READ_BATON and FS) to check whether each changed-path (and
45
 * copyfrom_path) is readable:
46
 *
47
 *     - If some paths are readable and some are not, then silently
48
 *     omit the unreadable paths from the CHANGED hash, and return
49
 *     SVN_ERR_ENTRY_NOT_FOUND.
50
 *
51
 *     - If absolutely every changed-path (and copyfrom_path) is
52
 *     unreadable, then return an empty CHANGED hash and
53
 *     APR_EGENERAL.  (This is to distinguish a revision
54
 *     which truly has no changed paths from a revision in which all
55
 *     paths are unreadable.)
43
 */
56
 */
44
static svn_error_t *
57
static svn_error_t *
45
detect_changed (apr_hash_t **changed,
58
detect_changed (apr_hash_t **changed,
46
                svn_fs_root_t *root,
59
                svn_fs_root_t *root,
60
                svn_fs_t *fs,
61
                svn_repos_authz_func_t authz_read_func,
62
                void *authz_read_baton,
47
                apr_pool_t *pool)
63
                apr_pool_t *pool)
48
{
64
{
49
  apr_hash_t *changes;
65
  apr_hash_t *changes;
50
  apr_hash_index_t *hi;
66
  apr_hash_index_t *hi;
51
  apr_pool_t *subpool = svn_pool_create (pool);
67
  apr_pool_t *subpool = svn_pool_create (pool);
52
  
68
  svn_boolean_t found_readable = FALSE;
69
  svn_boolean_t found_unreadable = FALSE;
70
53
  *changed = apr_hash_make (pool);
71
  *changed = apr_hash_make (pool);
54
  SVN_ERR (svn_fs_paths_changed (&changes, root, pool));
72
  SVN_ERR (svn_fs_paths_changed (&changes, root, pool));
55
  for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi))
73
  for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi))
Lines 68-73 Link Here
68
      path = (const char *) key;
86
      path = (const char *) key;
69
      change = val;
87
      change = val;
70
88
89
      /* Skip path if unreadable. */
90
      if (authz_read_func)
91
        {
92
          svn_boolean_t readable;
93
          SVN_ERR (authz_read_func (&readable,
94
                                    root, path,
95
                                    authz_read_baton, subpool));
96
          if (! readable)
97
            {
98
              found_unreadable = TRUE;
99
              continue;
100
            }
101
        }
102
103
      /* At least one changed-path was readable. */
104
      found_readable = TRUE;
105
71
      switch (change->change_kind)
106
      switch (change->change_kind)
72
        {
107
        {
73
        case svn_fs_path_change_reset:
108
        case svn_fs_path_change_reset:
Lines 101-110 Link Here
101
136
102
          SVN_ERR (svn_fs_copied_from (&copyfrom_rev, &copyfrom_path,
137
          SVN_ERR (svn_fs_copied_from (&copyfrom_rev, &copyfrom_path,
103
                                       root, path, subpool));
138
                                       root, path, subpool));
139
104
          if (copyfrom_path && SVN_IS_VALID_REVNUM (copyfrom_rev))
140
          if (copyfrom_path && SVN_IS_VALID_REVNUM (copyfrom_rev))
105
            {
141
            {
106
              item->copyfrom_path = apr_pstrdup (pool, copyfrom_path);
142
              svn_boolean_t readable = TRUE;
107
              item->copyfrom_rev = copyfrom_rev;
143
144
              if (authz_read_func)
145
                {
146
                  svn_fs_root_t *copyfrom_root;
147
                  
148
                  SVN_ERR (svn_fs_revision_root (&copyfrom_root, fs,
149
                                                 copyfrom_rev, subpool));
150
                  SVN_ERR (authz_read_func (&readable,
151
                                            copyfrom_root, copyfrom_path,
152
                                            authz_read_baton, subpool));
153
                  if (! readable)
154
                    found_unreadable = TRUE;
155
                }
156
157
              if (readable)
158
                {
159
                  item->copyfrom_path = apr_pstrdup (pool, copyfrom_path);
160
                  item->copyfrom_rev = copyfrom_rev;
161
                }
108
            }
162
            }
109
        }
163
        }
110
      apr_hash_set (*changed, apr_pstrdup (pool, path), 
164
      apr_hash_set (*changed, apr_pstrdup (pool, path), 
Lines 112-117 Link Here
112
    }
166
    }
113
167
114
  svn_pool_destroy (subpool);
168
  svn_pool_destroy (subpool);
169
170
  if (! found_readable)
171
    /* Every changed-path was unreadable. */
172
    return svn_error_create (APR_EGENERAL,
173
                             NULL, NULL);
174
175
  if (found_unreadable)
176
    /* At least one changed-path was unreadable. */
177
    return svn_error_create (SVN_ERR_ENTRY_NOT_FOUND,
178
                             NULL, NULL);
179
180
  /* Every changed-path was readable. */
115
  return SVN_NO_ERROR;
181
  return SVN_NO_ERROR;
116
}
182
}
117
183
Lines 132-146 Link Here
132
198
133
199
134
svn_error_t *
200
svn_error_t *
135
svn_repos_get_logs (svn_repos_t *repos,
201
svn_repos__get_logs2 (svn_repos_t *repos,
136
                    const apr_array_header_t *paths,
202
                      const apr_array_header_t *paths,
137
                    svn_revnum_t start,
203
                      svn_revnum_t start,
138
                    svn_revnum_t end,
204
                      svn_revnum_t end,
139
                    svn_boolean_t discover_changed_paths,
205
                      svn_boolean_t discover_changed_paths,
140
                    svn_boolean_t strict_node_history,
206
                      svn_boolean_t strict_node_history,
141
                    svn_log_message_receiver_t receiver,
207
                      svn_repos_authz_func_t authz_read_func,
142
                    void *receiver_baton,
208
                      void *authz_read_baton,
143
                    apr_pool_t *pool)
209
                      svn_log_message_receiver_t receiver,
210
                      void *receiver_baton,
211
                      apr_pool_t *pool)
144
{
212
{
145
  svn_revnum_t this_rev, head = SVN_INVALID_REVNUM;
213
  svn_revnum_t this_rev, head = SVN_INVALID_REVNUM;
146
  apr_pool_t *subpool = svn_pool_create (pool);
214
  apr_pool_t *subpool = svn_pool_create (pool);
Lines 191-200 Link Here
191
          /* Get the changed revisions for this path. */
259
          /* Get the changed revisions for this path. */
192
          const char *this_path = APR_ARRAY_IDX (paths, 0, const char *);
260
          const char *this_path = APR_ARRAY_IDX (paths, 0, const char *);
193
          revs = apr_array_make (pool, 64, sizeof (svn_revnum_t));
261
          revs = apr_array_make (pool, 64, sizeof (svn_revnum_t));
194
          SVN_ERR (svn_repos_history (fs, this_path, history_to_revs_array, 
262
          SVN_ERR (svn_repos__history2 (fs, this_path,
195
                                      revs, start, end, 
263
                                        history_to_revs_array, revs,
196
                                      strict_node_history ? FALSE : TRUE, 
264
                                        authz_read_func, authz_read_baton,
197
                                      pool));
265
                                        start, end, 
266
                                        strict_node_history ? FALSE : TRUE, 
267
                                        pool));
198
        }
268
        }
199
      else
269
      else
200
        {
270
        {
Lines 212-221 Link Here
212
282
213
              /* Get the changed revisions for this path, and add them to
283
              /* Get the changed revisions for this path, and add them to
214
                 the hash (this will eliminate duplicates). */
284
                 the hash (this will eliminate duplicates). */
215
              SVN_ERR (svn_repos_history (fs, this_path, history_to_revs_array,
285
              SVN_ERR (svn_repos__history2 (fs, this_path,
216
                                          changed_revs, start, end, 
286
                                            history_to_revs_array,
217
                                          strict_node_history ? FALSE : TRUE, 
287
                                            changed_revs,
218
                                          pool));
288
                                            authz_read_func, authz_read_baton,
289
                                            start, end, 
290
                                            strict_node_history
291
                                                       ? FALSE : TRUE, 
292
                                            pool));
219
              for (j = 0; j < changed_revs->nelts; j++)
293
              for (j = 0; j < changed_revs->nelts; j++)
220
                {
294
                {
221
                  /* We're re-using the memory allocated for the array
295
                  /* We're re-using the memory allocated for the array
Lines 288-298 Link Here
288
         them (i.e., "svn log -v" means `discover_changed_paths' will
362
         them (i.e., "svn log -v" means `discover_changed_paths' will
289
         be non-zero here).  */
363
         be non-zero here).  */
290
364
291
      if ((this_rev > 0) && discover_changed_paths)
365
366
      if ((this_rev > 0)        
367
          && (authz_read_func || discover_changed_paths))
292
        {
368
        {
293
          svn_fs_root_t *newroot;
369
          svn_fs_root_t *newroot;
370
          svn_error_t *patherr;
371
294
          SVN_ERR (svn_fs_revision_root (&newroot, fs, this_rev, subpool));
372
          SVN_ERR (svn_fs_revision_root (&newroot, fs, this_rev, subpool));
295
          SVN_ERR (detect_changed (&changed_paths, newroot, subpool));
373
          patherr = detect_changed (&changed_paths,
374
                                    newroot, fs,
375
                                    authz_read_func, authz_read_baton,
376
                                    subpool);
377
378
          if (patherr
379
              && patherr->apr_err == APR_EGENERAL)
380
            {
381
              /* All changed-paths are unreadable, so clear all fields. */
382
              svn_error_clear (patherr);              
383
              changed_paths = NULL;
384
              author = NULL;
385
              date = NULL;
386
              message = NULL;
387
            }
388
          else if (patherr
389
                   && patherr->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
390
            {
391
              /* At least one changed-path was unreadable, so omit the
392
                 log message.  (The unreadable paths are already
393
                 missing from the hash.) */
394
              svn_error_clear (patherr);
395
              message = NULL;
396
            }
397
          else if (patherr)
398
            return patherr;
399
400
          /* It may be the case that an authz func was passed in, but
401
             the user still doesn't want to see any changed-paths. */
402
          if (! discover_changed_paths)
403
            changed_paths = NULL;
296
        }
404
        }
297
405
298
      SVN_ERR ((*receiver) (receiver_baton,
406
      SVN_ERR ((*receiver) (receiver_baton,
Lines 310-312 Link Here
310
418
311
  return SVN_NO_ERROR;
419
  return SVN_NO_ERROR;
312
}
420
}
421
422
423
424
svn_error_t *
425
svn_repos_get_logs (svn_repos_t *repos,
426
                    const apr_array_header_t *paths,
427
                    svn_revnum_t start,
428
                    svn_revnum_t end,
429
                    svn_boolean_t discover_changed_paths,
430
                    svn_boolean_t strict_node_history,
431
                    svn_log_message_receiver_t receiver,
432
                    void *receiver_baton,
433
                    apr_pool_t *pool)
434
{
435
  return svn_repos__get_logs2 (repos, paths, start, end,
436
                               discover_changed_paths, strict_node_history,
437
                               NULL, NULL, /* no authz stuff */
438
                               receiver, receiver_baton, pool);
439
}
(-)subversion/libsvn_repos/rev_hunt.c (+43 lines)
Lines 170-175 Link Here
170
}
170
}
171
171
172
172
173
173
svn_error_t *
174
svn_error_t *
174
svn_repos_history (svn_fs_t *fs,
175
svn_repos_history (svn_fs_t *fs,
175
                   const char *path,
176
                   const char *path,
Lines 180-185 Link Here
180
                   svn_boolean_t cross_copies,
181
                   svn_boolean_t cross_copies,
181
                   apr_pool_t *pool)
182
                   apr_pool_t *pool)
182
{
183
{
184
  return svn_repos__history2 (fs, path, history_func, history_baton,
185
                              NULL, NULL,
186
                              start, end, cross_copies, pool);
187
}
188
189
190
191
svn_error_t *
192
svn_repos__history2 (svn_fs_t *fs,
193
                     const char *path,
194
                     svn_repos_history_func_t history_func,
195
                     void *history_baton,
196
                     svn_repos_authz_func_t authz_read_func,
197
                     void *authz_read_baton,
198
                     svn_revnum_t start,
199
                     svn_revnum_t end,
200
                     svn_boolean_t cross_copies,
201
                     apr_pool_t *pool)
202
{
183
  svn_fs_history_t *history;
203
  svn_fs_history_t *history;
184
  apr_pool_t *oldpool = svn_pool_create (pool);
204
  apr_pool_t *oldpool = svn_pool_create (pool);
185
  apr_pool_t *newpool = svn_pool_create (pool);
205
  apr_pool_t *newpool = svn_pool_create (pool);
Lines 209-214 Link Here
209
229
210
  /* Get a revision root for END, and an initial HISTORY baton.  */
230
  /* Get a revision root for END, and an initial HISTORY baton.  */
211
  SVN_ERR (svn_fs_revision_root (&root, fs, end, pool));
231
  SVN_ERR (svn_fs_revision_root (&root, fs, end, pool));
232
233
  if (authz_read_func)
234
    {
235
      svn_boolean_t readable;
236
      SVN_ERR (authz_read_func (&readable, root, path,
237
                                authz_read_baton, pool));
238
      if (! readable)
239
        return svn_error_create (SVN_ERR_ENTRY_NOT_FOUND, NULL, NULL);
240
    }
241
212
  SVN_ERR (svn_fs_node_history (&history, root, path, oldpool));
242
  SVN_ERR (svn_fs_node_history (&history, root, path, oldpool));
213
243
214
  /* Now, we loop over the history items, calling svn_fs_history_prev(). */
244
  /* Now, we loop over the history items, calling svn_fs_history_prev(). */
Lines 234-239 Link Here
234
      if (history_rev < start)
264
      if (history_rev < start)
235
        break;
265
        break;
236
266
267
      /* Is the history item readable?  If not, quit. */
268
      if (authz_read_func)
269
        {
270
          svn_boolean_t readable;
271
          svn_fs_root_t *history_root;
272
          SVN_ERR (svn_fs_revision_root (&history_root, fs,
273
                                         history_rev, newpool));
274
          SVN_ERR (authz_read_func (&readable, history_root, history_path,
275
                                    authz_read_baton, newpool));
276
          if (! readable)
277
            break;
278
        }
279
      
237
      /* Call the user-provided callback function. */
280
      /* Call the user-provided callback function. */
238
      SVN_ERR (history_func (history_baton, history_path, 
281
      SVN_ERR (history_func (history_baton, history_path, 
239
                             history_rev, newpool));
282
                             history_rev, newpool));
(-)subversion/libsvn_repos/repos.h (+33 lines)
Lines 162-169 Link Here
162
                                      const char *name,
162
                                      const char *name,
163
                                      svn_string_t *old_value,
163
                                      svn_string_t *old_value,
164
                                      apr_pool_t *pool);
164
                                      apr_pool_t *pool);
165
  
166
  
167
/* Created for 1.0.7 security fix.  Only used by mod_dav_svn; allows
168
   mod_dav_svn to pass in a new authz_read_func which is used to
169
   validate paths. */
170
svn_error_t *
171
svn_repos__get_logs2 (svn_repos_t *repos,
172
                     const apr_array_header_t *paths,
173
                     svn_revnum_t start,
174
                     svn_revnum_t end,
175
                     svn_boolean_t discover_changed_paths,
176
                     svn_boolean_t strict_node_history,
177
                     svn_repos_authz_func_t authz_read_func,
178
                     void *authz_read_baton,
179
                     svn_log_message_receiver_t receiver,
180
                     void *receiver_baton,
181
                     apr_pool_t *pool);
165
182
183
/* Created for 1.0.7 security fix.  Only used by mod_dav_svn; allows
184
   mod_dav_svn to pass in a new authz_read_func which is used to
185
   validate paths.  */
186
svn_error_t *
187
svn_repos__history2 (svn_fs_t *fs,
188
                    const char *path,
189
                    svn_repos_history_func_t history_func,
190
                    void *history_baton,
191
                    svn_repos_authz_func_t authz_read_func,
192
                    void *authz_read_baton,
193
                    svn_revnum_t start,
194
                    svn_revnum_t end,
195
                    svn_boolean_t cross_copies,
196
                    apr_pool_t *pool);
166
197
198
199
167
#ifdef __cplusplus
200
#ifdef __cplusplus
168
}
201
}
169
#endif /* __cplusplus */
202
#endif /* __cplusplus */

Return to bug 60610