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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

UrlFilter.js

Zuletzt modifiziert: 02.04.2025, 15:04 - Dateigröße: 6.41 KiB


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  };