blob: cf8152bcfb7cded7280188d78018d4fc50d7c583 [file] [log] [blame]
/**
* @copyright
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
* @endcopyright
*
* @file svn_dirent_uri.h
* @brief A library to manipulate URIs, relative paths and directory entries.
*
* This library makes a clear distinction between several path formats:
*
* - a dirent is a path on (local) disc or a UNC path (Windows) in
* either relative or absolute format.
* Examples:
* "/foo/bar", "X:/temp", "//server/share", "A:/" (Windows only), ""
* But not:
* "http://server"
*
* - a uri, for our purposes, is a percent-encoded, absolute path
* (URI) that starts with a schema definition. In practice, these
* tend to look like URLs, but never carry query strings.
* Examples:
* "http://server", "file:///path/to/repos",
* "svn+ssh://user@host:123/My%20Stuff/file.doc"
* But not:
* "file", "dir/file", "A:/dir", "/My%20Stuff/file.doc", ""
*
* - a relative path (relpath) is an unrooted path that can be joined
* to any other relative path, uri or dirent. A relative path is
* never rooted/prefixed by a '/'.
* Examples:
* "file", "dir/file", "dir/subdir/../file", ""
* But not:
* "/file", "http://server/file"
*
* This distinction is needed because on Windows we have to handle some
* dirents and URIs differently. Since it's not possible to determine from
* the path string if it's a dirent or a URI, it's up to the API user to
* make this choice. See also issue #2028.
*
* All incoming and outgoing paths are non-NULL unless otherwise documented.
*
* All of these functions expect paths passed into them to be in canonical
* form, except:
*
* - @c svn_dirent_canonicalize()
* - @c svn_dirent_canonicalize_safe()
* - @c svn_dirent_is_canonical()
* - @c svn_dirent_internal_style()
* - @c svn_relpath_canonicalize()
* - @c svn_relpath_canonicalize_safe()
* - @c svn_relpath_is_canonical()
* - @c svn_uri_canonicalize()
* - @c svn_uri_canonicalize_safe()
* - @c svn_uri_is_canonical()
*
* The Subversion codebase also recognizes some other classes of path:
*
* - A Subversion filesystem path (fspath) -- otherwise known as a
* path within a repository -- is a path relative to the root of
* the repository filesystem, that starts with a slash ("/"). The
* rules for a fspath are the same as for a relpath except for the
* leading '/'. A fspath never ends with '/' except when the whole
* path is just '/'. The fspath API is private (see
* private/svn_fspath.h).
*
* - A URL path (urlpath) is just the path part of a URL (the part
* that follows the schema, username, hostname, and port). These
* are also like relpaths, except that they have a leading slash
* (like fspaths) and are URI-encoded. The urlpath API is also
* private (see private/svn_fspath.h)
* Example:
* "/svn/repos/trunk/README",
* "/svn/repos/!svn/bc/45/file%20with%20spaces.txt"
*
* So, which path API is appropriate for your use-case?
*
* - If your path refers to a local file, directory, symlink, etc. of
* the sort that you can examine and operate on with other software
* on your computer, it's a dirent.
*
* - If your path is a full URL -- with a schema, hostname (maybe),
* and path portion -- it's a uri.
*
* - If your path is relative, and is somewhat ambiguous unless it's
* joined to some other more explicit (possible absolute) base
* (such as a dirent or URL), it's a relpath.
*
* - If your path is the virtual path of a versioned object inside a
* Subversion repository, it could be one of two different types of
* paths. We'd prefer to use relpaths (relative to the root
* directory of the virtual repository filesystem) for that stuff,
* but some legacy code uses fspaths. You'll need to figure out if
* your code expects repository paths to have a leading '/' or not.
* If so, they are fspaths; otherwise they are relpaths.
*
* - If your path refers only to the path part of URL -- as if
* someone hacked off the initial schema and hostname portion --
* it's a urlpath. To date, the ra_dav modules are the only ones
* within Subversion that make use of urlpaths, and this is because
* WebDAV makes heavy use of that form of path specification.
*
* When translating between local paths (dirents) and uris code should
* always go via the relative path format, perhaps by truncating a
* parent portion from a path with svn_*_skip_ancestor(), or by
* converting portions to basenames and then joining to existing
* paths.
*
* SECURITY WARNING: If a path that is received from an untrusted
* source -- such as from the network -- is converted to a dirent it
* should be tested with svn_dirent_is_under_root() before you can
* assume the path to be a safe local path.
*
* MEMORY ALLOCATION: A function documented as allocating the result
* in a pool may instead return a static string such as "." or "". If
* the result is equal to an input, it will duplicate the input.
*/
#ifndef SVN_DIRENT_URI_H
#define SVN_DIRENT_URI_H
#include <apr.h>
#include <apr_pools.h>
#include <apr_tables.h>
#include "svn_types.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Convert @a dirent from the local style to the canonical internal style.
* "Local style" means native path separators and "." for the empty path.
*
* Allocate the result in @a result_pool.
*
* @warning This function may call @c abort() if the @a dirent parameter
* is not a valid local-style path.
* Use svn_dirent_internal_style_safe() for tainted input.
*
* @since New in 1.6.
*/
const char *
svn_dirent_internal_style(const char *dirent,
apr_pool_t *result_pool);
/**
* Convert @a dirent from the local style to the canonical internal style
* and return it in @a *internal_style_dirent. "Local style" means native
* path separators and "." for the empty path.
*
* Similar to svn_dirent_internal_style() (which see), but returns an error
* if the @a dirent can not be canonicalized or of the result does not pass
* the svn_dirent_is_canonical() test.
*
* If the function fails and @a non_canonical_result is not @c NULL, the
* result of the failed canonicalization attempt (which may be @c NULL)
* will be returned in @a *non_canonical_result.
*
* Allocates the results in @a result_pool. Uses @a scratch_pool for
* temporary allocations.
*
* @since New in 1.12.
*/
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 @a dirent from the internal style to the local style.
* "Local style" means native path separators and "." for the empty path.
* If the input is not canonical, the output may not be canonical.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
const char *
svn_dirent_local_style(const char *dirent,
apr_pool_t *result_pool);
/** Join a base dirent (@a base) with a component (@a component).
*
* If either @a base or @a component is the empty string, then the other
* argument will be copied and returned. If both are the empty string then
* empty string is returned.
*
* If the @a component is an absolute dirent, then it is copied and returned.
* The platform specific rules for joining paths are used to join the components.
*
* This function is NOT appropriate for native (local) file
* dirents. Only for "internal" canonicalized dirents, since it uses '/'
* for the separator.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
char *
svn_dirent_join(const char *base,
const char *component,
apr_pool_t *result_pool);
/** Join multiple components onto a @a base dirent. The components are
* terminated by a @c SVN_VA_NULL.
*
* If any component is the empty string, it will be ignored.
*
* If any component is an absolute dirent, then it resets the base and
* further components will be appended to it.
*
* See svn_dirent_join() for further notes about joining dirents.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
char *
svn_dirent_join_many(apr_pool_t *result_pool,
const char *base,
...) SVN_NEEDS_SENTINEL_NULL;
/** Join a base relpath (@a base) with a component (@a component).
* @a component need not be a single component.
*
* If either @a base or @a component is the empty path, then the other
* argument will be copied and returned. If both are the empty path the
* empty path is returned.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_relpath_join(const char *base,
const char *component,
apr_pool_t *result_pool);
/** Gets the name of the specified canonicalized @a dirent as it is known
* within its parent directory. If the @a dirent is root, return "". The
* returned value will not have slashes in it.
*
* Example: svn_dirent_basename("/foo/bar") -> "bar"
*
* If @a result_pool is NULL, return a pointer to the basename in @a dirent,
* otherwise allocate the result in @a result_pool.
*
* @note If an empty string is passed, then an empty string will be returned.
*
* @since New in 1.7.
*/
const char *
svn_dirent_basename(const char *dirent,
apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a dirent, defined as
* the dirent with its basename removed.
*
* If @a dirent is root ("/", "X:/", "//server/share/") or "", it is returned
* unchanged.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
char *
svn_dirent_dirname(const char *dirent,
apr_pool_t *result_pool);
/** Divide the canonicalized @a dirent into @a *dirpath and @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
* Either @a dirpath or @a base_name may be @a dirent's own address, but they
* may not both be the same address, or the results are undefined.
*
* If @a dirent has two or more components, the separator between @a dirpath
* and @a base_name is not included in either of the new names.
*
* Examples:
* - <pre>"/foo/bar/baz" ==> "/foo/bar" and "baz"</pre>
* - <pre>"/bar" ==> "/" and "bar"</pre>
* - <pre>"/" ==> "/" and ""</pre>
* - <pre>"bar" ==> "" and "bar"</pre>
* - <pre>"" ==> "" and ""</pre>
* Windows: - <pre>"X:/" ==> "X:/" and ""</pre>
* - <pre>"X:/foo" ==> "X:/" and "foo"</pre>
* - <pre>"X:foo" ==> "X:" and "foo"</pre>
* Posix: - <pre>"X:foo" ==> "" and "X:foo"</pre>
*
* Allocate the results in @a result_pool.
*
* @since New in 1.7.
*/
void
svn_dirent_split(const char **dirpath,
const char **base_name,
const char *dirent,
apr_pool_t *result_pool);
/** Divide the canonicalized @a relpath into @a *dirpath and @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
* Either @a dirpath or @a base_name may be @a relpaths's own address, but
* they may not both be the same address, or the results are undefined.
*
* If @a relpath has two or more components, the separator between @a dirpath
* and @a base_name is not included in either of the new names.
*
* examples:
* - <pre>"foo/bar/baz" ==> "foo/bar" and "baz"</pre>
* - <pre>"bar" ==> "" and "bar"</pre>
* - <pre>"" ==> "" and ""</pre>
*
* Allocate the results in @a result_pool.
*
* @since New in 1.7.
*/
void
svn_relpath_split(const char **dirpath,
const char **base_name,
const char *relpath,
apr_pool_t *result_pool);
/** Get the basename of the specified canonicalized @a relpath. The
* basename is defined as the last component of the relpath. If the @a
* relpath has only one component then that is returned. The returned
* value will have no slashes in it.
*
* Example: svn_relpath_basename("/trunk/foo/bar") -> "bar"
*
* If @a result_pool is NULL, return a pointer to the basename in @a relpath,
* otherwise allocate the result in @a result_pool.
*
* @note If an empty string is passed, then an empty string will be returned.
*
* @since New in 1.7.
*/
const char *
svn_relpath_basename(const char *relpath,
apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a relpath, defined as
* the relpath with its basename removed.
*
* If @a relpath is empty, "" is returned.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_relpath_dirname(const char *relpath,
apr_pool_t *result_pool);
/** Return a maximum of @a max_components components of @a relpath. This is
* an efficient way of calling svn_relpath_dirname() multiple times until only
* a specific number of components is left.
*
* Allocate the result in @a result_pool (or statically in case of 0)
*
* @since New in 1.9.
*/
const char *
svn_relpath_prefix(const char *relpath,
int max_components,
apr_pool_t *result_pool);
/** Divide the canonicalized @a uri into a uri @a *dirpath and a
* (URI-decoded) relpath @a *base_name.
*
* If @a dirpath or @a base_name is NULL, then don't set that one.
*
* Either @a dirpath or @a base_name may be @a uri's own address, but they
* may not both be the same address, or the results are undefined.
*
* If @a uri has two or more components, the separator between @a dirpath
* and @a base_name is not included in either of the new names.
*
* Examples:
* - <pre>"http://server/foo/bar" ==> "http://server/foo" and "bar"</pre>
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
void
svn_uri_split(const char **dirpath,
const char **base_name,
const char *uri,
apr_pool_t *result_pool);
/** Get the (URI-decoded) basename of the specified canonicalized @a
* uri. The basename is defined as the last component of the uri. If
* the @a uri is root, return "". The returned value will have no
* slashes in it.
*
* Example: svn_uri_basename("http://server/foo/bar") -> "bar"
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
const char *
svn_uri_basename(const char *uri,
apr_pool_t *result_pool);
/** Get the dirname of the specified canonicalized @a uri, defined as
* the uri with its basename removed.
*
* If @a uri is root (e.g. "http://server"), it is returned
* unchanged.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_uri_dirname(const char *uri,
apr_pool_t *result_pool);
/** Return TRUE if @a dirent is considered absolute on the platform at
* hand. E.g. '/foo' on Posix platforms or 'X:/foo', '//server/share/foo'
* on Windows.
*
* @since New in 1.6.
*/
svn_boolean_t
svn_dirent_is_absolute(const char *dirent);
/** Return TRUE if @a dirent is considered a root directory on the platform
* at hand.
* E.g.:
* On Posix: '/'
* On Windows: '/', 'X:/', '//server/share', 'X:'
*
* Note that on Windows '/' and 'X:' are roots, but paths starting with this
* root are not absolute.
*
* @since New in 1.5.
*/
svn_boolean_t
svn_dirent_is_root(const char *dirent,
apr_size_t len);
/** Return TRUE if @a uri is a root URL (e.g., "http://server").
*
* @since New in 1.7
*/
svn_boolean_t
svn_uri_is_root(const char *uri,
apr_size_t len);
/**
* Return a new dirent like @a dirent, but transformed such that some types
* of dirent specification redundancies are removed.
*
* This involves:
* - collapsing redundant "/./" elements
* - removing multiple adjacent separator characters
* - removing trailing separator characters
* - converting the server name of a UNC path to lower case (on Windows)
* - converting a drive letter to upper case (on Windows)
*
* and possibly other semantically inoperative transformations.
*
* Allocate the result in @a result_pool.
*
* @warning This function may call @c abort() if @a dirent can not be
* canonicalized.
* Use svn_dirent_canonicalize_safe() for tainted input.
*
* @since New in 1.6.
*/
const char *
svn_dirent_canonicalize(const char *dirent,
apr_pool_t *result_pool);
/**
* Return a new @a *canonical_dirent like @a dirent, but transformed such
* that some types of dirent specification redundancies are removed.
*
* Similar to svn_dirent_canonicalize() (which see), but returns an error
* if the @a dirent can not be canonicalized or of the result does not pass
* the svn_dirent_is_canonical() test.
*
* If the function fails and @a non_canonical_result is not @c NULL, the
* result of the failed canonicalization attempt (which may be @c NULL)
* will be returned in @a *non_canonical_result.
*
* Allocates the results in @a result_pool. Uses @a scratch_pool for
* temporary allocations.
*
* @since New in 1.12.
*/
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 relpath like @a relpath, but transformed such that some types
* of relpath specification redundancies are removed.
*
* This involves:
* - collapsing redundant "/./" elements
* - removing multiple adjacent separator characters
* - removing trailing separator characters
*
* and possibly other semantically inoperative transformations.
*
* Allocate the result in @a result_pool.
*
* @warning This function may call @c abort() if @a relpath can not be
* canonicalized.
* Use svn_relpath_canonicalize_safe() for tainted input.
*
* @since New in 1.7.
*/
const char *
svn_relpath_canonicalize(const char *relpath,
apr_pool_t *result_pool);
/**
* Return a new @a *canonical_relpath like @a relpath, but transformed such
* that some types of relpath specification redundancies are removed.
*
* Similar to svn_relpath_canonicalize() (which see), but returns an error
* if the @a relpath can not be canonicalized or of the result does not
* pass the svn_relpath_is_canonical() test.
*
* If the function fails and @a non_canonical_result is not @c NULL, the
* result of the failed canonicalization attempt (which may be @c NULL)
* will be returned in @a *non_canonical_result.
*
* Allocates the results in @a result_pool. Uses @a scratch_pool for
* temporary allocations.
*
* @since New in 1.12.
*/
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 uri like @a uri, but transformed such that some types
* of uri specification redundancies are removed.
*
* This involves:
* - collapsing redundant "/./" elements
* - removing multiple adjacent separator characters
* - removing trailing separator characters
* - normalizing the escaping of the path component by unescaping
* characters that don't need escaping and escaping characters that do
* need escaping but weren't
* - removing the port number if it is the default port number (80 for
* http, 443 for https, 3690 for svn)
*
* and possibly other semantically inoperative transformations.
*
* Allocate the result in @a result_pool.
*
* @warning This function may call @c abort() if @a uri can not be
* canonicalized.
* Use svn_uri_canonicalize_safe() for tainted input.
*
* @since New in 1.7.
*/
const char *
svn_uri_canonicalize(const char *uri,
apr_pool_t *result_pool);
/**
* Return a new @a *canonical_uri like @a uri, but transformed such that
* some types of uri specification redundancies are removed.
*
* Similar to svn_uri_canonicalize() (which see), but returns an error if
* the @a uri can not be canonicalized or of the result does not pass the
* svn_uri_is_canonical() test.
*
* If the function fails and @a non_canonical_result is not @c NULL, the
* result of the failed canonicalization attempt (which may be @c NULL)
* will be returned in @a *non_canonical_result.
*
* Allocates the results in @a result_pool. Uses @a scratch_pool for
* temporary allocations.
*
* @since New in 1.12.
*/
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 @c TRUE iff @a dirent is canonical.
*
* Use @a scratch_pool for temporary allocations.
*
* @note The test for canonicalization is currently defined as
* "looks exactly the same as @c svn_dirent_canonicalize() would make
* it look".
*
* @see svn_dirent_canonicalize()
* @since New in 1.6.
*/
svn_boolean_t
svn_dirent_is_canonical(const char *dirent,
apr_pool_t *scratch_pool);
/** Return @c TRUE iff @a relpath is canonical.
*
* @see svn_relpath_canonicalize()
* @since New in 1.7.
*/
svn_boolean_t
svn_relpath_is_canonical(const char *relpath);
/** Return @c TRUE iff @a uri is canonical.
*
* Use @a scratch_pool for temporary allocations.
*
* @see svn_uri_canonicalize()
* @since New in 1.7.
*/
svn_boolean_t
svn_uri_is_canonical(const char *uri,
apr_pool_t *scratch_pool);
/** Return the longest common dirent shared by two canonicalized dirents,
* @a dirent1 and @a dirent2. If there's no common ancestor, return the
* empty path.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
char *
svn_dirent_get_longest_ancestor(const char *dirent1,
const char *dirent2,
apr_pool_t *result_pool);
/** Return the longest common path shared by two relative paths,
* @a relpath1 and @a relpath2. If there's no common ancestor, return the
* empty path.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
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 canonicalized uris,
* @a uri1 and @a uri2. If there's no common ancestor, return the
* empty path. In order for two URLs to have a common ancestor, they
* must (a) have the same protocol (since two URLs with the same path
* but different protocols may point at completely different
* resources), and (b) share a common ancestor in their path
* component, i.e. 'protocol://' is not a sufficient ancestor.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
char *
svn_uri_get_longest_ancestor(const char *uri1,
const char *uri2,
apr_pool_t *result_pool);
/** Convert @a relative canonicalized dirent to an absolute dirent and
* return the results in @a *pabsolute.
* Raise SVN_ERR_BAD_FILENAME if the absolute dirent cannot be determined.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.6.
*/
svn_error_t *
svn_dirent_get_absolute(const char **pabsolute,
const char *relative,
apr_pool_t *result_pool);
/** Similar to svn_dirent_skip_ancestor(), except that if @a child_dirent is
* the same as @a parent_dirent, it is not considered a child, so the result
* is @c NULL; an empty string is never returned.
*
* If @a result_pool is NULL, return a pointer into @a child_dirent, otherwise
* allocate the result in @a result_pool.
*
* ### TODO: Deprecate, as the semantics are trivially
* obtainable from *_skip_ancestor().
*
* @since New in 1.6.
*/
const char *
svn_dirent_is_child(const char *parent_dirent,
const char *child_dirent,
apr_pool_t *result_pool);
/** Return TRUE if @a parent_dirent is an ancestor of @a child_dirent or
* the dirents are equal, and FALSE otherwise.
*
* ### TODO: Deprecate, as the semantics are trivially
* obtainable from *_skip_ancestor().
*
* @since New in 1.6.
*/
svn_boolean_t
svn_dirent_is_ancestor(const char *parent_dirent,
const char *child_dirent);
/** Return TRUE if @a parent_uri is an ancestor of @a child_uri or
* the uris are equal, and FALSE otherwise.
*/
svn_boolean_t
svn_uri__is_ancestor(const char *parent_uri,
const char *child_uri);
/** Return the relative path part of @a child_dirent that is below
* @a parent_dirent, or just "" if @a parent_dirent is equal to
* @a child_dirent. If @a child_dirent is not below or equal to
* @a parent_dirent, return NULL.
*
* If one of @a parent_dirent and @a child_dirent is absolute and
* the other relative, return NULL.
*
* @since New in 1.7.
*/
const char *
svn_dirent_skip_ancestor(const char *parent_dirent,
const char *child_dirent);
/** Return the relative path part of @a child_relpath that is below
* @a parent_relpath, or just "" if @a parent_relpath is equal to
* @a child_relpath. If @a child_relpath is not below @a parent_relpath,
* return NULL.
*
* @since New in 1.7.
*/
const char *
svn_relpath_skip_ancestor(const char *parent_relpath,
const char *child_relpath);
/** Return the URI-decoded relative path of @a child_uri that is below
* @a parent_uri, or just "" if @a parent_uri is equal to @a child_uri. If
* @a child_uri is not below @a parent_uri, return NULL.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
const char *
svn_uri_skip_ancestor(const char *parent_uri,
const char *child_uri,
apr_pool_t *result_pool);
/** Find the common prefix of the canonicalized dirents in @a targets
* (an array of <tt>const char *</tt>'s), and remove redundant dirents if @a
* remove_redundancies is TRUE.
*
* - Set @a *pcommon to the absolute dirent of the dirent common to
* all of the targets. If the targets have no common prefix (e.g.
* "C:/file" and "D:/file" on Windows), set @a *pcommon to the empty
* string.
*
* - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
* to an array of targets relative to @a *pcommon, and if
* @a remove_redundancies is TRUE, omit any dirents that are
* descendants of another dirent in @a targets. If *pcommon
* is empty, @a *pcondensed_targets will contain absolute dirents;
* redundancies can still be removed. If @a pcondensed_targets is NULL,
* leave it alone.
*
* Else if there is exactly one target, then
*
* - Set @a *pcommon to that target, and
*
* - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
* to an array containing zero elements. Else if
* @a pcondensed_targets is NULL, leave it alone.
*
* If there are no items in @a targets, set @a *pcommon and (if
* applicable) @a *pcondensed_targets to @c NULL.
*
* Allocate the results in @a result_pool. Use @a scratch_pool for
* temporary allocations.
*
* @since New in 1.7.
*/
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 uris in @a targets
* (an array of <tt>const char *</tt>'s), and remove redundant uris if @a
* remove_redundancies is TRUE.
*
* - Set @a *pcommon to the common base uri of all of the targets.
* If the targets have no common prefix (e.g. "http://srv1/file"
* and "http://srv2/file"), set @a *pcommon to the empty
* string.
*
* - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
* to an array of URI-decoded targets relative to @a *pcommon, and
* if @a remove_redundancies is TRUE, omit any uris that are
* descendants of another uri in @a targets. If *pcommon is
* empty, @a *pcondensed_targets will contain absolute uris;
* redundancies can still be removed. If @a pcondensed_targets is
* NULL, leave it alone.
*
* Else if there is exactly one target, then
*
* - Set @a *pcommon to that target, and
*
* - If @a pcondensed_targets is non-NULL, set @a *pcondensed_targets
* to an array containing zero elements. Else if
* @a pcondensed_targets is NULL, leave it alone.
*
* If there are no items in @a targets, set @a *pcommon and (if
* applicable) @a *pcondensed_targets to @c NULL.
*
* Allocate the results in @a result_pool. Use @a scratch_pool for
* temporary allocations.
*
* @since New in 1.7.
*/
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);
/** Join @a path onto @a base_path, checking that @a path does not attempt
* to traverse above @a base_path. If @a path or any ".." component within
* it resolves to a path above @a base_path, or if @a path is an absolute
* path, then set @a *under_root to @c FALSE. Otherwise, set @a *under_root
* to @c TRUE and, if @a result_path is not @c NULL, set @a *result_path to
* the resulting path.
*
* @a path need not be canonical. @a base_path must be canonical and
* @a *result_path will be canonical.
*
* Allocate the result in @a result_pool.
*
* @note Use of this function is strongly encouraged. Do not roll your own.
* (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-3846)
*
* @since New in 1.7.
*/
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);
/** Set @a *dirent to the path corresponding to the file:// URL @a url, using
* the platform-specific file:// rules.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
svn_error_t *
svn_uri_get_dirent_from_file_url(const char **dirent,
const char *url,
apr_pool_t *result_pool);
/** Set @a *url to a file:// URL, corresponding to @a dirent using the
* platform specific dirent and file:// rules.
*
* Allocate the result in @a result_pool.
*
* @since New in 1.7.
*/
svn_error_t *
svn_uri_get_file_url_from_dirent(const char **url,
const char *dirent,
apr_pool_t *result_pool);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SVN_DIRENT_URI_H */