From f77b0e6d2d428ce9bef135f94120f6ee092f4d45 Mon Sep 17 00:00:00 2001 From: zhujinyong Date: Thu, 11 Nov 2021 05:10:38 +0800 Subject: [PATCH] * Check compatibility. --- lib/api/api.class.php | 41 ++++-- lib/snoopy/snoopy.class.php | 278 +++++++++++++++++++----------------- module/story/control.php | 6 +- 3 files changed, 174 insertions(+), 151 deletions(-) diff --git a/lib/api/api.class.php b/lib/api/api.class.php index 9eed7f471e..b5145945ee 100755 --- a/lib/api/api.class.php +++ b/lib/api/api.class.php @@ -495,7 +495,7 @@ class Snoopy $frameurls = $this->_frameurls; $this->_frameurls = array(); - while(list(,$frameurl) = each($frameurls)) + foreach($frameurls as $frameurl) { if($this->_framedepth < $this->maxframes) { @@ -503,7 +503,9 @@ class Snoopy $this->_framedepth++; } else + { break; + } } } return true; @@ -593,7 +595,7 @@ class Snoopy $frameurls = $this->_frameurls; $this->_frameurls = array(); - while(list(,$frameurl) = each($frameurls)) + foreach($frameurls as $frameurl) { if($this->_framedepth < $this->maxframes) { @@ -660,7 +662,7 @@ class Snoopy $frameurls = $this->_frameurls; $this->_frameurls = array(); - while(list(,$frameurl) = each($frameurls)) + foreach($frameurls as $frameurl) { if($this->_framedepth < $this->maxframes) { @@ -881,13 +883,13 @@ class Snoopy // catenate the non-empty matches from the conditional subpattern - while(list($key,$val) = each($links[2])) + foreach($links[2] as $key => $val) { if(!empty($val)) $match[] = $val; } - while(list($key,$val) = each($links[3])) + foreach($links[3] as $key => $val) { if(!empty($val)) $match[] = $val; @@ -1072,9 +1074,13 @@ class Snoopy if(!empty($this->rawheaders)) { if(!is_array($this->rawheaders)) + { $this->rawheaders = (array)$this->rawheaders; - while(list($headerKey,$headerVal) = each($this->rawheaders)) + } + foreach($this->rawheaders as $headerKey => $headerVal) + { $headers .= $headerKey.": ".$headerVal."\r\n"; + } } if(!empty($content_type)) { $headers .= "Content-type: $content_type"; @@ -1236,9 +1242,13 @@ class Snoopy if(!empty($this->rawheaders)) { if(!is_array($this->rawheaders)) + { $this->rawheaders = (array)$this->rawheaders; - while(list($headerKey,$headerVal) = each($this->rawheaders)) + } + foreach($this->rawheaders as $headerKey => $headerVal) + { $headers[] = $headerKey.": ".$headerVal; + } } if(!empty($content_type)) { if ($content_type == "multipart/form-data") @@ -1453,13 +1463,17 @@ class Snoopy switch ($this->_submit_type) { case "application/x-www-form-urlencoded": reset($formvars); - while(list($key,$val) = each($formvars)) { + foreach($formvars as $key => $val) + { if (is_array($val) || is_object($val)) { - while (list($cur_key, $cur_val) = each($val)) { + foreach($val as $cur_key => $cur_val) + { $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&"; } } else + { $postdata .= urlencode($key)."=".urlencode($val)."&"; + } } break; @@ -1467,9 +1481,10 @@ class Snoopy $this->_mime_boundary = "Snoopy".md5(uniqid(microtime())); reset($formvars); - while(list($key,$val) = each($formvars)) { + foreach($formvars as $key => $val) + { if (is_array($val) || is_object($val)) { - while (list($cur_key, $cur_val) = each($val)) { + foreach($val as $cur_key => $cur_val) { $postdata .= "--".$this->_mime_boundary."\r\n"; $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n"; $postdata .= "$cur_val\r\n"; @@ -1482,9 +1497,9 @@ class Snoopy } reset($formfiles); - while (list($field_name, $file_names) = each($formfiles)) { + foreach($formfiles as $field_name => $file_names) { settype($file_names, "array"); - while (list(, $file_name) = each($file_names)) { + foreach($file_names as $file_name) { if (!is_readable($file_name)) continue; $fp = fopen($file_name, "r"); diff --git a/lib/snoopy/snoopy.class.php b/lib/snoopy/snoopy.class.php index d5d7c2ce76..437affd6e2 100644 --- a/lib/snoopy/snoopy.class.php +++ b/lib/snoopy/snoopy.class.php @@ -59,15 +59,15 @@ class Snoopy var $passcookies = true; // pass set cookies back through redirects // NOTE: this currently does not respect // dates, domains or paths. - + var $user = ""; // user for http authentication var $pass = ""; // password for http authentication - + // http accept types var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; - + var $results = ""; // where the content is put - + var $error = ""; // error messages sent here var $response_code = ""; // response code returned from server var $headers = array(); // headers returned from server sent here @@ -93,11 +93,11 @@ class Snoopy // library functions built into php, // as these functions are not stable // as of this Snoopy release. - - /**** Private variables ****/ - + + /**** Private variables ****/ + var $_maxlinelen = 4096; // max line length (headers) - + var $_httpmethod = "GET"; // default http request method var $_httpversion = "HTTP/1.0"; // default http request version var $_submit_method = "POST"; // default submit method @@ -107,7 +107,7 @@ class Snoopy var $_redirectdepth = 0; // increments on an http redirect var $_frameurls = array(); // frame src urls var $_framedepth = 0; // increments on frame depth - + var $_isproxy = false; // set if using a proxy server var $_fp_timeout = 30; // timeout for socket connection @@ -122,7 +122,7 @@ class Snoopy function fetch($URI) { - + //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS); $URI_PARTS = parse_url($URI); if (!empty($URI_PARTS["user"])) @@ -133,7 +133,7 @@ class Snoopy $URI_PARTS["query"] = ''; if (empty($URI_PARTS["path"])) $URI_PARTS["path"] = ''; - + switch(strtolower($URI_PARTS["scheme"])) { case "http": @@ -153,7 +153,7 @@ class Snoopy // no proxy, send only the path $this->_httprequest($path, $fp, $URI, $this->_httpmethod); } - + $this->_disconnect($fp); if($this->_redirectaddr) @@ -176,8 +176,8 @@ class Snoopy { $frameurls = $this->_frameurls; $this->_frameurls = array(); - - while(list(,$frameurl) = each($frameurls)) + + foreach($frameurls as $frameurl) { if($this->_framedepth < $this->maxframes) { @@ -187,13 +187,13 @@ class Snoopy else break; } - } + } } else { return false; } - return true; + return true; break; case "https": if(!$this->curl_path) @@ -237,7 +237,7 @@ class Snoopy $frameurls = $this->_frameurls; $this->_frameurls = array(); - while(list(,$frameurl) = each($frameurls)) + foreach($frameurls as $frameurl) { if($this->_framedepth < $this->maxframes) { @@ -247,15 +247,15 @@ class Snoopy else break; } - } - return true; + } + return true; break; default: // not a valid protocol $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; return false; break; - } + } return true; } @@ -273,9 +273,9 @@ class Snoopy function submit($URI, $formvars="", $formfiles="") { unset($postdata); - + $postdata = $this->_prepare_post_body($formvars, $formfiles); - + $URI_PARTS = parse_url($URI); if (!empty($URI_PARTS["user"])) $this->user = $URI_PARTS["user"]; @@ -305,17 +305,17 @@ class Snoopy // no proxy, send only the path $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata); } - + $this->_disconnect($fp); if($this->_redirectaddr) { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) - { + { if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) - $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); - + $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); + // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) { @@ -334,9 +334,9 @@ class Snoopy { $frameurls = $this->_frameurls; $this->_frameurls = array(); - - while(list(,$frameurl) = each($frameurls)) - { + + foreach($frameurls as $frameurl) + { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); @@ -345,14 +345,14 @@ class Snoopy else break; } - } - + } + } else { return false; } - return true; + return true; break; case "https": if(!$this->curl_path) @@ -379,9 +379,9 @@ class Snoopy { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) - { + { if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) - $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); + $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) @@ -402,8 +402,8 @@ class Snoopy $frameurls = $this->_frameurls; $this->_frameurls = array(); - while(list(,$frameurl) = each($frameurls)) - { + foreach($frameurls as $frameurl) + { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); @@ -412,16 +412,16 @@ class Snoopy else break; } - } - return true; + } + return true; break; - + default: // not a valid protocol $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; return false; break; - } + } return true; } @@ -435,7 +435,7 @@ class Snoopy function fetchlinks($URI) { if ($this->fetch($URI)) - { + { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) @@ -463,9 +463,9 @@ class Snoopy function fetchform($URI) { - + if ($this->fetch($URI)) - { + { if(is_array($this->results)) { @@ -474,14 +474,14 @@ class Snoopy } else $this->results = $this->_stripform($this->results); - + return true; } else return false; } - - + + /*======================================================================*\ Function: fetchtext Purpose: fetch the text from a web page, stripping the links @@ -492,7 +492,7 @@ class Snoopy function fetchtext($URI) { if($this->fetch($URI)) - { + { if(is_array($this->results)) { for($x=0;$xresults);$x++) @@ -516,7 +516,7 @@ class Snoopy function submitlinks($URI, $formvars="", $formfiles="") { if($this->submit($URI,$formvars, $formfiles)) - { + { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) @@ -550,7 +550,7 @@ class Snoopy function submittext($URI, $formvars = "", $formfiles = "") { if($this->submit($URI,$formvars, $formfiles)) - { + { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) @@ -574,7 +574,7 @@ class Snoopy return false; } - + /*======================================================================*\ Function: set_submit_multipart @@ -586,7 +586,7 @@ class Snoopy $this->_submit_type = "multipart/form-data"; } - + /*======================================================================*\ Function: set_submit_normal Purpose: Set the form submission content type to @@ -597,14 +597,14 @@ class Snoopy $this->_submit_type = "application/x-www-form-urlencoded"; } - - + + /*======================================================================*\ Private functions \*======================================================================*/ - - + + /*======================================================================*\ Function: _striplinks Purpose: strip the hyperlinks from an html document @@ -613,28 +613,28 @@ class Snoopy \*======================================================================*/ function _striplinks($document) - { + { preg_match_all("'<\s*a\s.*?href\s*=\s* # find ]+)) # if quote found, match up to next matching # quote, otherwise match up to next space 'isx",$document,$links); - + // catenate the non-empty matches from the conditional subpattern - while(list($key,$val) = each($links[2])) + foreach($links[2] as $key => $val) { if(!empty($val)) $match[] = $val; - } - - while(list($key,$val) = each($links[3])) + } + + foreach($links[3] as $key => $val) { if(!empty($val)) $match[] = $val; - } - + } + // return the links return $match; } @@ -647,18 +647,18 @@ class Snoopy \*======================================================================*/ function _stripform($document) - { + { preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements); - + // catenate the matches $match = implode("\r\n",$elements[0]); - + // return the links return $match; } - - + + /*======================================================================*\ Function: _striptext Purpose: strip the text from an html document @@ -668,11 +668,11 @@ class Snoopy function _striptext($document) { - + // I didn't use preg eval (//e) since that is only available in PHP 4.0. // so, list your entities one by one here. I included some of the // more common ones. - + $search = array("']*?>.*?'si", // strip out javascript "'<[\/\!]*?[^<>]*?>'si", // strip out html tags "'([\r\n])[\s]+'", // strip out white space @@ -721,9 +721,9 @@ class Snoopy "", "", ); - + $text = preg_replace($search,$replace,$document); - + return $text; } @@ -737,7 +737,7 @@ class Snoopy function _expandlinks($links,$URI) { - + preg_match("/^[^\?]+/",$URI,$match); $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]); @@ -745,21 +745,21 @@ class Snoopy $match_part = parse_url($match); $match_root = $match_part["scheme"]."://".$match_part["host"]; - + $search = array( "|^http://".preg_quote($this->host)."|i", "|^(\/)|i", "|^(?!http://)(?!mailto:)|i", "|/\./|", "|/[^\/]+/\.\./|" ); - + $replace = array( "", $match_root."/", $match."/", "/", "/" - ); - + ); + $expandedLinks = preg_replace($search,$replace,$links); return $expandedLinks; @@ -772,19 +772,19 @@ class Snoopy $fp the current open file pointer $URI the full URI $body body contents to send if any (POST) - Output: + Output: \*======================================================================*/ - + function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="") { $cookie_headers = ''; if($this->passcookies && $this->_redirectaddr) $this->setcookies(); - + $URI_PARTS = parse_url($URI); if(empty($url)) $url = "/"; - $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; + $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; if(!empty($this->agent)) $headers .= "User-Agent: ".$this->agent."\r\n"; if(!empty($this->host) && !isset($this->rawheaders['Host'])) { @@ -798,10 +798,10 @@ class Snoopy if(!empty($this->referer)) $headers .= "Referer: ".$this->referer."\r\n"; if(!empty($this->cookies)) - { + { if(!is_array($this->cookies)) $this->cookies = (array)$this->cookies; - + reset($this->cookies); if ( count($this->cookies) > 0 ) { $cookie_headers .= 'Cookie: '; @@ -809,14 +809,18 @@ class Snoopy $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; "; } $headers .= substr($cookie_headers,0,-2) . "\r\n"; - } + } } if(!empty($this->rawheaders)) { if(!is_array($this->rawheaders)) + { $this->rawheaders = (array)$this->rawheaders; - while(list($headerKey,$headerVal) = each($this->rawheaders)) + } + foreach($this->rawheaders as $headerKey =>$headerVal) + { $headers .= $headerKey.": ".$headerVal."\r\n"; + } } if(!empty($content_type)) { $headers .= "Content-type: $content_type"; @@ -824,28 +828,28 @@ class Snoopy $headers .= "; boundary=".$this->_mime_boundary; $headers .= "\r\n"; } - if(!empty($body)) + if(!empty($body)) $headers .= "Content-length: ".strlen($body)."\r\n"; - if(!empty($this->user) || !empty($this->pass)) + if(!empty($this->user) || !empty($this->pass)) $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n"; - + //add proxy auth headers - if(!empty($this->proxy_user)) + if(!empty($this->proxy_user)) $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n"; $headers .= "\r\n"; - + // set the read timeout if needed if ($this->read_timeout > 0) socket_set_timeout($fp, $this->read_timeout); $this->timed_out = false; - + fwrite($fp,$headers.$body,strlen($headers.$body)); - + $this->_redirectaddr = false; unset($this->headers); - + while($currentHeader = fgets($fp,$this->_maxlinelen)) { if ($this->read_timeout > 0 && $this->_check_timeout($fp)) @@ -853,10 +857,10 @@ class Snoopy $this->status=-100; return false; } - + if($currentHeader == "\r\n") break; - + // if a header begins with Location: or URI:, set the redirect if(preg_match("/^(Location:|URI:)/i",$currentHeader)) { @@ -876,16 +880,16 @@ class Snoopy else $this->_redirectaddr = $matches[2]; } - + if(preg_match("|^HTTP/|",$currentHeader)) { if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status)) { $this->status= $status[1]; - } + } $this->response_code = $currentHeader; } - + $this->headers[] = $currentHeader; } @@ -903,12 +907,12 @@ class Snoopy $this->status=-100; return false; } - + // check if there is a a redirect meta tag - + if(preg_match("/']*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?" . ">'/i",$results,$match)) { - $this->_redirectaddr = $this->_expandlinks($match[1],$URI); + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); } // have we hit our frame depth and is there frame src to fetch? @@ -924,7 +928,7 @@ class Snoopy // no framed content else $this->results = $results; - + return true; } @@ -934,21 +938,21 @@ class Snoopy Input: $url the url to fetch $URI the full URI $body body contents to send if any (POST) - Output: + Output: \*======================================================================*/ - + function _httpsrequest($url,$URI,$http_method,$content_type="",$body="") - { + { if($this->passcookies && $this->_redirectaddr) $this->setcookies(); - $headers = array(); - + $headers = array(); + $URI_PARTS = parse_url($URI); if(empty($url)) $url = "/"; // GET ... header not needed for curl - //$headers[] = $http_method." ".$url." ".$this->_httpversion; + //$headers[] = $http_method." ".$url." ".$this->_httpversion; if(!empty($this->agent)) $headers[] = "User-Agent: ".$this->agent; if(!empty($this->host)) @@ -961,10 +965,10 @@ class Snoopy if(!empty($this->referer)) $headers[] = "Referer: ".$this->referer; if(!empty($this->cookies)) - { + { if(!is_array($this->cookies)) $this->cookies = (array)$this->cookies; - + reset($this->cookies); if ( count($this->cookies) > 0 ) { $cookie_str = 'Cookie: '; @@ -977,9 +981,13 @@ class Snoopy if(!empty($this->rawheaders)) { if(!is_array($this->rawheaders)) + { $this->rawheaders = (array)$this->rawheaders; - while(list($headerKey,$headerVal) = each($this->rawheaders)) + } + foreach($this->rawheaders as $headerKey => $headerVal) + { $headers[] = $headerKey.": ".$headerVal; + } } if(!empty($content_type)) { if ($content_type == "multipart/form-data") @@ -987,11 +995,11 @@ class Snoopy else $headers[] = "Content-type: $content_type"; } - if(!empty($body)) + if(!empty($body)) $headers[] = "Content-length: ".strlen($body); - if(!empty($this->user) || !empty($this->pass)) + if(!empty($this->user) || !empty($this->pass)) $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass); - + if(!extension_loaded('curl')) { @@ -1105,10 +1113,10 @@ class Snoopy // check if there is a a redirect meta tag - + if(preg_match("/']*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?" . ">'/i",$results,$match)) { - $this->_redirectaddr = $this->_expandlinks($match[1],$URI); + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); } // have we hit our frame depth and is there frame src to fetch? @@ -1125,7 +1133,7 @@ class Snoopy else $this->results = $results; - + return true; } @@ -1133,7 +1141,7 @@ class Snoopy Function: setcookies() Purpose: set cookies for a redirection \*======================================================================*/ - + function setcookies() { for($x=0; $xheaders); $x++) @@ -1143,7 +1151,7 @@ class Snoopy } } - + /*======================================================================*\ Function: _check_timeout Purpose: checks whether timeout has occurred @@ -1167,13 +1175,13 @@ class Snoopy Purpose: make a socket connection Input: $fp file pointer \*======================================================================*/ - + function _connect(&$fp) { if(!empty($this->proxy_host) && !empty($this->proxy_port)) { $this->_isproxy = true; - + $host = $this->proxy_host; $port = $this->proxy_port; } @@ -1182,9 +1190,9 @@ class Snoopy $host = $this->host; $port = $this->port; } - + $this->status = 0; - + if($fp = fsockopen( $host, $port, @@ -1220,13 +1228,13 @@ class Snoopy Purpose: disconnect a socket connection Input: $fp file pointer \*======================================================================*/ - + function _disconnect($fp) { return(fclose($fp)); } - + /*======================================================================*\ Function: _prepare_post_body Purpose: Prepare post body according to encoding type @@ -1234,7 +1242,7 @@ class Snoopy $formfiles - form upload files Output: post body \*======================================================================*/ - + function _prepare_post_body($formvars, $formfiles) { settype($formvars, "array"); @@ -1243,13 +1251,13 @@ class Snoopy if (count($formvars) == 0 && count($formfiles) == 0) return; - + switch ($this->_submit_type) { case "application/x-www-form-urlencoded": reset($formvars); - while(list($key,$val) = each($formvars)) { + foreach($formvars as $key => $val) { if (is_array($val) || is_object($val)) { - while (list($cur_key, $cur_val) = each($val)) { + foreach($val as $cur_key => $cur_val) { $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&"; } } else @@ -1259,11 +1267,11 @@ class Snoopy case "multipart/form-data": $this->_mime_boundary = "Snoopy".md5(uniqid(microtime())); - + reset($formvars); - while(list($key,$val) = each($formvars)) { + foreach($formvars as $key => $val) { if (is_array($val) || is_object($val)) { - while (list($cur_key, $cur_val) = each($val)) { + foreach($val as $cur_key => $cur_val) { $postdata .= "--".$this->_mime_boundary."\r\n"; $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n"; $postdata .= "$cur_val\r\n"; @@ -1274,11 +1282,11 @@ class Snoopy $postdata .= "$val\r\n"; } } - + reset($formfiles); - while (list($field_name, $file_names) = each($formfiles)) { + foreach($formfiles as $field_name => $file_names) { settype($file_names, "array"); - while (list(, $file_name) = each($file_names)) { + foreach($file_names as $file_name) { if (!is_readable($file_name)) continue; $fp = fopen($file_name, "r"); diff --git a/module/story/control.php b/module/story/control.php index ec4f979d37..46d3a21642 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -1828,7 +1828,7 @@ class story extends control if($executionID) { - $stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type); + $stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type); } else { @@ -1920,7 +1920,7 @@ class story extends control $storyInfo['moduleID'] = $story->module; $storyInfo['estimate'] = $story->estimate; $storyInfo['pri'] = $story->pri; - $storyInfo['spec'] = html_entity_decode($story->spec); + $storyInfo['spec'] = html_entity_decode($story->spec, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8'); echo json_encode($storyInfo); } @@ -2209,7 +2209,7 @@ class story extends control $story->reviewedBy = rtrim($story->reviewedBy, ','); /* Set child story title. */ - if($story->parent > 0 && strpos($story->title, htmlentities('>')) !== 0) $story->title = '>' . $story->title; + if($story->parent > 0 && strpos($story->title, htmlentities('>'), ENT_COMPAT | ENT_HTML401, 'UTF-8') !== 0) $story->title = '>' . $story->title; } if($executionID)