Subversion
svn_dirent_uri.h
Go to the documentation of this file.
1 /**
2  * @copyright
3  * ====================================================================
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements. See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership. The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License. You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied. See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file svn_dirent_uri.h
24  * @brief A library to manipulate URIs, relative paths and directory entries.
25  *
26  * This library makes a clear distinction between several path formats:
27  *
28  * - a dirent is a path on (local) disc or a UNC path (Windows) in
29  * either relative or absolute format.
30  * Examples:
31  * "/foo/bar", "X:/temp", "//server/share", "A:/" (Windows only), ""
32  * But not:
33  * "http://server"
34  *
35  * - a uri, for our purposes, is a percent-encoded, absolute path
36  * (URI) that starts with a schema definition. In practice, these
37  * tend to look like URLs, but never carry query strings.
38  * Examples:
39  * "http://server", "file:///path/to/repos",
40  * "svn+ssh://user@host:123/My%20Stuff/file.doc"
41  * But not:
42  * "file", "dir/file", "A:/dir", "/My%20Stuff/file.doc", ""
43  *
44  * - a relative path (relpath) is an unrooted path that can be joined
45  * to any other relative path, uri or dirent. A relative path is
46  * never rooted/prefixed by a '/'.
47  * Examples:
48  * "file", "dir/file", "dir/subdir/../file", ""
49  * But not:
50  * "/file", "http://server/file"
51  *
52  * This distinction is needed because on Windows we have to handle some
53  * dirents and URIs differently. Since it's not possible to determine from
54  * the path string if it's a dirent or a URI, it's up to the API user to
55  * make this choice. See also issue #2028.
56  *
57  * All incoming and outgoing paths are non-NULL unless otherwise documented.
58  *
59  * All of these functions expect paths passed into them to be in canonical
60  * form, except:
61  *
62  * - @c svn_dirent_canonicalize()
63  * - @c svn_dirent_canonicalize_safe()
64  * - @c svn_dirent_is_canonical()
65  * - @c svn_dirent_internal_style()
66  * - @c svn_relpath_canonicalize()
67  * - @c svn_relpath_canonicalize_safe()
68  * - @c svn_relpath_is_canonical()
69  * - @c svn_uri_canonicalize()
70  * - @c svn_uri_canonicalize_safe()
71  * - @c svn_uri_is_canonical()
72  *
73  * The Subversion codebase also recognizes some other classes of path:
74  *
75  * - A Subversion filesystem path (fspath) -- otherwise known as a
76  * path within a repository -- is a path relative to the root of
77  * the repository filesystem, that starts with a slash ("/"). The
78  * rules for a fspath are the same as for a relpath except for the
79  * leading '/'. A fspath never ends with '/' except when the whole
80  * path is just '/'. The fspath API is private (see
81  * private/svn_fspath.h).
82  *
83  * - A URL path (urlpath) is just the path part of a URL (the part
84  * that follows the schema, username, hostname, and port). These
85  * are also like relpaths, except that they have a leading slash
86  * (like fspaths) and are URI-encoded. The urlpath API is also
87  * private (see private/svn_fspath.h)
88  * Example:
89  * "/svn/repos/trunk/README",
90  * "/svn/repos/!svn/bc/45/file%20with%20spaces.txt"
91  *
92  * So, which path API is appropriate for your use-case?
93  *
94  * - If your path refers to a local file, directory, symlink, etc. of
95  * the sort that you can examine and operate on with other software
96  * on your computer, it's a dirent.
97  *
98  * - If your path is a full URL -- with a schema, hostname (maybe),
99  * and path portion -- it's a uri.
100  *
101  * - If your path is relative, and is somewhat ambiguous unless it's
102  * joined to some other more explicit (possible absolute) base
103  * (such as a dirent or URL), it's a relpath.
104  *
105  * - If your path is the virtual path of a versioned object inside a
106  * Subversion repository, it could be one of two different types of
107  * paths. We'd prefer to use relpaths (relative to the root
108  * directory of the virtual repository filesystem) for that stuff,
109  * but some legacy code uses fspaths. You'll need to figure out if
110  * your code expects repository paths to have a leading '/' or not.
111  * If so, they are fspaths; otherwise they are relpaths.
112  *
113  * - If your path refers only to the path part of URL -- as if
114  * someone hacked off the initial schema and hostname portion --
115  * it's a urlpath. To date, the ra_dav modules are the only ones
116  * within Subversion that make use of urlpaths, and this is because
117  * WebDAV makes heavy use of that form of path specification.
118  *
119  * When translating between local paths (dirents) and uris code should
120  * always go via the relative path format, perhaps by truncating a
121  * parent portion from a path with svn_*_skip_ancestor(), or by
122  * converting portions to basenames and then joining to existing
123  * paths.
124  *
125  * SECURITY WARNING: If a path that is received from an untrusted
126  * source -- such as from the network -- is converted to a dirent it
127  * should be tested with svn_dirent_is_under_root() before you can
128  * assume the path to be a safe local path.
129  *
130  * MEMORY ALLOCATION: A function documented as allocating the result
131  * in a pool may instead return a static string such as "." or "". If
132  * the result is equal to an input, it will duplicate the input.
133  */
134 
135 #ifndef SVN_DIRENT_URI_H
136 #define SVN_DIRENT_URI_H
137 
138 #include <apr.h>
139 #include <apr_pools.h>
140 #include <apr_tables.h>
141 
142 #include "svn_types.h"
143 
144 #ifdef __cplusplus
145 extern "C" {
146 #endif /* __cplusplus */
147 
148 
149 /**
150  * Convert @a dirent from the local style to the canonical internal style.
151  * "Local style" means native path separators and "." for the empty path.
152  *
153  * Allocate the result in @a result_pool.
154  *
155  * @warning This function may call @c abort() if the @a dirent parameter
156  * is not a valid local-style path.
157  * Use svn_dirent_internal_style_safe() for tainted input.
158  *
159  * @since New in 1.6.
160  */
161 const char *
162 svn_dirent_internal_style(const char *dirent,
163  apr_pool_t *result_pool);
164 
165 /**
166  * Convert @a dirent from the local style to the canonical internal style
167  * and return it in @a *internal_style_dirent. "Local style" means native
168  * path separators and "." for the empty path.
169  *
170  * Similar to svn_dirent_internal_style() (which see), but returns an error
171  * if the @a dirent can not be canonicalized or of the result does not pass
172  * the svn_dirent_is_canonical() test.
173  *
174  * If the function fails and @a non_canonical_result is not @c NULL, the
175  * result of the failed canonicalization attempt (which may be @c NULL)
176  * will be returned in @a *non_canonical_result.
177  *
178  * Allocates the results in @a result_pool. Uses @a scratch_pool for
179  * temporary allocations.
180  *
181  * @since New in 1.12.
182  */
183 svn_error_t *
184 svn_dirent_internal_style_safe(const char **internal_style_dirent,
185  const char **non_canonical_result,
186  const char *dirent,
187  apr_pool_t *result_pool,
188  apr_pool_t *scratch_pool);
189 
190 /** Convert @a dirent from the internal style to the local style.
191  * "Local style" means native path separators and "." for the empty path.
192  * If the input is not canonical, the output may not be canonical.
193  *
194  * Allocate the result in @a result_pool.
195  *
196  * @since New in 1.6.
197  */
198 const char *
199 svn_dirent_local_style(const char *dirent,
200  apr_pool_t *result_pool);
201 
202 /** Join a base dirent (@a base) with a component (@a component).
203  *
204  * If either @a base or @a component is the empty string, then the other
205  * argument will be copied and returned. If both are the empty string then
206  * empty string is returned.
207  *
208  * If the @a component is an absolute dirent, then it is copied and returned.
209  * The platform specific rules for joining paths are used to join the components.
210  *
211  * This function is NOT appropriate for native (local) file
212  * dirents. Only for "internal" canonicalized dirents, since it uses '/'
213  * for the separator.
214  *
215  * Allocate the result in @a result_pool.
216  *
217  * @since New in 1.6.
218  */
219 char *
220 svn_dirent_join(const char *base,
221  const char *component,
222  apr_pool_t *result_pool);
223 
224 /** Join multiple components onto a @a base dirent. The components are
225  * terminated by a @c SVN_VA_NULL.
226  *
227  * If any component is the empty string, it will be ignored.
228  *
229  * If any component is an absolute dirent, then it resets the base and
230  * further components will be appended to it.
231  *
232  * See svn_dirent_join() for further notes about joining dirents.
233  *
234  * Allocate the result in @a result_pool.
235  *
236  * @since New in 1.6.
237  */
238 char *
239 svn_dirent_join_many(apr_pool_t *result_pool,
240  const char *base,
242 
243 /** Join a base relpath (@a base) with a component (@a component).
244  * @a component need not be a single component.
245  *
246  * If either @a base or @a component is the empty path, then the other
247  * argument will be copied and returned. If both are the empty path the
248  * empty path is returned.
249  *
250  * Allocate the result in @a result_pool.
251  *
252  * @since New in 1.7.
253  */
254 char *
255 svn_relpath_join(const char *base,
256  const char *component,
257  apr_pool_t *result_pool);
258 
259 /** Gets the name of the specified canonicalized @a dirent as it is known
260  * within its parent directory. If the @a dirent is root, return "". The
261  * returned value will not have slashes in it.
262  *
263  * Example: svn_dirent_basename("/foo/bar") -> "bar"
264  *
265  * If @a result_pool is NULL, return a pointer to the basename in @a dirent,
266  * otherwise allocate the result in @a result_pool.
267  *
268  * @note If an empty string is passed, then an empty string will be returned.
269  *
270  * @since New in 1.7.
271  */
272 const char *
273 svn_dirent_basename(const char *dirent,
274  apr_pool_t *result_pool);
275 
276 /** Get the dirname of the specified canonicalized @a dirent, defined as
277  * the dirent with its basename removed.
278  *
279  * If @a dirent is root ("/", "X:/", "//server/share/") or "", it is returned
280  * unchanged.
281  *
282  * Allocate the result in @a result_pool.
283  *
284  * @since New in 1.6.
285  */
286 char *
287 svn_dirent_dirname(const char *dirent,
288  apr_pool_t *result_pool);
289 
290 /** Divide the canonicalized @a dirent into @a *dirpath and @a *base_name.
291  *
292  * If @a dirpath or @a base_name is NULL, then don't set that one.
293  *
294  * Either @a dirpath or @a base_name may be @a dirent's own address, but they
295  * may not both be the same address, or the results are undefined.
296  *
297  * If @a dirent has two or more components, the separator between @a dirpath
298  * and @a base_name is not included in either of the new names.
299  *
300  * Examples:
301  * - <pre>"/foo/bar/baz" ==> "/foo/bar" and "baz"</pre>
302  * - <pre>"/bar" ==> "/" and "bar"</pre>
303  * - <pre>"/" ==> "/" and ""</pre>
304  * - <pre>"bar" ==> "" and "bar"</pre>
305  * - <pre>"" ==> "" and ""</pre>
306  * Windows: - <pre>"X:/" ==> "X:/" and ""</pre>
307  * - <pre>"X:/foo" ==> "X:/" and "foo"</pre>
308  * - <pre>"X:foo" ==> "X:" and "foo"</pre>
309  * Posix: - <pre>"X:foo" ==> "" and "X:foo"</pre>
310  *
311  * Allocate the results in @a result_pool.
312  *
313  * @since New in 1.7.
314  */
315 void
316 svn_dirent_split(const char **dirpath,
317  const char **base_name,
318  const char *dirent,
319  apr_pool_t *result_pool);
320 
321 /** Divide the canonicalized @a relpath into @a *dirpath and @a *base_name.
322  *
323  * If @a dirpath or @a base_name is NULL, then don't set that one.
324  *
325  * Either @a dirpath or @a base_name may be @a relpaths's own address, but
326  * they may not both be the same address, or the results are undefined.
327  *
328  * If @a relpath has two or more components, the separator between @a dirpath
329  * and @a base_name is not included in either of the new names.
330  *
331  * examples:
332  * - <pre>"foo/bar/baz" ==> "foo/bar" and "baz"</pre>
333  * - <pre>"bar" ==> "" and "bar"</pre>
334  * - <pre>"" ==> "" and ""</pre>
335  *
336  * Allocate the results in @a result_pool.
337  *
338  * @since New in 1.7.
339  */
340 void
341 svn_relpath_split(const char **dirpath,
342  const char **base_name,
343  const char *relpath,
344  apr_pool_t *result_pool);
345 
346 /** Get the basename of the specified canonicalized @a relpath. The
347  * basename is defined as the last component of the relpath. If the @a
348  * relpath has only one component then that is returned. The returned
349  * value will have no slashes in it.
350  *
351  * Example: svn_relpath_basename("/trunk/foo/bar") -> "bar"
352  *
353  * If @a result_pool is NULL, return a pointer to the basename in @a relpath,
354  * otherwise allocate the result in @a result_pool.
355  *
356  * @note If an empty string is passed, then an empty string will be returned.
357  *
358  * @since New in 1.7.
359  */
360 const char *
361 svn_relpath_basename(const char *relpath,
362  apr_pool_t *result_pool);
363 
364 /** Get the dirname of the specified canonicalized @a relpath, defined as
365  * the relpath with its basename removed.
366  *
367  * If @a relpath is empty, "" is returned.
368  *
369  * Allocate the result in @a result_pool.
370  *
371  * @since New in 1.7.
372  */
373 char *
374 svn_relpath_dirname(const char *relpath,
375  apr_pool_t *result_pool);
376 
377 /** Return a maximum of @a max_components components of @a relpath. This is
378  * an efficient way of calling svn_relpath_dirname() multiple times until only
379  * a specific number of components is left.
380  *
381  * Allocate the result in @a result_pool (or statically in case of 0)
382  *
383  * @since New in 1.9.
384  */
385 const char *
386 svn_relpath_prefix(const char *relpath,
387  int max_components,
388  apr_pool_t *result_pool);
389 
390 
391 /** Divide the canonicalized @a uri into a uri @a *dirpath and a
392  * (URI-decoded) relpath @a *base_name.
393  *
394  * If @a dirpath or @a base_name is NULL, then don't set that one.
395  *
396  * Either @a dirpath or @a base_name may be @a uri's own address, but they
397  * may not both be the same address, or the results are undefined.
398  *
399  * If @a uri has two or more components, the separator between @a dirpath
400  * and @a base_name is not included in either of the new names.
401  *
402  * Examples:
403  * - <pre>"http://server/foo/bar" ==> "http://server/foo" and "bar"</pre>
404  *
405  * Allocate the result in @a result_pool.
406  *
407  * @since New in 1.7.
408  */
409 void
410 svn_uri_split(const char **dirpath,
411  const char **base_name,
412  const char *uri,
413  apr_pool_t *result_pool);
414 
415 /** Get the (URI-decoded) basename of the specified canonicalized @a
416  * uri. The basename is defined as the last component of the uri. If
417  * the @a uri is root, return "". The returned value will have no
418  * slashes in it.
419  *
420  * Example: svn_uri_basename("http://server/foo/bar") -> "bar"
421  *
422  * Allocate the result in @a result_pool.
423  *
424  * @since New in 1.7.
425  */
426 const char *
427 svn_uri_basename(const char *uri,
428  apr_pool_t *result_pool);
429 
430 /** Get the dirname of the specified canonicalized @a uri, defined as
431  * the uri with its basename removed.
432  *
433  * If @a uri is root (e.g. "http://server"), it is returned
434  * unchanged.
435  *
436  * Allocate the result in @a result_pool.
437  *
438  * @since New in 1.7.
439  */
440 char *
441 svn_uri_dirname(const char *uri,
442  apr_pool_t *result_pool);
443 
444 /** Return TRUE if @a dirent is considered absolute on the platform at
445  * hand. E.g. '/foo' on Posix platforms or 'X:/foo', '//server/share/foo'
446  * on Windows.
447  *
448  * @since New in 1.6.
449  */
451 svn_dirent_is_absolute(const char *dirent);
452 
453 /** Return TRUE if @a dirent is considered a root directory on the platform
454  * at hand.
455  * E.g.:
456  * On Posix: '/'
457  * On Windows: '/', 'X:/', '//server/share', 'X:'
458  *
459  * Note that on Windows '/' and 'X:' are roots, but paths starting with this
460  * root are not absolute.
461  *
462  * @since New in 1.5.
463  */
465 svn_dirent_is_root(const char *dirent,
466  apr_size_t len);
467 
468 /** Return TRUE if @a uri is a root URL (e.g., "http://server").
469  *
470  * @since New in 1.7
471  */
473 svn_uri_is_root(const char *uri,
474  apr_size_t len);
475 
476 /**
477  * Return a new dirent like @a dirent, but transformed such that some types
478  * of dirent specification redundancies are removed.
479  *
480  * This involves:
481  * - collapsing redundant "/./" elements
482  * - removing multiple adjacent separator characters
483  * - removing trailing separator characters
484  * - converting the server name of a UNC path to lower case (on Windows)
485  * - converting a drive letter to upper case (on Windows)
486  *
487  * and possibly other semantically inoperative transformations.
488  *
489  * Allocate the result in @a result_pool.
490  *
491  * @warning This function may call @c abort() if @a dirent can not be
492  * canonicalized.
493  * Use svn_dirent_canonicalize_safe() for tainted input.
494  *
495  * @since New in 1.6.
496  */
497 const char *
498 svn_dirent_canonicalize(const char *dirent,
499  apr_pool_t *result_pool);
500 
501 /**
502  * Return a new @a *canonical_dirent like @a dirent, but transformed such
503  * that some types of dirent specification redundancies are removed.
504  *
505  * Similar to svn_dirent_canonicalize() (which see), but returns an error
506  * if the @a dirent can not be canonicalized or of the result does not pass
507  * the svn_dirent_is_canonical() test.
508  *
509  * If the function fails and @a non_canonical_result is not @c NULL, the
510  * result of the failed canonicalization attempt (which may be @c NULL)
511  * will be returned in @a *non_canonical_result.
512  *
513  * Allocates the results in @a result_pool. Uses @a scratch_pool for
514  * temporary allocations.
515  *
516  * @since New in 1.12.
517  */
518 svn_error_t *
519 svn_dirent_canonicalize_safe(const char **canonical_dirent,
520  const char **non_canonical_result,
521  const char *dirent,
522  apr_pool_t *result_pool,
523  apr_pool_t *scratch_pool);
524 
525 
526 /**
527  * Return a new relpath like @a relpath, but transformed such that some types
528  * of relpath specification redundancies are removed.
529  *
530  * This involves:
531  * - collapsing redundant "/./" elements
532  * - removing multiple adjacent separator characters
533  * - removing trailing separator characters
534  *
535  * and possibly other semantically inoperative transformations.
536  *
537  * Allocate the result in @a result_pool.
538  *
539  * @warning This function may call @c abort() if @a relpath can not be
540  * canonicalized.
541  * Use svn_relpath_canonicalize_safe() for tainted input.
542  *
543  * @since New in 1.7.
544  */
545 const char *
546 svn_relpath_canonicalize(const char *relpath,
547  apr_pool_t *result_pool);
548 
549 /**
550  * Return a new @a *canonical_relpath like @a relpath, but transformed such
551  * that some types of relpath specification redundancies are removed.
552  *
553  * Similar to svn_relpath_canonicalize() (which see), but returns an error
554  * if the @a relpath can not be canonicalized or of the result does not
555  * pass the svn_relpath_is_canonical() test.
556  *
557  * If the function fails and @a non_canonical_result is not @c NULL, the
558  * result of the failed canonicalization attempt (which may be @c NULL)
559  * will be returned in @a *non_canonical_result.
560  *
561  * Allocates the results in @a result_pool. Uses @a scratch_pool for
562  * temporary allocations.
563  *
564  * @since New in 1.12.
565  */
566 
567 svn_error_t *
568 svn_relpath_canonicalize_safe(const char **canonical_relpath,
569  const char **non_canonical_result,
570  const char *relpath,
571  apr_pool_t *result_pool,
572  apr_pool_t *scratch_pool);
573 
574 
575 /**
576  * Return a new uri like @a uri, but transformed such that some types
577  * of uri specification redundancies are removed.
578  *
579  * This involves:
580  * - collapsing redundant "/./" elements
581  * - removing multiple adjacent separator characters
582  * - removing trailing separator characters
583  * - normalizing the escaping of the path component by unescaping
584  * characters that don't need escaping and escaping characters that do
585  * need escaping but weren't
586  * - removing the port number if it is the default port number (80 for
587  * http, 443 for https, 3690 for svn)
588  *
589  * and possibly other semantically inoperative transformations.
590  *
591  * Allocate the result in @a result_pool.
592  *
593  * @warning This function may call @c abort() if @a uri can not be
594  * canonicalized.
595  * Use svn_uri_canonicalize_safe() for tainted input.
596  *
597  * @since New in 1.7.
598  */
599 const char *
600 svn_uri_canonicalize(const char *uri,
601  apr_pool_t *result_pool);
602 
603 /**
604  * Return a new @a *canonical_uri like @a uri, but transformed such that
605  * some types of uri specification redundancies are removed.
606  *
607  * Similar to svn_uri_canonicalize() (which see), but returns an error if
608  * the @a uri can not be canonicalized or of the result does not pass the
609  * svn_uri_is_canonical() test.
610  *
611  * If the function fails and @a non_canonical_result is not @c NULL, the
612  * result of the failed canonicalization attempt (which may be @c NULL)
613  * will be returned in @a *non_canonical_result.
614  *
615  * Allocates the results in @a result_pool. Uses @a scratch_pool for
616  * temporary allocations.
617  *
618  * @since New in 1.12.
619  */
620 svn_error_t *
621 svn_uri_canonicalize_safe(const char **canonical_uri,
622  const char **non_canonical_result,
623  const char *uri,
624  apr_pool_t *result_pool,
625  apr_pool_t *scratch_pool);
626 
627 
628 /** Return @c TRUE iff @a dirent is canonical.
629  *
630  * Use @a scratch_pool for temporary allocations.
631  *
632  * @note The test for canonicalization is currently defined as
633  * "looks exactly the same as @c svn_dirent_canonicalize() would make
634  * it look".
635  *
636  * @see svn_dirent_canonicalize()
637  * @since New in 1.6.
638  */
640 svn_dirent_is_canonical(const char *dirent,
641  apr_pool_t *scratch_pool);
642 
643 /** Return @c TRUE iff @a relpath is canonical.
644  *
645  * @see svn_relpath_canonicalize()
646  * @since New in 1.7.
647  */
649 svn_relpath_is_canonical(const char *relpath);
650 
651 /** Return @c TRUE iff @a uri is canonical.
652  *
653  * Use @a scratch_pool for temporary allocations.
654  *
655  * @see svn_uri_canonicalize()
656  * @since New in 1.7.
657  */
659 svn_uri_is_canonical(const char *uri,
660  apr_pool_t *scratch_pool);
661 
662 /** Return the longest common dirent shared by two canonicalized dirents,
663  * @a dirent1 and @a dirent2. If there's no common ancestor, return the
664  * empty path.
665  *
666  * Allocate the result in @a result_pool.
667  *
668  * @since New in 1.6.
669  */
670 char *
671 svn_dirent_get_longest_ancestor(const char *dirent1,
672  const char *dirent2,
673  apr_pool_t *result_pool);
674 
675 /** Return the longest common path shared by two relative paths,
676  * @a relpath1 and @a relpath2. If there's no common ancestor, return the
677  * empty path.
678  *
679  * Allocate the result in @a result_pool.
680  *
681  * @since New in 1.7.
682  */
683 char *
684 svn_relpath_get_longest_ancestor(const char *relpath1,
685  const char *relpath2,
686  apr_pool_t *result_pool);
687 
688 /** Return the longest common path shared by two canonicalized uris,
689  * @a uri1 and @a uri2. If there's no common ancestor, return the
690  * empty path. In order for two URLs to have a common ancestor, they
691  * must (a) have the same protocol (since two URLs with the same path
692  * but different protocols may point at completely different
693  * resources), and (b) share a common ancestor in their path
694  * component, i.e. 'protocol://' is not a sufficient ancestor.
695  *
696  * Allocate the result in @a result_pool.
697  *
698  * @since New in 1.7.
699  */
700 char *
701 svn_uri_get_longest_ancestor(const char *uri1,
702  const char *uri2,
703  apr_pool_t *result_pool);
704 
705 /** Convert @a relative canonicalized dirent to an absolute dirent and
706  * return the results in @a *pabsolute.
707  * Raise SVN_ERR_BAD_FILENAME if the absolute dirent cannot be determined.
708  *
709  * Allocate the result in @a result_pool.
710  *
711  * @since New in 1.6.
712  */
713 svn_error_t *
714 svn_dirent_get_absolute(const char **pabsolute,
715  const char *relative,
716  apr_pool_t *result_pool);
717 
718 /** Similar to svn_dirent_skip_ancestor(), except that if @a child_dirent is
719  * the same as @a parent_dirent, it is not considered a child, so the result
720  * is @c NULL; an empty string is never returned.
721  *
722  * If @a result_pool is NULL, return a pointer into @a child_dirent, otherwise
723  * allocate the result in @a result_pool.
724  *
725  * ### TODO: Deprecate, as the semantics are trivially
726  * obtainable from *_skip_ancestor().
727  *
728  * @since New in 1.6.
729  */
730 const char *
731 svn_dirent_is_child(const char *parent_dirent,
732  const char *child_dirent,
733  apr_pool_t *result_pool);
734 
735 /** Return TRUE if @a parent_dirent is an ancestor of @a child_dirent or
736  * the dirents are equal, and FALSE otherwise.
737  *
738  * ### TODO: Deprecate, as the semantics are trivially
739  * obtainable from *_skip_ancestor().
740  *
741  * @since New in 1.6.
742  */
744 svn_dirent_is_ancestor(const char *parent_dirent,
745  const char *child_dirent);
746 
747 /** Return TRUE if @a parent_uri is an ancestor of @a child_uri or
748  * the uris are equal, and FALSE otherwise.
749  */
751 svn_uri__is_ancestor(const char *parent_uri,
752  const char *child_uri);
753 
754 
755 /** Return the relative path part of @a child_dirent that is below
756  * @a parent_dirent, or just "" if @a parent_dirent is equal to
757  * @a child_dirent. If @a child_dirent is not below or equal to
758  * @a parent_dirent, return NULL.
759  *
760  * If one of @a parent_dirent and @a child_dirent is absolute and
761  * the other relative, return NULL.
762  *
763  * @since New in 1.7.
764  */
765 const char *
766 svn_dirent_skip_ancestor(const char *parent_dirent,
767  const char *child_dirent);
768 
769 /** Return the relative path part of @a child_relpath that is below
770  * @a parent_relpath, or just "" if @a parent_relpath is equal to
771  * @a child_relpath. If @a child_relpath is not below @a parent_relpath,
772  * return NULL.
773  *
774  * @since New in 1.7.
775  */
776 const char *
777 svn_relpath_skip_ancestor(const char *parent_relpath,
778  const char *child_relpath);
779 
780 /** Return the URI-decoded relative path of @a child_uri that is below
781  * @a parent_uri, or just "" if @a parent_uri is equal to @a child_uri. If
782  * @a child_uri is not below @a parent_uri, return NULL.
783  *
784  * Allocate the result in @a result_pool.
785  *
786  * @since New in 1.7.
787  */
788 const char *
789 svn_uri_skip_ancestor(const char *parent_uri,
790  const char *child_uri,
791  apr_pool_t *result_pool);
792 
793 /** Find the common prefix of the canonicalized dirents in @a targets
794  * (an array of <tt>const char *</tt>'s), and remove redundant dirents if @a
795  * remove_redundancies is TRUE.
796  *
797  * - Set @a *pcommon to the absolute dirent of the dirent common to
798  * all of the targets. If the targets have no common prefix (e.g.
799  * "C:/file" and "D:/file" on Windows), set @a *pcommon to the empty
800  * string.
801  *
802  * - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
803  * to an array of targets relative to @a *pcommon, and if
804  * @a remove_redundancies is TRUE, omit any dirents that are
805  * descendants of another dirent in @a targets. If *pcommon
806  * is empty, @a *pcondensed_targets will contain absolute dirents;
807  * redundancies can still be removed. If @a pcondensed_targets is NULL,
808  * leave it alone.
809  *
810  * Else if there is exactly one target, then
811  *
812  * - Set @a *pcommon to that target, and
813  *
814  * - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
815  * to an array containing zero elements. Else if
816  * @a pcondensed_targets is NULL, leave it alone.
817  *
818  * If there are no items in @a targets, set @a *pcommon and (if
819  * applicable) @a *pcondensed_targets to @c NULL.
820  *
821  * Allocate the results in @a result_pool. Use @a scratch_pool for
822  * temporary allocations.
823  *
824  * @since New in 1.7.
825  */
826 svn_error_t *
827 svn_dirent_condense_targets(const char **pcommon,
828  apr_array_header_t **pcondensed_targets,
829  const apr_array_header_t *targets,
830  svn_boolean_t remove_redundancies,
831  apr_pool_t *result_pool,
832  apr_pool_t *scratch_pool);
833 
834 /** Find the common prefix of the canonicalized uris in @a targets
835  * (an array of <tt>const char *</tt>'s), and remove redundant uris if @a
836  * remove_redundancies is TRUE.
837  *
838  * - Set @a *pcommon to the common base uri of all of the targets.
839  * If the targets have no common prefix (e.g. "http://srv1/file"
840  * and "http://srv2/file"), set @a *pcommon to the empty
841  * string.
842  *
843  * - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
844  * to an array of URI-decoded targets relative to @a *pcommon, and
845  * if @a remove_redundancies is TRUE, omit any uris that are
846  * descendants of another uri in @a targets. If *pcommon is
847  * empty, @a *pcondensed_targets will contain absolute uris;
848  * redundancies can still be removed. If @a pcondensed_targets is
849  * NULL, leave it alone.
850  *
851  * Else if there is exactly one target, then
852  *
853  * - Set @a *pcommon to that target, and
854  *
855  * - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
856  * to an array containing zero elements. Else if
857  * @a pcondensed_targets is NULL, leave it alone.
858  *
859  * If there are no items in @a targets, set @a *pcommon and (if
860  * applicable) @a *pcondensed_targets to @c NULL.
861  *
862  * Allocate the results in @a result_pool. Use @a scratch_pool for
863  * temporary allocations.
864  *
865  * @since New in 1.7.
866  */
867 svn_error_t *
868 svn_uri_condense_targets(const char **pcommon,
869  apr_array_header_t **pcondensed_targets,
870  const apr_array_header_t *targets,
871  svn_boolean_t remove_redundancies,
872  apr_pool_t *result_pool,
873  apr_pool_t *scratch_pool);
874 
875 /** Join @a path onto @a base_path, checking that @a path does not attempt
876  * to traverse above @a base_path. If @a path or any ".." component within
877  * it resolves to a path above @a base_path, or if @a path is an absolute
878  * path, then set @a *under_root to @c FALSE. Otherwise, set @a *under_root
879  * to @c TRUE and, if @a result_path is not @c NULL, set @a *result_path to
880  * the resulting path.
881  *
882  * @a path need not be canonical. @a base_path must be canonical and
883  * @a *result_path will be canonical.
884  *
885  * Allocate the result in @a result_pool.
886  *
887  * @note Use of this function is strongly encouraged. Do not roll your own.
888  * (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-3846)
889  *
890  * @since New in 1.7.
891  */
892 svn_error_t *
894  const char **result_path,
895  const char *base_path,
896  const char *path,
897  apr_pool_t *result_pool);
898 
899 /** Set @a *dirent to the path corresponding to the file:// URL @a url, using
900  * the platform-specific file:// rules.
901  *
902  * Allocate the result in @a result_pool.
903  *
904  * @since New in 1.7.
905  */
906 svn_error_t *
907 svn_uri_get_dirent_from_file_url(const char **dirent,
908  const char *url,
909  apr_pool_t *result_pool);
910 
911 /** Set @a *url to a file:// URL, corresponding to @a dirent using the
912  * platform specific dirent and file:// rules.
913  *
914  * Allocate the result in @a result_pool.
915  *
916  * @since New in 1.7.
917  */
918 svn_error_t *
919 svn_uri_get_file_url_from_dirent(const char **url,
920  const char *dirent,
921  apr_pool_t *result_pool);
922 
923 #ifdef __cplusplus
924 }
925 #endif /* __cplusplus */
926 
927 #endif /* SVN_DIRENT_URI_H */
svn_dirent_canonicalize_safe
svn_error_t * svn_dirent_canonicalize_safe(const char **canonical_dirent, const char **non_canonical_result, const char *dirent, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Return a new *canonical_dirent like dirent, but transformed such that some types of dirent specificat...
svn_dirent_join_many
char * svn_dirent_join_many(apr_pool_t *result_pool, const char *base,...)
Join multiple components onto a base dirent.
svn_error_t
Subversion error object.
Definition: svn_types.h:180
svn_uri_is_root
svn_boolean_t svn_uri_is_root(const char *uri, apr_size_t len)
Return TRUE if uri is a root URL (e.g., "http://server").
svn_dirent_is_root
svn_boolean_t svn_dirent_is_root(const char *dirent, apr_size_t len)
Return TRUE if dirent is considered a root directory on the platform at hand.
svn_relpath_canonicalize
const char * svn_relpath_canonicalize(const char *relpath, apr_pool_t *result_pool)
Return a new relpath like relpath, but transformed such that some types of relpath specification redu...
svn_dirent_skip_ancestor
const char * svn_dirent_skip_ancestor(const char *parent_dirent, const char *child_dirent)
Return the relative path part of child_dirent that is below parent_dirent, or just "" if parent_diren...
svn_dirent_local_style
const char * svn_dirent_local_style(const char *dirent, apr_pool_t *result_pool)
Convert dirent from the internal style to the local style.
svn_dirent_get_absolute
svn_error_t * svn_dirent_get_absolute(const char **pabsolute, const char *relative, apr_pool_t *result_pool)
Convert relative canonicalized dirent to an absolute dirent and return the results in *pabsolute.
svn_dirent_is_canonical
svn_boolean_t svn_dirent_is_canonical(const char *dirent, apr_pool_t *scratch_pool)
Return TRUE iff dirent is canonical.
svn_dirent_basename
const char * svn_dirent_basename(const char *dirent, apr_pool_t *result_pool)
Gets the name of the specified canonicalized dirent as it is known within its parent directory.
svn_uri_split
void svn_uri_split(const char **dirpath, const char **base_name, const char *uri, apr_pool_t *result_pool)
Divide the canonicalized uri into a uri *dirpath and a (URI-decoded) relpath *base_name.
svn_relpath_split
void svn_relpath_split(const char **dirpath, const char **base_name, const char *relpath, apr_pool_t *result_pool)
Divide the canonicalized relpath into *dirpath and *base_name.
svn_dirent_condense_targets
svn_error_t * svn_dirent_condense_targets(const char **pcommon, apr_array_header_t **pcondensed_targets, const apr_array_header_t *targets, svn_boolean_t remove_redundancies, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Find the common prefix of the canonicalized dirents in targets (an array of const char *'s),...
svn_uri_skip_ancestor
const char * svn_uri_skip_ancestor(const char *parent_uri, const char *child_uri, apr_pool_t *result_pool)
Return the URI-decoded relative path of child_uri that is below parent_uri, or just "" if parent_uri ...
svn_uri_canonicalize
const char * svn_uri_canonicalize(const char *uri, apr_pool_t *result_pool)
Return a new uri like uri, but transformed such that some types of uri specification redundancies are...
SVN_NEEDS_SENTINEL_NULL
#define SVN_NEEDS_SENTINEL_NULL
Macro used to mark functions that require a final null sentinel argument.
Definition: svn_types.h:109
svn_relpath_basename
const char * svn_relpath_basename(const char *relpath, apr_pool_t *result_pool)
Get the basename of the specified canonicalized relpath.
svn_types.h
Subversion's data types.
svn_uri_condense_targets
svn_error_t * svn_uri_condense_targets(const char **pcommon, apr_array_header_t **pcondensed_targets, const apr_array_header_t *targets, svn_boolean_t remove_redundancies, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Find the common prefix of the canonicalized uris in targets (an array of const char *'s),...
svn_dirent_canonicalize
const char * svn_dirent_canonicalize(const char *dirent, apr_pool_t *result_pool)
Return a new dirent like dirent, but transformed such that some types of dirent specification redunda...
svn_dirent_get_longest_ancestor
char * svn_dirent_get_longest_ancestor(const char *dirent1, const char *dirent2, apr_pool_t *result_pool)
Return the longest common dirent shared by two canonicalized dirents, dirent1 and dirent2.
svn_uri__is_ancestor
svn_boolean_t svn_uri__is_ancestor(const char *parent_uri, const char *child_uri)
Return TRUE if parent_uri is an ancestor of child_uri or the uris are equal, and FALSE otherwise.
svn_uri_get_longest_ancestor
char * svn_uri_get_longest_ancestor(const char *uri1, const char *uri2, apr_pool_t *result_pool)
Return the longest common path shared by two canonicalized uris, uri1 and uri2.
svn_dirent_join
char * svn_dirent_join(const char *base, const char *component, apr_pool_t *result_pool)
Join a base dirent (base) with a component (component).
svn_relpath_is_canonical
svn_boolean_t svn_relpath_is_canonical(const char *relpath)
Return TRUE iff relpath is canonical.
svn_relpath_canonicalize_safe
svn_error_t * svn_relpath_canonicalize_safe(const char **canonical_relpath, const char **non_canonical_result, const char *relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Return a new *canonical_relpath like relpath, but transformed such that some types of relpath specifi...
svn_relpath_join
char * svn_relpath_join(const char *base, const char *component, apr_pool_t *result_pool)
Join a base relpath (base) with a component (component).
svn_uri_get_file_url_from_dirent
svn_error_t * svn_uri_get_file_url_from_dirent(const char **url, const char *dirent, apr_pool_t *result_pool)
Set *url to a file:// URL, corresponding to dirent using the platform specific dirent and file:// rul...
svn_dirent_internal_style_safe
svn_error_t * svn_dirent_internal_style_safe(const char **internal_style_dirent, const char **non_canonical_result, const char *dirent, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Convert dirent from the local style to the canonical internal style and return it in *internal_style_...
svn_uri_get_dirent_from_file_url
svn_error_t * svn_uri_get_dirent_from_file_url(const char **dirent, const char *url, apr_pool_t *result_pool)
Set *dirent to the path corresponding to the file:// URL url, using the platform-specific file:// rul...
svn_uri_canonicalize_safe
svn_error_t * svn_uri_canonicalize_safe(const char **canonical_uri, const char **non_canonical_result, const char *uri, apr_pool_t *result_pool, apr_pool_t *scratch_pool)
Return a new *canonical_uri like uri, but transformed such that some types of uri specification redun...
svn_relpath_dirname
char * svn_relpath_dirname(const char *relpath, apr_pool_t *result_pool)
Get the dirname of the specified canonicalized relpath, defined as the relpath with its basename remo...
svn_dirent_is_under_root
svn_error_t * svn_dirent_is_under_root(svn_boolean_t *under_root, const char **result_path, const char *base_path, const char *path, apr_pool_t *result_pool)
Join path onto base_path, checking that path does not attempt to traverse above base_path.
svn_relpath_prefix
const char * svn_relpath_prefix(const char *relpath, int max_components, apr_pool_t *result_pool)
Return a maximum of max_components components of relpath.
svn_boolean_t
int svn_boolean_t
YABT: Yet Another Boolean Type.
Definition: svn_types.h:141
svn_relpath_get_longest_ancestor
char * svn_relpath_get_longest_ancestor(const char *relpath1, const char *relpath2, apr_pool_t *result_pool)
Return the longest common path shared by two relative paths, relpath1 and relpath2.
svn_dirent_is_ancestor
svn_boolean_t svn_dirent_is_ancestor(const char *parent_dirent, const char *child_dirent)
Return TRUE if parent_dirent is an ancestor of child_dirent or the dirents are equal,...
svn_dirent_internal_style
const char * svn_dirent_internal_style(const char *dirent, apr_pool_t *result_pool)
Convert dirent from the local style to the canonical internal style.
svn_relpath_skip_ancestor
const char * svn_relpath_skip_ancestor(const char *parent_relpath, const char *child_relpath)
Return the relative path part of child_relpath that is below parent_relpath, or just "" if parent_rel...
svn_dirent_is_absolute
svn_boolean_t svn_dirent_is_absolute(const char *dirent)
Return TRUE if dirent is considered absolute on the platform at hand.
svn_uri_basename
const char * svn_uri_basename(const char *uri, apr_pool_t *result_pool)
Get the (URI-decoded) basename of the specified canonicalized uri.
svn_dirent_dirname
char * svn_dirent_dirname(const char *dirent, apr_pool_t *result_pool)
Get the dirname of the specified canonicalized dirent, defined as the dirent with its basename remove...
svn_dirent_is_child
const char * svn_dirent_is_child(const char *parent_dirent, const char *child_dirent, apr_pool_t *result_pool)
Similar to svn_dirent_skip_ancestor(), except that if child_dirent is the same as parent_dirent,...
svn_uri_is_canonical
svn_boolean_t svn_uri_is_canonical(const char *uri, apr_pool_t *scratch_pool)
Return TRUE iff uri is canonical.
svn_dirent_split
void svn_dirent_split(const char **dirpath, const char **base_name, const char *dirent, apr_pool_t *result_pool)
Divide the canonicalized dirent into *dirpath and *base_name.
svn_uri_dirname
char * svn_uri_dirname(const char *uri, apr_pool_t *result_pool)
Get the dirname of the specified canonicalized uri, defined as the uri with its basename removed.