summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/bootstrap.inc55
-rw-r--r--includes/common.inc33
-rw-r--r--includes/file.inc4
-rw-r--r--includes/path.inc2
-rw-r--r--includes/stream_wrappers.inc2
5 files changed, 66 insertions, 30 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 4184c4036..8fff1c40e 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -492,6 +492,13 @@ function drupal_environment_initialize() {
$_SERVER['HTTP_HOST'] = '';
}
+ // When clean URLs are enabled, emulate ?q=foo/bar using REQUEST_URI. It is
+ // not possible to append the query string using mod_rewrite without the B
+ // flag (this was added in Apache 2.2.8), because mod_rewrite unescapes the
+ // path before passing it on to PHP. This is a problem when the path contains
+ // e.g. "&" or "%" that have special meanings in URLs and must be encoded.
+ $_GET['q'] = request_path();
+
// Enforce E_ALL, but allow users to set levels not part of E_ALL.
error_reporting(E_ALL | error_reporting());
@@ -559,8 +566,8 @@ function drupal_settings_initialize() {
// $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
// be modified by a visitor.
- if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
- $base_path = "/$dir";
+ if ($dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')) {
+ $base_path = $dir;
$base_url .= $base_path;
$base_path .= '/';
}
@@ -1859,6 +1866,50 @@ function language_default($property = NULL) {
}
/**
+ * Returns the requested URL path of the page being viewed.
+ *
+ * Examples:
+ * - http://example.com/node/306 returns "node/306".
+ * - http://example.com/drupalfolder/node/306 returns "node/306" while
+ * base_path() returns "/drupalfolder/".
+ * - http://example.com/path/alias (which is a path alias for node/306) returns
+ * "path/alias" as opposed to the internal path.
+ *
+ * @return
+ * The requested Drupal URL path.
+ *
+ * @see current_path()
+ */
+function request_path() {
+ static $path;
+
+ if (isset($path)) {
+ return $path;
+ }
+
+ if (isset($_GET['q'])) {
+ // This is a request with a ?q=foo/bar query string. $_GET['q'] is
+ // overwritten in drupal_path_initialize(), but request_path() is called
+ // very early in the bootstrap process, so the original value is saved in
+ // $path and returned in later calls.
+ $path = $_GET['q'];
+ }
+ elseif (isset($_SERVER['REQUEST_URI'])) {
+ // This is a request using a clean URL. Extract the path from REQUEST_URI.
+ $request_path = strtok($_SERVER['REQUEST_URI'], '?');
+ $base_path_len = strlen(rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/'));
+ // Unescape and strip $base_path prefix, leaving q without a leading slash.
+ $path = substr(urldecode($request_path), $base_path_len + 1);
+ }
+ else {
+ // This is the front page.
+ $path = '';
+ }
+
+ return $path;
+}
+
+/**
* If Drupal is behind a reverse proxy, we use the X-Forwarded-For header
* instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of
* the proxy server, and not the client's. If Drupal is run in a cluster
diff --git a/includes/common.inc b/includes/common.inc
index c6472be18..20b0648c7 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -501,7 +501,6 @@ function drupal_http_build_query(array $query, $parent = '') {
}
else {
// For better readability of paths in query strings, we decode slashes.
- // @see drupal_encode_path()
$params[] = $key . '=' . str_replace('%2F', '/', rawurlencode($value));
}
}
@@ -623,38 +622,18 @@ function drupal_parse_url($url) {
}
/**
- * Encode a path for usage in a URL.
+ * Encodes a Drupal path for use in a URL.
*
- * Wrapper around rawurlencode() which avoids Apache quirks. Should be used when
- * placing arbitrary data into the path component of an URL.
+ * For aesthetic reasons slashes are not escaped.
*
- * Do not use this function to pass a path to url(). url() properly handles
- * and encodes paths internally.
- * This function should only be used on paths, not on query string arguments.
- * Otherwise, unwanted double encoding will occur.
- *
- * Notes:
- * - For aesthetic reasons, we do not escape slashes. This also avoids a 'feature'
- * in Apache where it 404s on any path containing '%2F'.
- * - mod_rewrite unescapes %-encoded ampersands, hashes, and slashes when clean
- * URLs are used, which are interpreted as delimiters by PHP. These
- * characters are double escaped so PHP will still see the encoded version.
- * - With clean URLs, Apache changes '//' to '/', so every second slash is
- * double escaped.
+ * Note that url() takes care of calling this function, so a path passed to that
+ * function should not be encoded in advance.
*
* @param $path
- * The URL path component to encode.
+ * The Drupal path to encode.
*/
function drupal_encode_path($path) {
- if (!empty($GLOBALS['conf']['clean_url'])) {
- return str_replace(array('%2F', '%26', '%23', '//'),
- array('/', '%2526', '%2523', '/%252F'),
- rawurlencode($path)
- );
- }
- else {
- return str_replace('%2F', '/', rawurlencode($path));
- }
+ return str_replace('%2F', '/', rawurlencode($path));
}
/**
diff --git a/includes/file.inc b/includes/file.inc
index 6395c6323..ccac9cabc 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -901,6 +901,10 @@ function file_unmunge_filename($filename) {
* of $basename.
*/
function file_create_filename($basename, $directory) {
+ // Strip control characters (ASCII value < 32). Though these are allowed in
+ // some filesystems, not many applications handle them well.
+ $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
+
// A URI or path may already have a trailing slash or look like "public://".
if (substr($directory, -1) == '/') {
$separator = '';
diff --git a/includes/path.inc b/includes/path.inc
index 0f61d6c27..8585a3b78 100644
--- a/includes/path.inc
+++ b/includes/path.inc
@@ -384,6 +384,8 @@ function drupal_match_path($path, $patterns) {
*
* @return
* The current Drupal URL path.
+ *
+ * @see request_path()
*/
function current_path() {
return $_GET['q'];
diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc
index b4edb0933..2940b1e66 100644
--- a/includes/stream_wrappers.inc
+++ b/includes/stream_wrappers.inc
@@ -639,7 +639,7 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
*/
function getExternalUrl() {
$path = str_replace('\\', '/', file_uri_target($this->uri));
- return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . $path;
+ return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . drupal_encode_path($path);
}
}