PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » HTTP » HTTP_WebDAV_Server » Bug #6189

Various international filename issues

Details

Submitted2005-12-08 08:42 UTC
Frompprasse at actindo dot de
Assignedhholzgra
StatusClosed
PackageHTTP_WebDAV_Server
PHP VersionIrrelevant
OSLinux / MacOS / Windows
Roadmaps1.0

Comments

[2005-12-08 08:42 UTC] pprasse at actindo dot de

Description:
------------
As said in bug #4971 _urlencode is not sufficient for international filenames.

1. _urlencode has to add property encoding (and _urldecode has to decode properly) if _prop_encoding!='utf-8' for clients to display international filenames correctly. (Fix attached)

2. Windows submits question marks in filenames (which you can not create in Windows but can be created by other clients) as literal '?', which means we get everything before the question mark in $_SERVER['PATH_INFO'] and everything behind it in $_SERVER['QUERY_STRING']. (Fix attached)

3. In _copymove we have to _urldecode $options['dest'] before checking for locks. (Fix attached)

[2005-12-08 08:44 UTC] pprasse at actindo dot de

Here's a patch for Server.php:

--- Server.php 2005-04-06 00:51:09.000000000 +0200
+++ Server.php.new 2005-12-08 09:34:02.617707904 +0100
@@ -129,7 +129,7 @@
$uri.= "//$_SERVER[HTTP_HOST]$_SERVER[SCRIPT_NAME]";

$this->base_uri = $uri;
- $this->uri = $uri . $_SERVER[PATH_INFO]";
+ $this->uri = $uri . $_SERVER['PATH_INFO'];

// identify ourselves
if (empty($this->dav_powered_by)) {
@@ -158,9 +158,15 @@
$this->http_status("412 Precondition failed");
return;
}
-
+
// set path
- $this->path = $this->_urldecode($_SERVER["PATH_INFO"]);
+ if( strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'microsoft') !== FALSE )
+ {
+ // Windows sends question marks in filenames as query string
+ $this->path = $this->_urldecode($_SERVER["PATH_INFO"].(!empty($_SERVER['QUERY_STRING']) ? '%3F'.$_SERVER['QUERY_STRING'] : '') );
+ }
+ else
+ $this->path = $this->_urldecode($_SERVER["PATH_INFO"]);
if (!strlen($this->path)) {
header("Location: ".$this->base_uri."/");
exit;
@@ -634,7 +640,7 @@

$href = $this->_slashify($_SERVER['SCRIPT_NAME'] . $path);

- echo " <D:href>$href</D:href>\n";
+ echo " <D:href>".$this->_urlencode($href)."</D:href>\n";

// report all found properties and their values (if any)
if (isset($file["props"]) && is_array($file["props"])) {
@@ -1294,7 +1300,7 @@

$options["locktoken"] = $this->_new_locktoken();

- $stat = $this->lock($options);
+ $stat = $this->lock($options);
}

if(is_bool($stat)) {
@@ -1398,6 +1404,7 @@
!strncmp($_SERVER["SCRIPT_NAME"], $path,
strlen($_SERVER["SCRIPT_NAME"]))) {
$options["dest"] = substr($path, strlen($_SERVER["SCRIPT_NAME"]));
+ $options['dest'] = $this->_urldecode( $options['dest'] );
if (!$this->_check_lock_status($options["dest"])) {
$this->http_status("423 Locked");
return;
@@ -1774,7 +1781,7 @@
// ... and lock is not owned?
if (is_array($lock) && count($lock)) {
// FIXME doesn't check uri restrictions yet
- if (!strstr($_SERVER["HTTP_IF"], $lock["token"])) {
+ if( strpos($_SERVER["HTTP_IF"], $lock["token"]) === FALSE ) {
if (!$exclusive_only || ($lock["scope"] !== "shared"))
return false;
}
@@ -1864,13 +1871,10 @@
* @param string URL to encode
* @return string encoded URL
*/
- function _urlencode($url)
+ function _urlencode( $path )
{
- return strtr($url, array(" "=>"%20",
- "&"=>"%26",
- "<"=>"%3C",
- ">"=>"%3E",
- ));
+ $ret = rawurlencode( $this->_prop_encode($path) );
+ return strtr( $ret, array( '%2F' => '/' ) );
}

/**
@@ -1881,9 +1885,9 @@
* @param string URL to decode
* @return string decoded URL
*/
- function _urldecode($path)
+ function _urldecode( $path )
{
- return urldecode($path);
+ return $this->_prop_decode( rawurldecode($path) );
}

/**
@@ -1906,6 +1910,25 @@
}

/**
+ * UTF-8 decode property values if not already done so
+ *
+ * @param string text to decode
+ * @return string utf-8 decoded text
+ */
+ function _prop_decode($text)
+ {
+ switch (strtolower($this->_prop_encoding)) {
+ case "utf-8":
+ return $text;
+ case "iso-8859-1":
+ case "iso-8859-15":
+ case "latin-1":
+ default:
+ return utf8_decode($text);
+ }
+ }
+
+ /**
* Slashify - make sure path ends in a slash
*
* @param string directory path