~ubuntu-branches/ubuntu/jaunty/moodle/jaunty

« back to all changes in this revision

Viewing changes to lib/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php

  • Committer: Bazaar Package Importer
  • Author(s): Jordan Mantha, Matt Oquist
  • Date: 2009-02-25 15:16:22 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20090225151622-0ekt1liwhv2obfza
Tags: 1.9.4.dfsg-0ubuntu1
* Merge with Debian git (Closes LP: #322961, #239481, #334611):
  - use Ubuntu's smarty lib directory for linking
  - use internal yui library 
  - add update-notifier support back in

[Matt Oquist]
  * renamed prerm script
  * significantly rewrote postinst and other maintainer scripts to improve
    user experience and package maintainability
    (Closes LP: #225662, #325450, #327843, #303078, #234609)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
// does not support network paths
 
4
 
 
5
require_once 'HTMLPurifier/URIFilter.php';
 
6
 
 
7
HTMLPurifier_ConfigSchema::define(
 
8
    'URI', 'MakeAbsolute', false, 'bool', '
 
9
<p>
 
10
    Converts all URIs into absolute forms. This is useful when the HTML
 
11
    being filtered assumes a specific base path, but will actually be
 
12
    viewed in a different context (and setting an alternate base URI is
 
13
    not possible). %URI.Base must be set for this directive to work.
 
14
    This directive has been available since 2.1.0.
 
15
</p>
 
16
');
 
17
 
 
18
class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter
 
19
{
 
20
    var $name = 'MakeAbsolute';
 
21
    var $base;
 
22
    var $basePathStack = array();
 
23
    function prepare($config) {
 
24
        $def = $config->getDefinition('URI');
 
25
        $this->base = $def->base;
 
26
        if (is_null($this->base)) {
 
27
            trigger_error('URI.MakeAbsolute is being ignored due to lack of value for URI.Base configuration', E_USER_ERROR);
 
28
            return;
 
29
        }
 
30
        $this->base->fragment = null; // fragment is invalid for base URI
 
31
        $stack = explode('/', $this->base->path);
 
32
        array_pop($stack); // discard last segment
 
33
        $stack = $this->_collapseStack($stack); // do pre-parsing
 
34
        $this->basePathStack = $stack;
 
35
    }
 
36
    function filter(&$uri, $config, &$context) {
 
37
        if (is_null($this->base)) return true; // abort early
 
38
        if (
 
39
            $uri->path === '' && is_null($uri->scheme) &&
 
40
            is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)
 
41
        ) {
 
42
            // reference to current document
 
43
            $uri = $this->base->copy();
 
44
            return true;
 
45
        }
 
46
        if (!is_null($uri->scheme)) {
 
47
            // absolute URI already: don't change
 
48
            if (!is_null($uri->host)) return true;
 
49
            $scheme_obj = $uri->getSchemeObj($config, $context);
 
50
            if (!$scheme_obj) {
 
51
                // scheme not recognized
 
52
                return false;
 
53
            }
 
54
            if (!$scheme_obj->hierarchical) {
 
55
                // non-hierarchal URI with explicit scheme, don't change
 
56
                return true;
 
57
            }
 
58
            // special case: had a scheme but always is hierarchical and had no authority
 
59
        }
 
60
        if (!is_null($uri->host)) {
 
61
            // network path, don't bother
 
62
            return true;
 
63
        }
 
64
        if ($uri->path === '') {
 
65
            $uri->path = $this->base->path;
 
66
        }elseif ($uri->path[0] !== '/') {
 
67
            // relative path, needs more complicated processing
 
68
            $stack = explode('/', $uri->path);
 
69
            $new_stack = array_merge($this->basePathStack, $stack);
 
70
            $new_stack = $this->_collapseStack($new_stack);
 
71
            $uri->path = implode('/', $new_stack);
 
72
        }
 
73
        // re-combine
 
74
        $uri->scheme = $this->base->scheme;
 
75
        if (is_null($uri->userinfo)) $uri->userinfo = $this->base->userinfo;
 
76
        if (is_null($uri->host))     $uri->host     = $this->base->host;
 
77
        if (is_null($uri->port))     $uri->port     = $this->base->port;
 
78
        return true;
 
79
    }
 
80
    
 
81
    /**
 
82
     * Resolve dots and double-dots in a path stack
 
83
     * @private
 
84
     */
 
85
    function _collapseStack($stack) {
 
86
        $result = array();
 
87
        for ($i = 0; isset($stack[$i]); $i++) {
 
88
            $is_folder = false;
 
89
            // absorb an internally duplicated slash
 
90
            if ($stack[$i] == '' && $i && isset($stack[$i+1])) continue;
 
91
            if ($stack[$i] == '..') {
 
92
                if (!empty($result)) {
 
93
                    $segment = array_pop($result);
 
94
                    if ($segment === '' && empty($result)) {
 
95
                        // error case: attempted to back out too far:
 
96
                        // restore the leading slash
 
97
                        $result[] = '';
 
98
                    } elseif ($segment === '..') {
 
99
                        $result[] = '..'; // cannot remove .. with ..
 
100
                    }
 
101
                } else {
 
102
                    // relative path, preserve the double-dots
 
103
                    $result[] = '..';
 
104
                }
 
105
                $is_folder = true;
 
106
                continue;
 
107
            }
 
108
            if ($stack[$i] == '.') {
 
109
                // silently absorb
 
110
                $is_folder = true;
 
111
                continue;
 
112
            }
 
113
            $result[] = $stack[$i];
 
114
        }
 
115
        if ($is_folder) $result[] = '';
 
116
        return $result;
 
117
    }
 
118
}
 
119