... block? if (is_array($token) && $token[0] == T_INLINE_HTML) { $inline_html = $token[1]; // T_INLINE_HTML blocks can be split. Need to handle the case // where one token has "expr_append($inline_html); } // Note: This approach won't catch }i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { $last_match = array_pop($matches[0]); if (is_array($last_match)) { $closing_script_pos = $last_match[1]; } else { $closing_script_pos = $last_match; } } if (preg_match('{]*>}i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { $last_match = array_pop($matches[0]); if (is_array($last_match)) { $opening_script_pos = $last_match[1]; } else { $opening_script_pos = $last_match; } } if ($opening_script_pos != $closing_script_pos) { $in_script_block = $opening_script_pos > $closing_script_pos; } } // Look and report each instance of < ? = ... ? > if (!is_array($token)) { // A single char token, e.g: ; ( ) if ($frame) { $frame->expr_append($token); } } else if ($token[0] == T_OPEN_TAG_WITH_ECHO) { // No need for a stack here - assume < ? = cannot be nested. $frame = self::_create_frame($token, $in_script_block); } else if ($frame && $token[0] == T_CLOSE_TAG) { // Store the < ? = ... ? > block that just ended here. $found[$view][] = $frame; $frame = null; } else if ($frame && $token[0] == T_VARIABLE) { $frame->expr_append($token[1]); } else if ($frame && $token[0] == T_STRING) { $frame->expr_append($token[1]); // t() and t2() are special in that they're guaranteed to return a SafeString(). if (in_array($token[1], array("t", "t2"))) { if (self::_token_matches("(", $tokens, $token_number + 1)) { $frame->is_safestring(true); $frame->expr_append("("); $token_number++; $token = $tokens[$token_number]; } } else if ($token[1] == "SafeString") { // Looking for SafeString::of(... if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && in_array($tokens[$token_number + 2][1], array("of", "of_safe_html", "purify")) && self::_token_matches("(", $tokens, $token_number + 3)) { $frame->is_safestring(true); $method = $tokens[$token_number + 2][1]; $frame->expr_append("::$method("); $token_number += 3; $token = $tokens[$token_number]; } } else if ($token[1] == "json_encode") { if (self::_token_matches("(", $tokens, $token_number + 1)) { $frame->json_encode_called(true); $frame->expr_append("("); $token_number++; $token = $tokens[$token_number]; } } else if ($token[1] == "url") { // url methods return a SafeString if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && in_array($tokens[$token_number + 2][1], array("site", "current", "base", "file", "abs_site", "abs_current", "abs_file", "merge")) && self::_token_matches("(", $tokens, $token_number + 3)) { $frame->is_safestring(true); $method = $tokens[$token_number + 2][1]; $frame->expr_append("::$method("); $token_number += 3; $token = $tokens[$token_number]; } } } else if ($frame && $token[0] == T_OBJECT_OPERATOR) { $frame->expr_append($token[1]); if (self::_token_matches(array(T_STRING), $tokens, $token_number + 1) && in_array($tokens[$token_number + 1][1], array("for_js", "for_html", "purified_html")) && self::_token_matches("(", $tokens, $token_number + 2)) { $method = $tokens[$token_number + 1][1]; $frame->expr_append("$method("); $token_number += 2; $token = $tokens[$token_number]; if ("for_js" == $method) { $frame->for_js_called(true); } else if ("for_html" == $method) { $frame->for_html_called(true); } else if ("purified_html" == $method) { $frame->purified_html_called(true); } } } else if ($frame) { $frame->expr_append($token[1]); } } } /* * Generate the report * * States for uses of < ? = X ? >: * JS_XSS: * In