网站源码为glype1.3
虚拟主机操作系统:windows2003在线代理网,其它网页元素正常显示,只有图片不能显示,图片显示为一个红色的叉。
未选网页加密时,图片的SRC地址也有异常,例如图片链接地址中的“/”显示“%2F”。
网站我就不说出来了,怕被墙。
求哪位大侠能帮帮我把类似“%2F”转换成浏览器能识别的“/”,感谢!glype1.3下载地址:http://www.glype.com/
虚拟主机操作系统:windows2003在线代理网,其它网页元素正常显示,只有图片不能显示,图片显示为一个红色的叉。
未选网页加密时,图片的SRC地址也有异常,例如图片链接地址中的“/”显示“%2F”。
网站我就不说出来了,怕被墙。
求哪位大侠能帮帮我把类似“%2F”转换成浏览器能识别的“/”,感谢!glype1.3下载地址:http://www.glype.com/
解决方案 »
- 求PHP通用的字符过滤函数。
- 还是绘图问题,对于函数理解
- PHP使用CURL上传文件
- 求MAC地址的正则表达式
- DOMDocument::saveXML 返回值为空字符串
- 关于目前data、uploads有执行.php权限,非常危险,需要立即取消目录的执行权限!的问题不会弄啊,大神求教。。。
- 连接局域网上某机器数据库超时!
- 怎么让数组一行显示3列(急)
- 时间本地化“ Tue, 16 Aug 2005 17:39:36 GMT”怎样转换为北京时间啊
- 一个关于通过Form上传文件的问题
- [求助]php删除问题~!求助~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- PHP关天UCenter整合接口方面的问题
中文可以urldecode
<?php
/*******************************************************************
* Glype is copyright and trade 2007-2012 UpsideOut, Inc. d/b/a Glype
* and/or its licensors, successors and assigners. All rights reserved.
*
* Use of Glype is subject to the terms of the Software License Agreement.
* http://www.glype.com/license.php
*******************************************************************
* This is the parser for the proxy - changes the original 'raw'
* document so that everything (images, links, etc.) is rerouted to
* be downloaded via the proxy script instead of directly.
******************************************************************/class parser { # State of javascript parser - null for parse everything, false
# for parse all non-standard overrides, or (array) with specifics
private $jsFlagState;
# Browsing options (Remove Scripts, etc.)
private $htmlOptions; # Constructor accepts options and saves them in the object
function __construct($htmlOptions, $jsFlags) {
$this->jsFlagState = $jsFlags;
$this->htmlOptions = $htmlOptions;
}
/*****************************************************************
* HTML parsers - main parsing function splits up document into
* component parts ('normal' HTML, scripts and styles)
******************************************************************/
function HTMLDocument($input, $insert='', $inject=false, $footer='') { #
# Apply parsing that only needs to be done once..
# # Remove titles if option is enabled
if ( $this->htmlOptions['stripTitle'] ) {
$input = preg_replace('#<title.*?</title>#is', '', $input, 1);
$input = preg_replace('#<meta[^>]*name=["\']title["\'][^>]*>#is', '', $input, 1);
} # Remove and record a <base> href
$input = preg_replace_callback('#<base href\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)[^>]*>#i', 'html_stripBase', $input, 1); # Proxy url= values in meta redirects
$input = preg_replace_callback('#content\s*=\s*(["\\\'])?[0-9]+\s*;\s*url=([\\\'"]|&\#39;)?((?(?<=")[^"]+|(?(?<=\\\')[^\\\']+|[^\\\'" >]+)))(?(2)\\2|)(?(1)\\1|)#i', 'html_metaRefresh', $input, 1); # Process forms
$input = preg_replace_callback('#<form([^>]*)>(.*?)</form>#is', 'html_form', $input);
# Remove scripts blocks (avoids individual processing below)
if ( $this->htmlOptions['stripJS'] ) {
$input = preg_replace('#<script[^>]*>.*?</script>#is', '', $input);
}
#
# Split up the document into its different types and parse them
# # Build up new document into this var
$new = '';
$offset = 0; # Find instances of script or style blocks
while ( preg_match('#<(s(?:cript|tyle))[^>]*>#i', $input, $match, PREG_OFFSET_CAPTURE, $offset) ) { # What type of block is this?
$block = strtolower($match[1][0]); # Start position of content
$outerStart = $match[0][1];
$innerStart = $outerStart + strlen($match[0][0]); # Determine type of end tag and find it's position
$endTag = "</$block>";
$innerEnd = stripos($input, $endTag, $innerStart);
if ($innerEnd===false) {
$endTag = "</";
$innerEnd = stripos($input, $endTag, $innerStart);
if ($innerEnd===false) {
$input = preg_replace('#<script[^>]*>.*?$#is', '', $input);
break;
}
}
$outerEnd = $innerEnd + strlen($endTag);
# Parse everything up till here and add to the new document
$new .= $this->HTML(substr($input, $offset, $innerStart - $offset));
# Find parsing function
$parseFunction = $block == 'style' ? 'CSS' : 'JS' ; # Add the parsed block
$new .= $this->$parseFunction(substr($input, $innerStart, $innerEnd - $innerStart)); # Move offset to new position
$offset = $innerEnd; }
# And add the final chunk (between last script/style block and end of doc)
$new .= $this->HTML(substr($input, $offset)); # Replace input with the updated document
$input = $new; # Encode the page
if ( $this->htmlOptions['encodePage'] ) {
$input = encodePage($input);
} #
# Now add our own code bits
# # Insert our mini form after the <body>
if ( $insert !== false ) { # Check for a frameset
if ( ( $useFrames = stripos($input, '<frameset') ) !== false ) { # Flag the frames so only first displays mini-form
$input = preg_replace_callback('#<frame[^>]+src\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)#i', 'html_flagFrames', $input); } # Attempt to add after body
$input = preg_replace('#(<body[^>]*>)#i', '$1' . $insert, $input, 1, $tmp); # Check it inserted and append (if not a frameset)
if ( ! $tmp && ! $useFrames ) {
$input = $insert . $input;
} } # Insert our javascript library
if ( $inject ) { # Generate javascript to insert
$inject = injectionJS(); # Add our proxy javascript after <head>
$input = preg_replace('#(<head[^>]*>)#i', '$1' . $inject, $input, 1, $tmp); # If no <head>, just prepend
if ( ! $tmp ) {
$input = $inject . $input;
} } # Add anything to the footer?
if ( $footer ) { $input = preg_replace('#(</body[^>]*>)#i', $footer . '$1', $input, 1, $tmp); # If no </body>, just append the footer
if ( ! $tmp ){
$input .= $footer;
} } # Return new document
return $input; } # Parse HTML sections
function HTML($input) { # Removing objects? Follow spec and display inner content of object tags instead.
if ( $this->htmlOptions['stripObjects'] ) { # Remove all object tags (including those deprecated but still common)
$input = preg_replace('#<(?>object|applet|param|embed)[^>]*>#i', '', $input, -1, $tmp); # Found any? Remove the corresponding end tags
if ( $tmp ) {
$input = preg_replace('#</(?>object|applet|param|embed)>#i', '', $input, $tmp);
} } else { # Parse <param name="movie" value="URL"> tags
$input = preg_replace_callback('#<param[^>]+value\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)[^>]*>#i', 'html_paramValue', $input); # To do: proxy object related URLs } # Show content within <noscript> tags
# (preg_ seems to be faster than 2 str_ireplace() calls)
if ( $this->htmlOptions['stripJS'] ) {
$input = preg_replace('#</?noscript>#i', '', $input);
} # Parse onX events
$input = preg_replace_callback('#\b(on(?<!\.on)[a-z]{2,20})\s*=\s*([\\\'"])?((?(2)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(2)\\2|)#i', array(&$this, 'html_eventJS'), $input); # Parse style attributes
$input = preg_replace_callback('#style\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)#i', array(&$this, 'html_elementCSS'), $input); # Proxy URL attributes - this is the bottleneck but optimized
# as much as possible (or at least, as much as I can).
$input = preg_replace_callback('#(?><[A-Z][A-Z0-9]{0,15})(?>\s+[^>\s]+)*?\s*(?>(href|src|background)\s*=(?!\\\\)\s*)(?>([\\\'"])?)((?(2)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^ >]{1,1000}))(?(2)\\2|)#i', 'html_attribute', $input); # Return changed input
return $input; } # Proxy an onX javascript event
function html_eventJS($input) {
return $this->htmlOptions['stripJS'] ? '' : $input[1] . '=' . $input[2] . $this->JS($input[3]) . $input[2];
} # Proxy a style="CSS" attribute
function html_elementCSS($input) {
return 'style=' . $input[1] . $this->CSS($input[2]) . $input[1];
}
<?php
/*******************************************************************
* Glype is copyright and trade 2007-2012 UpsideOut, Inc. d/b/a Glype
* and/or its licensors, successors and assigners. All rights reserved.
*
* Use of Glype is subject to the terms of the Software License Agreement.
* http://www.glype.com/license.php
*******************************************************************
* This is the parser for the proxy - changes the original 'raw'
* document so that everything (images, links, etc.) is rerouted to
* be downloaded via the proxy script instead of directly.
******************************************************************/class parser { # State of javascript parser - null for parse everything, false
# for parse all non-standard overrides, or (array) with specifics
private $jsFlagState;
# Browsing options (Remove Scripts, etc.)
private $htmlOptions; # Constructor accepts options and saves them in the object
function __construct($htmlOptions, $jsFlags) {
$this->jsFlagState = $jsFlags;
$this->htmlOptions = $htmlOptions;
}
/*****************************************************************
* HTML parsers - main parsing function splits up document into
* component parts ('normal' HTML, scripts and styles)
******************************************************************/
function HTMLDocument($input, $insert='', $inject=false, $footer='') { #
# Apply parsing that only needs to be done once..
# # Remove titles if option is enabled
if ( $this->htmlOptions['stripTitle'] ) {
$input = preg_replace('#<title.*?</title>#is', '', $input, 1);
$input = preg_replace('#<meta[^>]*name=["\']title["\'][^>]*>#is', '', $input, 1);
} # Remove and record a <base> href
$input = preg_replace_callback('#<base href\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)[^>]*>#i', 'html_stripBase', $input, 1); # Proxy url= values in meta redirects
$input = preg_replace_callback('#content\s*=\s*(["\\\'])?[0-9]+\s*;\s*url=([\\\'"]|&\#39;)?((?(?<=")[^"]+|(?(?<=\\\')[^\\\']+|[^\\\'" >]+)))(?(2)\\2|)(?(1)\\1|)#i', 'html_metaRefresh', $input, 1); # Process forms
$input = preg_replace_callback('#<form([^>]*)>(.*?)</form>#is', 'html_form', $input);
# Remove scripts blocks (avoids individual processing below)
if ( $this->htmlOptions['stripJS'] ) {
$input = preg_replace('#<script[^>]*>.*?</script>#is', '', $input);
}
#
# Split up the document into its different types and parse them
# # Build up new document into this var
$new = '';
$offset = 0; # Find instances of script or style blocks
while ( preg_match('#<(s(?:cript|tyle))[^>]*>#i', $input, $match, PREG_OFFSET_CAPTURE, $offset) ) { # What type of block is this?
$block = strtolower($match[1][0]); # Start position of content
$outerStart = $match[0][1];
$innerStart = $outerStart + strlen($match[0][0]); # Determine type of end tag and find it's position
$endTag = "</$block>";
$innerEnd = stripos($input, $endTag, $innerStart);
if ($innerEnd===false) {
$endTag = "</";
$innerEnd = stripos($input, $endTag, $innerStart);
if ($innerEnd===false) {
$input = preg_replace('#<script[^>]*>.*?$#is', '', $input);
break;
}
}
$outerEnd = $innerEnd + strlen($endTag);
# Parse everything up till here and add to the new document
$new .= $this->HTML(substr($input, $offset, $innerStart - $offset));
# Find parsing function
$parseFunction = $block == 'style' ? 'CSS' : 'JS' ; # Add the parsed block
$new .= $this->$parseFunction(substr($input, $innerStart, $innerEnd - $innerStart)); # Move offset to new position
$offset = $innerEnd; } # And add the final chunk (between last script/style block and end of doc)
$new .= $this->HTML(substr($input, $offset)); # Replace input with the updated document
$input = $new; # Encode the page
if ( $this->htmlOptions['encodePage'] ) {
$input = encodePage($input);
} #
# Now add our own code bits
# # Insert our mini form after the <body>
if ( $insert !== false ) { # Check for a frameset
if ( ( $useFrames = stripos($input, '<frameset') ) !== false ) { # Flag the frames so only first displays mini-form
$input = preg_replace_callback('#<frame[^>]+src\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)#i', 'html_flagFrames', $input); } # Attempt to add after body
$input = preg_replace('#(<body[^>]*>)#i', '$1' . $insert, $input, 1, $tmp); # Check it inserted and append (if not a frameset)
if ( ! $tmp && ! $useFrames ) {
$input = $insert . $input;
} } # Insert our javascript library
if ( $inject ) { # Generate javascript to insert
$inject = injectionJS(); # Add our proxy javascript after <head>
$input = preg_replace('#(<head[^>]*>)#i', '$1' . $inject, $input, 1, $tmp); # If no <head>, just prepend
if ( ! $tmp ) {
$input = $inject . $input;
} } # Add anything to the footer?
if ( $footer ) { $input = preg_replace('#(</body[^>]*>)#i', $footer . '$1', $input, 1, $tmp); # If no </body>, just append the footer
if ( ! $tmp ){
$input .= $footer;
} } # Return new document
return $input; } # Parse HTML sections
function HTML($input) { # Removing objects? Follow spec and display inner content of object tags instead.
if ( $this->htmlOptions['stripObjects'] ) { # Remove all object tags (including those deprecated but still common)
$input = preg_replace('#<(?>object|applet|param|embed)[^>]*>#i', '', $input, -1, $tmp); # Found any? Remove the corresponding end tags
if ( $tmp ) {
$input = preg_replace('#</(?>object|applet|param|embed)>#i', '', $input, $tmp);
} } else { # Parse <param name="movie" value="URL"> tags
$input = preg_replace_callback('#<param[^>]+value\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)[^>]*>#i', 'html_paramValue', $input); # To do: proxy object related URLs } # Show content within <noscript> tags
# (preg_ seems to be faster than 2 str_ireplace() calls)
if ( $this->htmlOptions['stripJS'] ) {
$input = preg_replace('#</?noscript>#i', '', $input);
} # Parse onX events
$input = preg_replace_callback('#\b(on(?<!\.on)[a-z]{2,20})\s*=\s*([\\\'"])?((?(2)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(2)\\2|)#i', array(&$this, 'html_eventJS'), $input); # Parse style attributes
$input = preg_replace_callback('#style\s*=\s*([\\\'"])?((?(1)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^\s"\\\'>]{1,1000}))(?(1)\\1|)#i', array(&$this, 'html_elementCSS'), $input); # Proxy URL attributes - this is the bottleneck but optimized
# as much as possible (or at least, as much as I can).
$input = preg_replace_callback('#(?><[A-Z][A-Z0-9]{0,15})(?>\s+[^>\s]+)*?\s*(?>(href|src|background)\s*=(?!\\\\)\s*)(?>([\\\'"])?)((?(2)(?(?<=")[^"]{1,1000}|[^\\\']{1,1000})|[^ >]{1,1000}))(?(2)\\2|)#i', 'html_attribute', $input); # Return changed input
return $input; } # Proxy an onX javascript event
function html_eventJS($input) {
return $this->htmlOptions['stripJS'] ? '' : $input[1] . '=' . $input[2] . $this->JS($input[3]) . $input[2];
} # Proxy a style="CSS" attribute
function html_elementCSS($input) {
return 'style=' . $input[1] . $this->CSS($input[2]) . $input[1];
}
/*****************************************************************
* CSS parser - main parsing function
* CSS parsing is a complicated by the caching of CSS files. We need
* to consider (A) cross-domain caching and (B) the unique URLs option.
* A) If possible, use a relative URL so the saved URLs do not explictly
* point to a single domain.
* B) There is a second set of callback functions with "_unique" suffixed
* and these return the original URL to be reparesed.
******************************************************************/ # The URLs depend on the unique and path info settings. The type parameter allows
# us to specify the unique callbacks.
function CSS($input, $storeUnique=false) { # What type of parsing is this? Normally we parse any URLs to redirect
# back through the proxy but not when storing a cache with unique URLs.
$type = $storeUnique ? '_unique' : ''; # CSS needs proxying the calls to url(), @import and src=''
$input = preg_replace_callback('#\burl\s*\(\s*[\\\'"]?([^\\\'"\)]+)[\\\'"]?\s*\)#i', 'css_URL' . $type, $input);
$input = preg_replace_callback('#@import\s*[\\\'"]([^\\\'"\(\)]+)[\\\'"]#i', 'css_import' . $type, $input);
$input = preg_replace_callback('#\bsrc\s*=\s*([\\\'"])?([^)\\\'"]+)(?(1)\\1|)#i', 'css_src' . $type, $input); # Return changed
return $input; }
/*****************************************************************
* Javascript parser - main parsing function
*
* The specific parts that need proxying depends on which javascript
* functions we've been able to override. On first page load, the browser
* capabilities are tested to see what we can do client-side and the results
* sent back to us. This allows us to parse only what we have to.
* If $CONFIG['override_javascript'] is disabled, all commands are parsed
* server-side. This will use much more CPU!
*
* Commands to proxy only if no override at all:
* document.write()
* document.writeln()
* window.open()
* eval()
*
* Commands to proxy, regardless of browser capabilities:
* location.replace()
* .innerHTML=
*
* Commands to proxy if the extra "watch" flag is set
* (the browser doesn't support the .watch() method):
* location=
* x.location=
* location.href=
*
* Commands to proxy if the extra "setters" flag is set
* (the browser doesn't support the __defineSetter__() method):
* .src=
* .href=
* .background=
* .action=
*
* Commands to proxy if the extra "ajax" flag is set
* (the browser failed to override the .open() method):
* XMLHttpRequest.open()
******************************************************************/ function JS($input) { # Stripping?
if ( $this->htmlOptions['stripJS'] ) {
return '';
}
# Get our flags
$flags = $this->jsFlagState; # Unless we know we don't need to, apply all the browser-specific flags
if ( ! is_array($this->jsFlagState) ) {
$flags = array('ajax', 'watch', 'setters');
}
# If override is disabled, add a "base" flag
if ( $this->jsFlagState === null ) {
$flags[] = 'base';
} # Start parsing!
$search = array();
# Create shortcuts to various search patterns:
# "before" - matches preceeding character (string of single char) [ignoring whitespace]
# "after" - matches next character (string of single char) [ignoring whitespace]
# "id" - key for identifying the original match (e.g. if we have >1 of the same key)
$assignmentPattern = array('before' => '.', 'after' => '=');
$methodPattern = array('before' => '.', 'after' => '(');
$functionPattern = array('after' => '('); # Configure strings to search for, starting with always replaced commands
$search['innerHTML'][] = $assignmentPattern;
$search['location'][] = array('after' => '.', 'id' => 'replace()');
# ^ This is only for location.replace() - other forms are handled later # Look for attribute assignments
if ( in_array('setters', $flags) ) {
$search['src'][] = $assignmentPattern;
$search['href'][] = $assignmentPattern;
$search['action'][] = $assignmentPattern;
$search['background'][] = $assignmentPattern;
}
# Look for location changes
# location.href will be handled above, location= is handled here
if ( in_array('watch', $flags) ) {
$search['location'][] = array('after' => '=', 'id' => 'assignment');
} # Look for .open() if either AJAX (XMLHttpRequest.open) or
# base (window.open) flags are present
if ( in_array('ajax', $flags) || in_array('base', $flags) ) {
$search['open'][] = $methodPattern;
}
# Add the basic code if no override
if ( in_array('base', $flags) ) {
$search['eval'][] = $functionPattern;
$search['writeln'][] = $methodPattern;
$search['write'][] = $methodPattern;
} # Set up starting parameters
$offset = 0;
$length = strlen($input);
$searchStrings = array_keys($search); while ( $offset < $length ) { # Start off by assuming no more items (i.e. the next position
# of interest is the end of the document)
$commandPos = $length; # Loop through the search subjects
foreach ( $searchStrings as $item ) { # Any more instances of this?
if ( ( $tmp = strpos($input, $item, $offset) ) === false ) { # Nope, skip to next item
continue; }
# Closer to the currently held 'next' position?
if ( $tmp < $commandPos ) { $commandPos = $tmp;
$command = $item; } } # No matches found? Finish parsing.
if ( $commandPos == $length ) {
break;
}
# We've found the main point of interest; now use the
# search parameters to check the surrounding chars to validate
# the match.
$valid = false; foreach ( $search[$command] as $pattern ) {
# Check the preceeding chars
if ( isset($pattern['before']) && str_checkprev($input, $pattern['before'], $commandPos-1) === false ) {
continue;
}
# Check next chars
if ( isset($pattern['after']) && ( $postCharPos = str_checknext($input, $pattern['after'], $commandPos + strlen($command), false, true) ) === false ) {
continue;
}
# Still here? Match must be OK so generate a match ID
if ( isset($pattern['id']) ) {
$valid = $command . $pattern['id'];
} else {
$valid = $command;
}
break;
}
# What we do next depends on which match (if any) we've found...
switch ( $valid ) {
# Assigment
case 'src':
case 'href':
case 'background':
case 'action':
case 'locationassignment':
case 'innerHTML': # Check our post-char position for = as well (could be equality
# test rather than assignment, i.e. == )
if ( ! isset($input[$postCharPos]) || $input[$postCharPos] == '=' ) {
break;
} # Find the end of this statement
$endPos = analyze_js($input, $postCharPos);
$valueLength = $endPos - $postCharPos; # Produce replacement command
$replacement = sprintf('parse%s(%s)', $command=='innerHTML' ? 'HTML' : 'URL', substr($input, $postCharPos, $valueLength));
# Adjust total document length as appropriate
$length += strlen($replacement);
# Make the replacement
$input = substr_replace($input, $replacement, $postCharPos, $valueLength);
# Move offset up to new position
$offset = $endPos + 10;
# Go get next match
continue 2;
# Function calls - we don't know for certain if these are in fact members of the
# appropriate objects (window/XMLHttpRequest for .open(), document for .write() and
# .writeln) so we won't change anything. Main.js still overrides these functions but
# does nothing with them by default. We add an extra parameter to tell our override
# to kick in.
case 'open':
case 'write':
case 'writeln':
# Find the end position (the closing ")" for the function call)
$endPos = analyze_js($input, $postCharPos);
# Insert our additional argument just before that
$input = substr_replace($input, ',"gl"', $endPos, 0);
# Adjust the document length
$length += 5;
# And move the offset
$offset = $endPos + 5;
# Get next match
continue 2;
# Eval() is a just as easy since we can just wrap the entire thing in parseJS().
case 'eval':
# Ensure this is a call to eval(), not anotherfunctionendingineval()
if ( isset($input[$commandPos-1]) && strpos('abcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_', $input[$commandPos-1]) !== false ) {
break;
}
# Find the end position (the closing ")" for the function call)
$endPos = analyze_js($input, $postCharPos);
$valueLength = $endPos - $postCharPos;
# Generate our replacement
$replacement = sprintf('parseJS(%s)', substr($input, $postCharPos, $valueLength));
# Make the replacement
$input = substr_replace($input, $replacement, $postCharPos, $valueLength);
# Adjust the document length
$length += 9;
# And move the offset
$offset = $endPos + 9;
continue 2;
# location.replace() is a tricky one. We have the position of the char
# after . as $postCharPos and need to ensure we're calling replace(),
# then parse the entire URL
case 'locationreplace()': # Validate the match
if ( ! preg_match('#\Greplace\s*\(#', $input, $tmp, 0, $postCharPos) ) {
break;
}