On Thu, Feb 25, 2010 at 12:11 AM, Bert Huijben <[email protected]> wrote:
>
>
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]] On
>> Behalf Of Lieven Govaerts
>> Sent: woensdag 24 februari 2010 23:39
>> To: C. Michael Pilato
>> Cc: Subversion Development
>> Subject: Re: bug report: ra_serf gets PROPFIND failure on certain non-
>> ASCII paths
>
>
>> These paths are canonicalized before being used, but
>> svn_uri_canonicalize doesn't touch the encoded characters. Maybe it
>> should just convert those letters to lowercase? I don't really see a
>> better fix.
>
> svn_uri_canonicalize is still used for more than urls/uris, so it doesn't
> handle any encoding itself.
>
> But besides that, I also think this is not the right way to fix this. For
> several characters in uris it is optional if they are escaped or not. We need
> a better fix than just fixing the casing of the escaped characters...
>
> Unescaping the paths would be an option that resolves it in the generic case,
> or unescape followed by a specific standard escaping. (This last method is
> used in some class libraries to avoid similar issues, but to provide a useful
> uri anyway)
Attached patch fixes the problem. Better suggestions are welcome, I'll
commit tonight.
Lieven
[[[
ra_serf: Fix support for international characters in paths.
Found by: cmpilato
* subversion/libsvn_ra_serf/property.c
(end_propfind): Replace call to svn_uri_canonicalize with a call to
svn_ra_serf__uri_to_internal.
* subversion/libsvn_ra_serf/merge.c
(end_merge): Here too.
* subversion/libsvn_ra_serf/ra_serf.h
(svn_ra_serf__uri_to_internal): New function declaration.
* subversion/libsvn_ra_serf/util.c
(svn_ra_serf__uri_to_internal): New function definition.
]]]
Index: subversion/libsvn_ra_serf/merge.c
===================================================================
--- subversion/libsvn_ra_serf/merge.c (revision 911289)
+++ subversion/libsvn_ra_serf/merge.c (working copy)
@@ -364,7 +364,7 @@
info->prop_val = apr_pstrmemdup(info->pool, info->prop_val,
info->prop_val_len);
if (strcmp(info->prop_name, "href") == 0)
- info->prop_val = svn_uri_canonicalize(info->prop_val, info->pool);
+ info->prop_val = svn_ra_serf__uri_to_internal(info->prop_val,
info->pool);
/* Set our property. */
apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,
Index: subversion/libsvn_ra_serf/util.c
===================================================================
--- subversion/libsvn_ra_serf/util.c (revision 911289)
+++ subversion/libsvn_ra_serf/util.c (working copy)
@@ -1772,3 +1772,20 @@
return SVN_NO_ERROR;
}
+
+const char *
+svn_ra_serf__uri_to_internal(const char *uri_in, apr_pool_t *pool)
+{
+ const char *target;
+
+ /* Convert to URI, unescaping all internatonal characters. */
+ target = svn_path_uri_decode(uri_in, pool);
+
+ /* Now escape the international characters again. */
+ target = svn_path_uri_from_iri(target, pool);
+
+ /* Strip any trailing '/' and collapse other redundant elements. */
+ target = svn_uri_canonicalize(target, pool);
+
+ return target;
+}
Index: subversion/libsvn_ra_serf/property.c
===================================================================
--- subversion/libsvn_ra_serf/property.c (revision 911289)
+++ subversion/libsvn_ra_serf/property.c (working copy)
@@ -29,6 +29,7 @@
#include "svn_xml.h"
#include "svn_props.h"
#include "svn_dirent_uri.h"
+#include "svn_path.h"
#include "private/svn_dav_protocol.h"
#include "svn_private_config.h"
@@ -332,7 +333,7 @@
{
if (strcmp(ctx->depth, "1") == 0)
{
- ctx->current_path = svn_uri_canonicalize(info->val, ctx->pool);
+ ctx->current_path = svn_ra_serf__uri_to_internal(info->val,
ctx->pool);
}
else
{
Index: subversion/libsvn_ra_serf/ra_serf.h
===================================================================
--- subversion/libsvn_ra_serf/ra_serf.h (revision 911289)
+++ subversion/libsvn_ra_serf/ra_serf.h (working copy)
@@ -1521,6 +1521,13 @@
svn_error_t *
svn_ra_serf__error_on_status(int status_code, const char *path);
+/**
+ * Handle an external uri so that it can be compared with other uri's.
+ * (canonicalize + re-encode international characters).
+ */
+const char *
+svn_ra_serf__uri_to_internal(const char *uri_in, apr_pool_t *pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */