Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
UrlFilter.js
001 /** @const */
002 var UrlFilter =
003 {
004 /**
005 * @param {*} attrValue
006 * @param {!Object} urlConfig
007 * @param {?Logger=} logger
008 * @return {*}
009 */
010 filter: function(attrValue, urlConfig, logger)
011 {
012 /**
013 * Trim the URL to conform with HTML5 then parse it
014 * @link http://dev.w3.org/html5/spec/links.html#attr-hyperlink-href
015 */
016 var p = UrlFilter.parseUrl(attrValue.replace(/^\s+/, '').replace(/\s+$/, ''));
017
018 var error = UrlFilter.validateUrl(urlConfig, p);
019 if (error)
020 {
021 if (logger)
022 {
023 p['attrValue'] = attrValue;
024 logger.err(error, p);
025 }
026
027 return false;
028 }
029
030 return UrlFilter.rebuildUrl(urlConfig, p);
031 },
032
033 /**
034 * Parse a URL and return its components
035 *
036 * Similar to PHP's own parse_url() except that all parts are always returned
037 *
038 * @param {string} url Original URL
039 * @return {!Object}
040 */
041 parseUrl: function(url)
042 {
043 var regexp = /^(?:([a-z][-+.\w]*):)?(?:\/\/(?:([^:\/?#]*)(?::([^\/?#]*)?)?@)?(?:(\[[a-f\d:]+\]|[^:\/?#]+)(?::(\d*))?)?(?![^\/?#]))?([^?#]*)(\?[^#]*)?(#.*)?$/i;
044
045 // NOTE: this regexp always matches because of the last three captures
046 var m = regexp['exec'](url),
047 parts = {},
048 tokens = ['scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment'];
049 tokens.forEach(
050 function(name, i)
051 {
052 parts[name] = (m[i + 1] > '') ? m[i + 1] : '';
053 }
054 );
055
056 /**
057 * @link http://tools.ietf.org/html/rfc3986#section-3.1
058 *
059 * 'An implementation should accept uppercase letters as equivalent to lowercase in
060 * scheme names (e.g., allow "HTTP" as well as "http") for the sake of robustness but
061 * should only produce lowercase scheme names for consistency.'
062 */
063 parts['scheme'] = parts['scheme'].toLowerCase();
064
065 /**
066 * Normalize the domain label separators and remove trailing dots
067 * @link http://url.spec.whatwg.org/#domain-label-separators
068 */
069 parts['host'] = parts['host'].replace(/[\u3002\uff0e\uff61]/g, '.').replace(/\.+$/g, '');
070
071 // Test whether host has non-ASCII characters and punycode it if possible
072 if (/[^\x00-\x7F]/.test(parts['host']) && typeof punycode !== 'undefined')
073 {
074 parts['host'] = punycode.toASCII(parts['host']);
075 }
076
077 return parts;
078 },
079
080 /**
081 * Rebuild a parsed URL
082 *
083 * @param {!Object} urlConfig
084 * @param {!Object} p
085 * @return {string}
086 */
087 rebuildUrl: function(urlConfig, p)
088 {
089 var url = '';
090 if (p['scheme'] !== '')
091 {
092 url += p['scheme'] + ':';
093 }
094 if (p['host'] !== '')
095 {
096 url += '//';
097
098 // Add the credentials if applicable
099 if (p['user'] !== '')
100 {
101 // Reencode the credentials in case there are invalid chars in them, or suspicious
102 // characters such as : or @ that could confuse a browser into connecting to the
103 // wrong host (or at least, to a host that is different than the one we thought)
104 url += rawurlencode(decodeURIComponent(p['user']));
105
106 if (p['pass'] !== '')
107 {
108 url += ':' + rawurlencode(decodeURIComponent(p['pass']));
109 }
110
111 url += '@';
112 }
113
114 url += p['host'];
115
116 // Append the port number (note that as per the regexp it can only contain digits)
117 if (p['port'] !== '')
118 {
119 url += ':' + p['port'];
120 }
121 }
122 else if (p['scheme'] === 'file')
123 {
124 // Allow the file: scheme to not have a host and ensure it starts with slashes
125 url += '//';
126 }
127
128 // Build the path, including the query and fragment parts
129 var path = p['path'] + p['query'] + p['fragment'];
130
131 /**
132 * "For consistency, URI producers and normalizers should use uppercase hexadecimal digits
133 * for all percent- encodings."
134 *
135 * @link http://tools.ietf.org/html/rfc3986#section-2.1
136 */
137 path = path.replace(
138 /%.?[a-f]/g,
139 function (str)
140 {
141 return str.toUpperCase();
142 },
143 path
144 );
145
146 // Append the sanitized path to the URL
147 url += UrlFilter.sanitizeUrl(path);
148
149 // Replace the first colon if there's no scheme and it could potentially be interpreted as
150 // the scheme separator
151 if (!p['scheme'])
152 {
153 url = url.replace(/^([^\/]*):/, '$1%3A');
154 }
155
156 return url;
157 },
158
159 /**
160 * Sanitize a URL for safe use regardless of context
161 *
162 * This method URL-encodes some sensitive characters in case someone would want to use the URL in
163 * some JavaScript thingy, or in CSS. We also encode characters that are not allowed in the path
164 * of a URL as defined in RFC 3986 appendix A, including percent signs that are not immediately
165 * followed by two hex digits.
166 *
167 * " and ' to prevent breaking out of quotes (JavaScript or otherwise)
168 * ( and ) to prevent the use of functions in JavaScript (eval()) or CSS (expression())
169 * < and > to prevent breaking out of <script>
170 * \r and \n because they're illegal in JavaScript
171 * [ and ] because the W3 validator rejects them and they "should" be escaped as per RFC 3986
172 * Non-ASCII characters as per RFC 3986
173 * Control codes and spaces, as per RFC 3986
174 *
175 * @link http://sla.ckers.org/forum/read.php?2,51478
176 * @link http://timelessrepo.com/json-isnt-a-javascript-subset
177 * @link http://www.ietf.org/rfc/rfc3986.txt
178 * @link http://stackoverflow.com/a/1547922
179 * @link http://tools.ietf.org/html/rfc3986#appendix-A
180 *
181 * @param {string} url Original URL
182 * @return {string} Sanitized URL
183 */
184 sanitizeUrl: function(url)
185 {
186 return url.replace(/[^\u0020-\u007E]+/g, encodeURIComponent).replace(
187 /%(?![0-9A-Fa-f]{2})|[^!#-&*-;=?-Z_a-z~]/g,
188 function (m)
189 {
190 return '%' + m[0].charCodeAt(0).toString(16).toUpperCase();
191 }
192 );
193 },
194
195 /**
196 * Validate a parsed URL
197 *
198 * @param {!Object} urlConfig
199 * @param {!Object} p
200 * @return {string|undefined}
201 */
202 validateUrl: function(urlConfig, p)
203 {
204 if (p['scheme'] !== '' && !urlConfig.allowedSchemes.test(p['scheme']))
205 {
206 return 'URL scheme is not allowed';
207 }
208
209 if (p['host'] !== '')
210 {
211 /**
212 * Test whether the host is valid
213 * @link http://tools.ietf.org/html/rfc1035#section-2.3.1
214 * @link http://tools.ietf.org/html/rfc1123#section-2
215 */
216 var regexp = /^(?!-)[-a-z0-9]{0,62}[a-z0-9](?:\.(?!-)[-a-z0-9]{0,62}[a-z0-9])*$/i;
217 if (!regexp.test(p['host']))
218 {
219 // If the host invalid, retest as an IPv4 and IPv6 address (IPv6 in brackets)
220 if (!NetworkFilter.filterIpv4(p['host'])
221 && !NetworkFilter.filterIpv6(p['host'].replace(/^\[(.*)\]$/, '$1', p['host'])))
222 {
223 return 'URL host is invalid';
224 }
225 }
226
227 if ((urlConfig.disallowedHosts && urlConfig.disallowedHosts.test(p['host']))
228 || (urlConfig.restrictedHosts && !urlConfig.restrictedHosts.test(p['host'])))
229 {
230 return 'URL host is not allowed';
231 }
232 }
233 else if (/^(?:(?:f|ht)tps?)$/.test(p['scheme']))
234 {
235 return 'Missing host';
236 }
237 }
238 };