se) 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: * -
"/foo/bar/baz"  ==>  "/foo/bar" and "baz"
* -
"/bar"          ==>  "/"  and "bar"
* -
"/"             ==>  "/"  and ""
* -
"bar"           ==>  ""   and "bar"
* -
""              ==>  ""   and ""
* Windows: -
"X:/"           ==>  "X:/" and ""
* -
"X:/foo"        ==>  "X:/" and "foo"
* -
"X:foo"         ==>  "X:" and "foo"
* Posix: -
"X:foo"         ==>  ""   and "X:foo"
* * 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: * -
"foo/bar/baz"  ==>  "foo/bar" and "baz"
* -
"bar"          ==>  ""  and "bar"
* -
""              ==>  ""   and ""
* * 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: * -
"http://server/foo/bar"  ==>  "http://server/foo" and "bar"
* * 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 const char *'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 const char *'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 */