/** * Checks a CSS style sheet. * * @param string The data of the style sheet * @return ?map Error information (NULL: no error) */ function _validate_css_sheet($data) { global $CSS_TAG_RANGES, $CSS_VALUE_RANGES, $VALIDATED_ALREADY; $CSS_TAG_RANGES = array(); $CSS_VALUE_RANGES = array(); $errors = array(); $len = strlen($data); $status = CSS_NO_MANS_LAND; $line = 0; $class_before_comment = NULL; $class = ''; $at_rule = ''; $at_rule_block = ''; //$left_no_mans_land_once=false; $brace_level = 0; $i = 0; $class_start_line = NULL; $class_start_i = NULL; $class_name = ''; $in_comment = false; $quoting = false; while ($i < $len) { $next = $data[$i]; $val = ord($next); if ($next == '_' || $next == '.' || $next == '-' || $val >= 65 && $val <= 90 || $val >= 97 && $val <= 122 || $val >= 48 && $val <= 57) { $alpha_numeric = true; $whitespace = false; $comment_starting = false; } else { $alpha_numeric = false; $whitespace = $next == "\t" || $val == 13 || $val == 10 || $next == ' '; $comment_starting = $next == '/' && $i < $len - 2 && $data[$i + 1] == '*'; } switch ($status) { case CSS_AT_RULE: if ($next == '{') { $brace_level = 0; $status = CSS_AT_RULE_BLOCK; $at_rule_block = ''; } elseif ($next == ';') { $status = CSS_NO_MANS_LAND; if (substr($at_rule, 0, 6) == 'import ') { $count = substr_count($at_rule, '"'); $first = strpos($at_rule, '"') + 1; if ($count < 2) { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER', 1 => $next, 2 => number_format($line), 'pos' => $i); return $errors; } $at_file = substr($at_rule, $first, strpos($at_rule, '"', $first) - 1 - $first); if (!isset($VALIDATED_ALREADY[$at_file])) { $at_file = qualify_url($at_file, $GLOBALS['URL_BASE']); if ($at_file != '') { $data2 = http_download_file($at_file, NULL, false); if (!is_null($data2)) { $css_tag_ranges_backup = $CSS_TAG_RANGES; $css_value_ranges_backup = $CSS_VALUE_RANGES; $test = _validate_css_sheet($data2); $CSS_TAG_RANGES = $css_tag_ranges_backup; $CSS_VALUE_RANGES = $css_value_ranges_backup; if (is_array($test)) { foreach ($test as $error) { $error['pos'] = $i; $errors[] = $error; } } } } } } } else { $at_rule .= $next; } break; case CSS_AT_RULE_BLOCK: if ($next == '{') { ++$brace_level; $at_rule_block .= $next; } elseif ($next == '}' && $brace_level == 0) { $status = CSS_NO_MANS_LAND; if (substr($at_rule, 0, 6) == 'media ') { $css_tag_ranges_backup = $CSS_TAG_RANGES; $css_value_ranges_backup = $CSS_VALUE_RANGES; $test = _validate_css_sheet($at_rule_block); $CSS_TAG_RANGES = $css_tag_ranges_backup; $CSS_VALUE_RANGES = $css_value_ranges_backup; if (is_array($test)) { foreach ($test as $error) { $error['pos'] = $i; $errors[] = $error; } } } } elseif ($next == '}') { $brace_level--; $at_rule_block .= $next; } else { $at_rule_block .= $next; } break; case CSS_NO_MANS_LAND: if ($whitespace) { // Continuing } elseif ($next == '.' || $next == '#' || $alpha_numeric) { $status = CSS_IN_CLASS_NAME; $class_name = ''; //$left_no_mans_land_once=true; } elseif ($next == '@') { $status = CSS_AT_RULE; $at_rule = ''; } elseif ($comment_starting) { $status = CSS_IN_COMMENT; $class_before_comment = CSS_NO_MANS_LAND; } elseif ($next == '*') { $status = CSS_IN_CLASS_NAME; $class_name = '*'; //$left_no_mans_land_once=true; } else { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER', 1 => $next, 2 => number_format($line), 'pos' => $i); // return $errors; } break; case CSS_EXPECTING_CLASS_NAME: if ($comment_starting) { $status = CSS_IN_COMMENT; $class_before_comment = CSS_EXPECTING_CLASS_NAME; } elseif ($whitespace) { // Continuing } elseif ($next == '*') { $status = CSS_IN_CLASS_NAME; $class_name = '*'; } elseif ($next == '.' || $next == '#' || $alpha_numeric) { $status = CSS_IN_CLASS_NAME; $class_name = $alpha_numeric ? $next : ''; } else { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER', 1 => $next, 2 => number_format($line), 'pos' => $i); // return $errors; } break; case CSS_IN_COMMENT: if ($next == '*' && $i != $len - 2 && $data[$i + 1] == '/') { $status = $class_before_comment; ++$i; } break; case CSS_IN_CLASS_NAME: if ($alpha_numeric || $next == ':' || $next == '#') { $class_name .= $next; } else { // Test class name $cnt = substr_count($class_name, ':'); if ($cnt > 0) { $pseudo = substr($class_name, strpos($class_name, ':') + 1); if ($GLOBALS['VALIDATION_COMPAT'] && !in_array($pseudo, array('active', 'hover', 'link', 'visited', 'first-letter', 'first-line'))) { $errors[] = array(0 => 'CSS_BAD_PSEUDO_CLASS', 1 => $pseudo, 'pos' => $i); } } if ($whitespace) { $status = CSS_EXPECTING_SEP_OR_CLASS_NAME_OR_CLASS; } elseif ($next == '>') { $status = CSS_EXPECTING_CLASS_NAME; if ($GLOBALS['VALIDATION_COMPAT']) { $errors[] = array(0 => 'CSS_BAD_SELECTOR', 1 => '>', 'pos' => $i); } } elseif ($next == ',') { $status = CSS_EXPECTING_CLASS_NAME; } elseif ($next == '{') { $status = CSS_IN_CLASS; $class_start_line = $line; $class_start_i = $i; $class = ''; } else { $matches = array(); if ($next == '[' && preg_match('#\\[(\\w+|)?\\w+([$*~|^]?="[^;"]*")?\\]#', substr($data, $i, 50), $matches)) { if ($GLOBALS['VALIDATION_COMPAT']) { $errors[] = array(0 => 'CSS_BAD_SELECTOR', 1 => '(attribute-selectors)', 'pos' => $i); } $i += strlen($matches[0]) - 1; } else { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER', 1 => $next, 2 => number_format($line), 'pos' => $i); // return $errors; } } } break; case CSS_EXPECTING_SEP_OR_CLASS_NAME_OR_CLASS: if ($next == '{') { $status = CSS_IN_CLASS; $class_start_line = $line; $class_start_i = $i; $class = ''; } elseif ($whitespace || $next == '*') { // Continuing } elseif ($comment_starting) { $status = CSS_IN_COMMENT; $class_before_comment = CSS_EXPECTING_SEP_OR_CLASS_NAME_OR_CLASS; } elseif ($next == ',' || $next == '>') { $status = CSS_EXPECTING_CLASS_NAME; } elseif ($next == '.' || $next == '#' || $alpha_numeric) { $status = CSS_IN_CLASS_NAME; $class_name = ''; } else { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER', 1 => $next, 2 => number_format($line), 'pos' => $i); // return $errors; } break; case CSS_IN_CLASS: if ($quoting) { if (($next == '"' || $next == "'") && $data[$i - 1] != "\\") { $quoting = !$quoting; } $class .= $next; } elseif ($in_comment) { $comment_ending = $next == '*' && $i < $len - 2 && $data[$i + 1] == '/'; if ($comment_ending) { $in_comment = false; } $class .= $next; } elseif ($next == '}') { $status = CSS_NO_MANS_LAND; $test = _validate_css_class($class, $class_start_i, $class_start_line + 1); if (is_array($test)) { $errors = array_merge($errors, $test); } } elseif ($comment_starting) { $in_comment = true; $class .= $next; } elseif (($next == '"' || $next == "'") && $data[$i - 1] != "\\") { $quoting = true; $class .= $next; } elseif ($next == '{') { $errors[] = array(0 => 'CSS_UNEXPECTED_CHARACTER_CLASS', 1 => $next, 2 => number_format($line), 'pos' => $i); return $errors; } else { $class .= $next; } break; } if ($val == 10) { ++$line; } ++$i; } if ($status != CSS_NO_MANS_LAND) { $errors[] = array(0 => 'CSS_UNEXPECTED_TERMINATION', 'pos' => $i); return $errors; } return $errors == array() ? NULL : $errors; }
/** * Take a URL and process it to make a hard include. We'll get the HTML and we'll also load up some global stuff for 'do_header' to use. * * @param URLPATH The URL that we're operating on. * @param URLPATH We open up linked URLs under this recursively. * @return string The cleaned up contents at the URL, set up for the recursive integrator usage. */ function reprocess_url($url, $operation_base_url) { if (url_is_local($url)) { return ''; } $trail_end = strrpos($url, '/'); if ($trail_end !== false) { $url_base = substr($url, 0, $trail_end); } $val = mixed(); // Cookie relaying from client through to server $url_bits = @parse_url($url) or warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_NO_SERVER', $url)); $url_bits_2 = parse_url(get_base_url()); $cookies_relayed = NULL; if (!array_key_exists('host', $url_bits)) { $url_bits['host'] = 'localhost'; } if (!array_key_exists('host', $url_bits_2)) { $url_bits_2['host'] = 'localhost'; } if ($url_bits['host'] == $url_bits_2['host']) { $cookies_relayed = array(); foreach ($_COOKIE as $key => $val) { if (is_array($val)) { $cookies_relayed[$key] = array(); foreach ($val as $_val) { if (get_magic_quotes_gpc()) { $_val = stripslashes($_val); } $cookies_relayed[$key][] = $_val; } } else { if (get_magic_quotes_gpc()) { $val = stripslashes($val); } $cookies_relayed[$key] = $val; } } } // Download the document $ua = ocp_srv('HTTP_USER_AGENT'); if ($ua == '') { $ua = 'ocP-integrator'; } $accept = ocp_srv('HTTP_ACCEPT'); if ($accept == '') { $accept = NULL; } $accept_charset = ocp_srv('HTTP_ACCEPT_CHARSET'); if ($accept_charset == '') { $accept_charset = NULL; } $accept_language = ocp_srv('HTTP_ACCEPT_LANGUAGE'); if ($accept_language == '') { $accept_language = NULL; } $post_relayed = NULL; if (count($_POST) != 0) { $post_relayed = array(); foreach ($_POST as $key => $val) { if (is_array($val)) { $post_relayed[$key] = array(); foreach ($val as $_val) { if (get_magic_quotes_gpc()) { $_val = stripslashes($_val); } $post_relayed[$key] = $val; } } else { if (get_magic_quotes_gpc()) { $val = stripslashes($val); } $post_relayed[$key] = $val; } } } require_code('character_sets'); $document = convert_to_internal_encoding(http_download_file($url, NULL, true, false, $ua, $post_relayed, $cookies_relayed, $accept, $accept_charset, $accept_language)); global $HTTP_DOWNLOAD_MIME_TYPE; if ($HTTP_DOWNLOAD_MIME_TYPE != 'text/html' && $HTTP_DOWNLOAD_MIME_TYPE != 'application/xhtml+xml') { header('Location: ' . str_replace("\r", '', str_replace(chr(10), '', $url))); return ''; } // Were we asked to set any cookies? if ($url_bits['host'] == $url_bits_2['host']) { global $HTTP_NEW_COOKIES; if (!is_null($HTTP_NEW_COOKIES)) { foreach ($HTTP_NEW_COOKIES as $key => $val) { $parts = explode('; ', $val); foreach ($parts as $i => $part) { if ($i != 0) { $temp = explode('=', $part, 2); if (array_key_exists(1, $temp)) { $parts[trim($temp[0])] = trim(rawurldecode($temp[1])); } } } //$parts['domain']=$url_bits_2['host']; // To fix an inconvenience caused by mismatching cookie settings (e.g. cookie on subdomain) //echo($key.'->'.trim(rawurldecode($parts[0]))); //print_r($parts); //exit(); $parts['domain'] = get_cookie_domain(); setcookie($key, trim(rawurldecode($parts[0])), array_key_exists('expires', $parts) ? strtotime($parts['expires']) : 0, array_key_exists('path', $parts) ? $parts['path'] : '', array_key_exists('domain', $parts) ? $parts['domain'] : ''); } } } // Sort out title $matches = array(); if (preg_match('#<\\s*title[^>]*>(.*)<\\s*/\\s*title\\s*>#is', $document, $matches) != 0) { global $SEO_TITLE; $title = str_replace('•', '-', str_replace('–', '-', str_replace('—', '-', @html_entity_decode($matches[1], ENT_QUOTES, get_charset())))); $SEO_TITLE = $title; get_page_title(trim($title), false); } // Better base? $matches = array(); if (preg_match('#<\\s*base\\s+href\\s*=\\s*["\']?(.*)["\']?\\s*/?\\s*>#is', $document, $matches) != 0) { $url_base = trim(@html_entity_decode($matches[1], ENT_QUOTES, get_charset())); } // Sort out body if (preg_match('#<\\s*body[^>]*>(.*)<\\s*/\\s*body\\s*>#is', $document, $matches) != 0) { $body = '<div>' . $matches[1] . '</div>'; } else { $body = '<div>' . $document . '</div>'; } // Link filtering, so as to make non-external/non-new-window hyperlinks link through the ocPortal module $_self_url = build_url(array('page' => '_SELF'), '_SELF', NULL, false, true); $self_url = $_self_url->evaluate(); $expressions = array('(src)="([^"]*)"', '(src)=\'([^\'])*\'', '(href)="([^"]*)"', '(href)=\'([^\'])*\'', '(data)="([^"]*)"', '(data)=\'([^\']*)\'', '(action)="([^"]*)"', '(action)=\'([^\']*)\''); foreach ($expressions as $expression) { $all_matches = array(); $count = preg_match_all('#(<[^>]*)' . $expression . '([^>]*>)#i', $body, $all_matches); if ($count != 0) { for ($i = 0; $i < count($all_matches[0]); $i++) { $m_to_replace = $all_matches[0][$i]; $m_type = trim(@html_entity_decode($all_matches[2][$i], ENT_QUOTES, get_charset())); $m_url = trim(@html_entity_decode($all_matches[3][$i], ENT_QUOTES, get_charset())); if (url_is_local($m_url)) { $m_url = qualify_url($m_url, $url_base); } $non_local = substr($m_url, 0, strlen($operation_base_url)) != $operation_base_url; if ($m_type == 'src' || $m_type == 'data' || $non_local) { $new_url = $m_url; } else { $new_url = $self_url . '&url=' . rawurlencode($m_url); } $body = str_replace($m_to_replace, $all_matches[1][$i] . $m_type . '="' . escape_html($new_url) . '"' . $all_matches[4][$i], $body); } } } // Moving of CSS sheet imports, etc, into ocPortal's head section if (preg_match('#<head[^<>]*>(.*)</head>#is', $document, $matches) != 0) { $head = $matches[1]; // meta global $SEO_KEYWORDS, $SEO_DESCRIPTION; $count = preg_match_all('#\\<\\s*meta[^\\>]*name=["\']([^"\']*)["\'][^\\>]*content="([^"]*)"[^\\>]*/?\\s*>#i', $head, $all_matches); if ($count == 0) { $count = preg_match_all('#\\<\\s*meta\\s+[^\\>]*name=["\']([^"\']*)["\']\\s+[^\\>]*content=\'([^\']*)\'[^\\>]*/?\\s*>#i', $head, $all_matches); } if ($count != 0) { for ($i = 0; $i < count($all_matches[0]); $i++) { $m_name = trim(@html_entity_decode($all_matches[1][$i], ENT_QUOTES, get_charset())); $m_content = trim(@html_entity_decode($all_matches[2][$i], ENT_QUOTES, get_charset())); if ($m_name == 'description') { $SEO_DESCRIPTION = $m_content; } elseif ($m_name == 'keywords') { $SEO_KEYWORDS = explode(',', $m_content); } } } // Stuff to copy global $EXTRA_HEAD; $head_patterns = array('#<\\s*script.*<\\s*/\\s*script\\s*>#isU', '#<\\s*link[^<>]*>#isU', '#<\\s*style.*<\\s*/\\s*style\\s*>#isU'); foreach ($head_patterns as $pattern) { $num_matches = preg_match_all($pattern, $head, $matches); for ($i = 0; $i < $num_matches; $i++) { $x = $matches[0][$i]; $match_x = array(); if (preg_match('#\\s(src|href)=["\']([^"\']+)["\']#i', $x, $match_x) != 0) { if (url_is_local($match_x[1])) { $url_new = qualify_url($match_x[2], $url_base); $x = str_replace($match_x[0], str_replace($match_x[2], $url_new, $match_x[0]), $x); } } $EXTRA_HEAD->attach($x); } } } return $body; }
/** * Return the file in the URL by downloading it over HTTP. If a byte limit is given, it will only download that many bytes. It outputs warnings, returning NULL, on error. * * @param URLPATH The URL to download * @param ?integer The number of bytes to download. This is not a guarantee, it is a minimum (NULL: all bytes) * @range 1 max * @param boolean Whether to throw an ocPortal error, on error * @param boolean Whether to block redirects (returns NULL when found) * @param string The user-agent to identify as * @param ?array An optional array of POST parameters to send; if this is NULL, a GET request is used (NULL: none) * @param ?array An optional array of cookies to send (NULL: none) * @param ?string 'accept' header value (NULL: don't pass one) * @param ?string 'accept-charset' header value (NULL: don't pass one) * @param ?string 'accept-language' header value (NULL: don't pass one) * @param ?resource File handle to write to (NULL: do not do that) * @param ?string The HTTP referer (NULL: none) * @param ?array A pair: authentication username and password (NULL: none) * @param float The timeout * @param boolean Whether to treat the POST parameters as a raw POST (rather than using MIME) * @param ?array Files to send. Map between field to file path (NULL: none) * @return ?string The data downloaded (NULL: error) */ function _http_download_file($url, $byte_limit = NULL, $trigger_error = true, $no_redirect = false, $ua = 'ocPortal', $post_params = NULL, $cookies = NULL, $accept = NULL, $accept_charset = NULL, $accept_language = NULL, $write_to_file = NULL, $referer = NULL, $auth = NULL, $timeout = 6.0, $is_xml = false, $files = NULL) { $url = str_replace(' ', '%20', $url); // Prevent DOS loop attack if (ocp_srv('HTTP_USER_AGENT') == $ua) { $ua = 'ocP-recurse'; } if (ocp_srv('HTTP_USER_AGENT') == 'ocP-recurse') { return NULL; } require_code('urls'); if (url_is_local($url)) { $url = get_custom_base_url() . '/' . $url; } if (strpos($url, '/') !== false && strrpos($url, '/') < 7) { $url .= '/'; } global $DOWNLOAD_LEVEL; $DOWNLOAD_LEVEL++; global $HTTP_DOWNLOAD_MIME_TYPE; $HTTP_DOWNLOAD_MIME_TYPE = NULL; global $HTTP_CHARSET; $HTTP_CHARSET = NULL; global $HTTP_DOWNLOAD_SIZE; $HTTP_DOWNLOAD_SIZE = 0; global $HTTP_DOWNLOAD_URL; $HTTP_DOWNLOAD_URL = $url; global $HTTP_MESSAGE; $HTTP_MESSAGE = NULL; global $HTTP_MESSAGE_B; $HTTP_MESSAGE_B = NULL; global $HTTP_NEW_COOKIES; if ($DOWNLOAD_LEVEL == 0) { $HTTP_NEW_COOKIES = array(); } global $HTTP_FILENAME; $HTTP_FILENAME = NULL; if ($DOWNLOAD_LEVEL == 8) { return ''; } //critical_error('FILE_DOS',$url); // Prevent possible DOS attack $url_parts = @parse_url($url); if ($url_parts === false || !isset($url_parts['host'])) { if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_BAD_URL', escape_html($url))); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_BAD_URL', escape_html($url)); } $DOWNLOAD_LEVEL--; $HTTP_MESSAGE = 'malconstructed-URL'; return NULL; } if (!array_key_exists('scheme', $url_parts)) { $url_parts['scheme'] = 'http'; } $use_curl = $url_parts['scheme'] != 'http' && function_exists('curl_version') || function_exists('get_value') && get_value('prefer_curl') === '1'; // Prep cookies and post data if (!is_null($post_params)) { if ($is_xml) { $_postdetails_params = $post_params[0]; } else { $_postdetails_params = ''; //$url_parts['scheme'].'://'.$url_parts['host'].$url2.'?'; $first = true; if (array_keys($post_params) == array('_')) { $_postdetails_params = $post_params['_']; } else { foreach ($post_params as $param_key => $param_value) { if ($use_curl) { if (substr($param_value, 0, 1) == '@') { $param_value = ' @' . substr($param_value, 1); } } $_postdetails_params .= array_key_exists('query', $url_parts) || !$first ? '&' . $param_key . '=' . rawurlencode($param_value) : $param_key . '=' . rawurlencode($param_value); $first = false; } } } } else { $_postdetails_params = ''; } if (!is_null($cookies) && count($cookies) != 0) { $_cookies = ''; $done_one_cookie = false; foreach ($cookies as $key => $val) { if ($done_one_cookie) { $_cookies .= '; '; } if (is_array($val)) { foreach ($val as $key2 => $val2) { if (!is_string($key2)) { $key2 = strval($key2); } if ($done_one_cookie) { $_cookies .= '; '; } $_cookies .= $key . '[' . $key2 . ']=' . rawurlencode($val2); $done_one_cookie = true; } } else { $_cookies .= $key . '=' . rawurlencode($val); } $done_one_cookie = true; } } if ($use_curl) { if (!is_null($files)) { if (is_null($post_params)) { $post_params = array(); } foreach ($files as $upload_field => $file_path) { $post_params[$upload_field] = '@' . $file_path; } } // CURL if (function_exists('curl_version')) { if (function_exists('curl_init')) { if (function_exists('curl_setopt')) { if (function_exists('curl_exec')) { if (function_exists('curl_error')) { if (function_exists('curl_close')) { if (function_exists('curl_getinfo')) { if ($url_parts['scheme'] == 'https' || $url_parts['scheme'] == 'http') { $curl_version = curl_version(); if (is_string($curl_version) && strpos($curl_version, 'OpenSSL') !== false || is_array($curl_version) && array_key_exists('ssl_version', $curl_version)) { $ch = curl_init($url); if (!is_null($post_params)) { curl_setopt($ch, CURLOPT_POST, true); if (is_null($files)) { curl_setopt($ch, CURLOPT_POSTFIELDS, $_postdetails_params); } else { @curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params); // PHP5.5 gives a deprecation warning } } if (!is_null($cookies) && count($cookies) != 0) { curl_setopt($ch, CURLOPT_COOKIE, $_cookies); } $crt_path = get_file_base() . '/data/curl-ca-bundle.crt'; if (ini_get('curl.cainfo') == '') { curl_setopt($ch, CURLOPT_CAINFO, $crt_path); curl_setopt($ch, CURLOPT_CAPATH, $crt_path); } //curl_setopt($ch,CURLOPT_SSLVERSION,6); curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1'); //if (!$no_redirect) @curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true); // May fail with safe mode, meaning we can't follow Location headers. But we can do better ourselves anyway and protect against file:// exploits. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($timeout)); curl_setopt($ch, CURLOPT_TIMEOUT, intval($timeout)); curl_setopt($ch, CURLOPT_USERAGENT, $ua); $headers = array(); if ($is_xml) { $headers[] = 'Content-Type: application/xml'; } if (!is_null($accept)) { $headers[] = 'Accept: ' . rawurlencode($accept); } if (!is_null($accept_charset)) { $headers[] = 'Accept-Charset: ' . rawurlencode($accept_charset); } if (!is_null($accept_language)) { $headers[] = 'Accept-Language: ' . rawurlencode($accept_language); } if (is_null($files)) { // Breaks file uploads for some reason curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); if (!is_null($auth)) { curl_setopt($ch, CURLOPT_USERPWD, implode(':', $auth)); } if (!is_null($referer)) { curl_setopt($ch, CURLOPT_REFERER, $referer); } $proxy = get_value('proxy', NULL, true); if ($proxy == '') { $proxy = NULL; } if (!is_null($proxy) && $url_parts['host'] != 'localhost' && $url_parts['host'] != '127.0.0.1') { $port = get_value('proxy_port', NULL, true); if (is_null($port)) { $port = '8080'; } curl_setopt($ch, CURLOPT_PROXY, $proxy . ':' . $port); $proxy_user = get_value('proxy_user', NULL, true); if (!is_null($proxy_user)) { $proxy_password = get_value('proxy_password', NULL, true); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_user . ':' . $proxy_password); } } if (!is_null($byte_limit)) { curl_setopt($ch, CURLOPT_RANGE, '0-' . strval($byte_limit == 0 ? 0 : $byte_limit - 1)); } $line = curl_exec($ch); if ($line === false) { $error = curl_error($ch); curl_close($ch); } else { if (substr($line, 0, 25) == "HTTP/1.1 100 Continue\r\n\r\n") { $line = substr($line, 25); } if (substr($line, 0, 25) == "HTTP/1.0 100 Continue\r\n\r\n") { $line = substr($line, 25); } $HTTP_DOWNLOAD_MIME_TYPE = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $HTTP_DOWNLOAD_SIZE = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); $HTTP_DOWNLOAD_URL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); $HTTP_MESSAGE = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); if ($HTTP_MESSAGE == '206') { $HTTP_MESSAGE = '200'; } // We don't care about partial-content return code, as ocP implementation gets ranges differently and we check '200' as a return result if (strpos($HTTP_DOWNLOAD_MIME_TYPE, ';') !== false) { $HTTP_CHARSET = substr($HTTP_DOWNLOAD_MIME_TYPE, 8 + strpos($HTTP_DOWNLOAD_MIME_TYPE, 'charset=')); $HTTP_DOWNLOAD_MIME_TYPE = substr($HTTP_DOWNLOAD_MIME_TYPE, 0, strpos($HTTP_DOWNLOAD_MIME_TYPE, ';')); } curl_close($ch); if (substr($line, 0, strlen('HTTP/1.0 200 Connection Established')) == 'HTTP/1.0 200 Connection Established') { $line = substr($line, strpos($line, "\r\n\r\n") + 4); } $pos = strpos($line, "\r\n\r\n"); if (substr($line, 0, strlen('HTTP/1.1 100 ')) == 'HTTP/1.1 100 ' || substr($line, 0, strlen('HTTP/1.0 100 ')) == 'HTTP/1.0 100 ') { $pos = strpos($line, "\r\n\r\n", $pos + 4); } if ($pos === false) { $pos = strlen($line); } else { $pos += 4; } $lines = explode("\r\n", substr($line, 0, $pos)); foreach ($lines as $lno => $_line) { $_line .= "\r\n"; $matches = array(); if (preg_match('#^Content-Disposition: [^;]*;\\s*filename="([^"]*)"#i', $_line, $matches) != 0) { $HTTP_FILENAME = $matches[1]; } if (preg_match("#^Set-Cookie: ([^\r\n=]*)=([^\r\n]*)\r\n#i", $_line, $matches) != 0) { $HTTP_NEW_COOKIES[trim(rawurldecode($matches[1]))] = trim($matches[2]); } if (preg_match("#^Location: (.*)\r\n#i", $_line, $matches) != 0) { if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = basename($matches[1]); } if (strpos($matches[1], '://') === false) { $matches[1] = qualify_url($matches[1], $url); } if ($matches[1] != $url) { $bak = $HTTP_FILENAME; $text = $no_redirect ? mixed() : _http_download_file($matches[1], $byte_limit, $trigger_error, false, $ua, NULL, $cookies, $accept, $accept_charset, $accept_language, $write_to_file); if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = $bak; } $DOWNLOAD_LEVEL--; return _detect_character_encoding($text); } } } $DOWNLOAD_LEVEL--; $ret = _detect_character_encoding(substr($line, $pos)); if (!is_null($write_to_file)) { fwrite($write_to_file, $ret); $ret = ''; } return $ret; } } } } } } } } } } } $errno = 0; $errstr = ''; if ($url_parts['scheme'] == 'http') { if (!array_key_exists('host', $url_parts)) { $url_parts['host'] = '127.0.0.1'; } $connect_to = $url_parts['host']; $base_url_parsed = parse_url(get_base_url()); if (!array_key_exists('host', $base_url_parsed)) { $base_url_parsed['host'] = '127.0.0.1'; } if ($base_url_parsed['host'] == $connect_to && function_exists('get_option') && get_option('ip_forwarding') == '1') { $connect_to = '127.0.0.1'; // Localhost can fail due to IP6 } elseif (preg_match('#(\\s|,|^)gethostbyname(\\s|$|,)#i', @ini_get('disable_functions')) == 0) { $connect_to = gethostbyname($connect_to); } // for DNS cacheing $proxy = function_exists('get_value') ? get_value('proxy', NULL, true) : NULL; if ($proxy == '') { $proxy = NULL; } if (!is_null($proxy) && $connect_to != 'localhost' && $connect_to != '127.0.0.1') { $proxy_port = get_value('proxy_port', NULL, true); if (is_null($proxy_port)) { $proxy_port = '8080'; } $mysock = @fsockopen($proxy, intval($proxy_port), $errno, $errstr, $timeout); } else { $mysock = @fsockopen($connect_to, array_key_exists('port', $url_parts) ? $url_parts['port'] : 80, $errno, $errstr, $timeout); } if (is_null($mysock)) { $mysock = false; } // For Quercus #4549 } else { $mysock = false; } if ($mysock !== false) { if (function_exists('stream_set_timeout')) { if (@stream_set_timeout($mysock, intval($timeout)) === false) { $mysock = false; } } elseif (function_exists('socket_set_timeout')) { if (@socket_set_timeout($mysock, intval($timeout)) === false) { $mysock = false; } } } if ($mysock !== false) { $url2 = array_key_exists('path', $url_parts) ? $url_parts['path'] : '/'; if (array_key_exists('query', $url_parts)) { $url2 .= '?' . $url_parts['query']; } if (!is_null($proxy) && $connect_to != 'localhost' && $connect_to != '127.0.0.1') { $out = ''; $out .= (is_null($post_params) ? $byte_limit === 0 ? 'HEAD ' : 'GET ' : 'POST ') . str_replace("\r", '', str_replace(chr(10), '', $url)) . " HTTP/1.1\r\n"; $proxy_user = get_value('proxy_user', NULL, true); if (!is_null($proxy_user)) { $proxy_password = get_value('proxy_password', NULL, true); $out .= 'Proxy-Authorization: Basic ' . base64_encode($proxy_user . ':' . $proxy_password) . "\r\n"; } } else { $out = (is_null($post_params) ? $byte_limit === 0 ? 'HEAD ' : 'GET ' : 'POST ') . str_replace("\r", '', str_replace(chr(10), '', $url2)) . " HTTP/1.1\r\n"; } $out .= "Host: " . $url_parts['host'] . "\r\n"; if (!is_null($cookies) && count($cookies) != 0) { $out .= 'Cookie: ' . $_cookies . "\r\n"; } $out .= "User-Agent: " . rawurlencode($ua) . "\r\n"; if (!is_null($auth)) { $out .= "Authorization: Basic " . base64_encode(implode(':', $auth)) . "==\r\n"; } if (!is_null($accept)) { $out .= "Accept: " . rawurlencode($accept) . "\r\n"; } else { $out .= "Accept: */*\r\n"; // There's a mod_security rule that checks for this } if (!is_null($accept_charset)) { $out .= "Accept-Charset: " . rawurlencode($accept_charset) . "\r\n"; } if (!is_null($accept_language)) { $out .= "Accept-Language: " . rawurlencode($accept_language) . "\r\n"; } if (!is_null($referer)) { $out .= "Referer: " . rawurlencode($referer) . "\r\n"; } if ($_postdetails_params != '') { if ($is_xml) { $out .= "Content-Type: application/xml\r\n"; $out .= 'Content-length: ' . strval(strlen($_postdetails_params)) . "\r\n"; $out .= "\r\n" . $_postdetails_params . "\r\n\r\n"; } else { if (is_null($files)) { $out .= 'Content-type: application/x-www-form-urlencoded; charset=' . get_charset() . "\r\n"; $out .= 'Content-length: ' . strval(strlen($_postdetails_params)) . "\r\n"; $out .= "\r\n" . $_postdetails_params . "\r\n\r\n"; } else { $divider = uniqid('', true); $out2 = ''; $out .= 'Content-type: multipart/form-data; boundary="--ocp' . $divider . '"; charset=' . get_charset() . "\r\n"; foreach ($post_params as $key => $val) { $out2 .= '----ocp' . $divider . "\r\n"; $out2 .= 'Content-Disposition: form-data; name="' . urlencode($key) . '"' . "\r\n\r\n"; $out2 .= $val . "\r\n"; } if (!is_null($files)) { foreach ($files as $upload_field => $file_path) { $out2 .= '----ocp' . $divider . "\r\n"; $out2 .= 'Content-Disposition: form-data; name="' . urlencode($upload_field) . '"; filename="' . urlencode(basename($file_path)) . '"' . "\r\n"; $out2 .= 'Content-Type: application/octet-stream' . "\r\n\r\n"; $out2 .= file_get_contents($file_path) . "\r\n"; } } $out2 .= '----ocp' . $divider . "--\r\n"; $out .= 'Content-length: ' . strval(strlen($out2)) . "\r\n"; $out .= "\r\n" . $out2; } } } $out .= "Connection: Close\r\n\r\n"; @fwrite($mysock, $out); $data_started = false; $input = ''; $input_len = 0; $first_fail_time = mixed(); $chunked = false; $buffer_unprocessed = ''; while ($chunked || !@feof($mysock)) { $line = @fread($mysock, $chunked && strlen($buffer_unprocessed) > 10 ? 10 : 1024); if ($line === false) { if (!$chunked || $buffer_unprocessed == '') { break; } $line = ''; } if ($line == '') { if (!is_null($first_fail_time)) { if ($first_fail_time < time() - 5) { break; } } else { $first_fail_time = time(); } } else { $first_fail_time = NULL; } if ($data_started) { $line = $buffer_unprocessed . $line; $buffer_unprocessed = ''; if ($chunked) { $matches = array(); if (preg_match('#^(\\r\\n)?([a-f\\d]+) *(;[^\\r\\n]*)?\\r\\n(.*)$#is', $line, $matches) != 0) { $amount_wanted = hexdec($matches[2]); if (strlen($matches[4]) < $amount_wanted) { $buffer_unprocessed = $line; continue; } $buffer_unprocessed = substr($matches[4], $amount_wanted); // May be some more extra read $line = substr($matches[4], 0, $amount_wanted); if ($line == '') { break; } } else { // Should not happen :S } } if (is_null($write_to_file)) { $input .= $line; } else { fwrite($write_to_file, $line); } $input_len += strlen($line); if (!is_null($byte_limit) && $input_len >= $byte_limit) { $input = substr($input, 0, $byte_limit); break; } } elseif ($line != '') { $old_line = $line; $lines = explode("\r\n", $line); $tally = 0; foreach ($lines as $lno => $line) { $line .= "\r\n"; $tally += strlen($line); $matches = array(); if (preg_match("#Transfer-Encoding: chunked\r\n#i", $line, $matches) != 0) { $chunked = true; } if (preg_match("#Content-Disposition: [^\r\n]*filename=\"([^;\r\n]*)\"\r\n#i", $line, $matches) != 0) { $HTTP_FILENAME = $matches[1]; } if (preg_match("#^Set-Cookie: ([^\r\n=]*)=([^\r\n]*)\r\n#i", $line, $matches) != 0) { $HTTP_NEW_COOKIES[trim(rawurldecode($matches[1]))] = trim($matches[2]); } if (preg_match("#^Content-Length: ([^;\r\n]*)\r\n#i", $line, $matches) != 0) { $HTTP_DOWNLOAD_SIZE = intval($matches[1]); } if (preg_match("#^Content-Type: ([^;\r\n]*)(;[^\r\n]*)?\r\n#i", $line, $matches) != 0) { $HTTP_DOWNLOAD_MIME_TYPE = $matches[1]; if (array_key_exists(2, $matches)) { $_ct_more = explode(';', str_replace(' ', '', trim($matches[2]))); foreach ($_ct_more as $ct_more) { $ct_bits = explode('=', $ct_more, 2); if (count($ct_bits) == 2 && strtolower($ct_bits[0]) == 'charset') { $HTTP_CHARSET = trim($ct_bits[1]); } } } } if (preg_match("#^Refresh: (\\d*);(.*)\r\n#i", $line, $matches) != 0) { if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = basename($matches[1]); } @fclose($mysock); if (strpos($matches[1], '://') === false) { $matches[1] = qualify_url($matches[1], $url); } $bak = $HTTP_FILENAME; $text = $no_redirect ? mixed() : _http_download_file($matches[2], $byte_limit, $trigger_error, false, $ua, NULL, $cookies, $accept, $accept_charset, $accept_language, $write_to_file); if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = $bak; } $DOWNLOAD_LEVEL--; return _detect_character_encoding($text); } if (preg_match("#^Location: (.*)\r\n#i", $line, $matches) != 0) { if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = basename($matches[1]); } @fclose($mysock); if (strpos($matches[1], '://') === false) { $matches[1] = qualify_url($matches[1], $url); } if ($matches[1] != $url) { $bak = $HTTP_FILENAME; $text = $no_redirect ? mixed() : _http_download_file($matches[1], $byte_limit, $trigger_error, false, $ua, NULL, $cookies, $accept, $accept_charset, $accept_language, $write_to_file); if (is_null($HTTP_FILENAME)) { $HTTP_FILENAME = $bak; } $DOWNLOAD_LEVEL--; return _detect_character_encoding($text); } } if (preg_match("#HTTP/(\\d*\\.\\d*) (\\d*) #", $line, $matches) != 0) { // 200 = Ok // 301/302 = Redirected: Not good, we should not be here // 401 = Unauthorized // 403 = Forbidden // 404 = Not found // 500 = Internal server error $HTTP_MESSAGE = $matches[2]; switch ($matches[2]) { case '302': case '301': // We'll expect a location header break; case '200': // Good break; case '401': if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_STATUS_UNAUTHORIZED', escape_html($url))); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_STATUS_UNAUTHORIZED', escape_html($url)); } @fclose($mysock); $HTTP_DOWNLOAD_MIME_TYPE = 'security'; $DOWNLOAD_LEVEL--; return NULL; case '403': if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_STATUS_UNAUTHORIZED', escape_html($url))); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_STATUS_UNAUTHORIZED', escape_html($url)); } @fclose($mysock); $HTTP_DOWNLOAD_MIME_TYPE = 'security'; $DOWNLOAD_LEVEL--; return NULL; case '404': if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_STATUS_NOT_FOUND', escape_html($url))); } @fclose($mysock); $DOWNLOAD_LEVEL--; return NULL; case '500': if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_STATUS_SERVER_ERROR', escape_html($url))); } @fclose($mysock); $DOWNLOAD_LEVEL--; return NULL; default: if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_STATUS_UNKNOWN', escape_html($url))); } } } if ($line == "\r\n") { $data_started = true; $buffer_unprocessed = substr($old_line, $tally); if ($buffer_unprocessed === false) { $buffer_unprocessed = ''; } break; } } } } // Process any non-chunked extra buffer (chunked would have been handled in main loop) if (!$chunked) { if ($buffer_unprocessed != '') { if (is_null($write_to_file)) { $input .= $buffer_unprocessed; } else { fwrite($write_to_file, $buffer_unprocessed); } $input_len += strlen($buffer_unprocessed); if (!is_null($byte_limit) && $input_len >= $byte_limit) { $input = substr($input, 0, $byte_limit); } } } @fclose($mysock); if (!$data_started) { if ($byte_limit === 0) { return ''; } if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_NO_SERVER', escape_html($url))); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_NO_SERVER', escape_html($url)); } $DOWNLOAD_LEVEL--; $HTTP_MESSAGE = 'no-data'; return NULL; } $size_expected = $HTTP_DOWNLOAD_SIZE; if (!is_null($byte_limit)) { if ($byte_limit < $HTTP_DOWNLOAD_SIZE) { $size_expected = $byte_limit; } } if ($input_len < $size_expected) { if ($trigger_error) { warn_exit(do_lang_tempcode('HTTP_DOWNLOAD_CUT_SHORT', escape_html($url), escape_html(integer_format($size_expected)), escape_html(integer_format($input_len)))); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_CUT_SHORT', escape_html($url), escape_html(integer_format($size_expected)), escape_html(integer_format($input_len))); } $DOWNLOAD_LEVEL--; $HTTP_MESSAGE = 'short-data'; return _detect_character_encoding($input); } $DOWNLOAD_LEVEL--; return _detect_character_encoding($input); } else { if ($errno != 110 && ($errno != 10060 || @ini_get('default_socket_timeout') == '1') && is_null($post_params)) { // Perhaps fsockopen is restricted... try fread/file_get_contents @ini_set('allow_url_fopen', '1'); $timeout_before = @ini_get('default_socket_timeout'); @ini_set('default_socket_timeout', strval(intval($timeout))); if (is_null($byte_limit) && is_null($write_to_file)) { $read_file = @file_get_contents($url); } else { $_read_file = @fopen($url, 'rb'); if ($_read_file !== false) { $read_file = ''; while (!feof($_read_file) && (is_null($byte_limit) || strlen($read_file) < $byte_limit)) { $line = fread($_read_file, 1024); if (is_null($write_to_file)) { $read_file .= $line; } else { fwrite($write_to_file, $line); } } fclose($_read_file); } else { $read_file = false; } } @ini_set('allow_url_fopen', '0'); @ini_set('default_socket_timeout', $timeout_before); if ($read_file !== false) { $DOWNLOAD_LEVEL--; return _detect_character_encoding($read_file); } $errstr = $php_errormsg; } if ($trigger_error) { if ($errstr == '') { $errstr = strval($errno); } $error = do_lang_tempcode('_HTTP_DOWNLOAD_NO_SERVER', escape_html($url), escape_html($errstr)); warn_exit($error); } else { $HTTP_MESSAGE_B = do_lang_tempcode('HTTP_DOWNLOAD_NO_SERVER', escape_html($url)); } $DOWNLOAD_LEVEL--; $HTTP_MESSAGE = 'could not connect to host (' . $errstr . ')'; return NULL; } }
/** * Used by semihtml_to_comcode to fix <a> tag links. preg_replace_callback callback * * @param array Array of matches * @return string Substituted text */ function _a_tag_link_fixup($matches) { $referer = post_param('http_referer', ocp_srv('HTTP_REFERER')); $caller_url = looks_like_url($referer) ? preg_replace('#/[^/]*$#', '', $referer) : get_base_url(); $ret = '<a ' . $matches[1] . 'href="' . qualify_url($matches[2], $caller_url) . '"' . $matches[3] . '>'; return $ret; }
function handleParsedElement($parser, $pos, $name, $attrs) { global $tag_stack; global $err; global $banner; global $img_conversion_enabled; global $skin; global $allow_skin_attribute; static $number_of_decks = 0; static $number_of_forms = 0; static $number_of_linksets = 0; static $markup_language = 0; static $raw_mode = false; if (function_exists("xml_get_current_line_number")) { $line = xml_get_current_line_number($parser); } else { $line = "???"; } switch ($name) { case "HAWHAW": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_HAWHAW, $parser); $tag_stack->push(0, HAX_TAG_HAWHAW); } else { // HAX_PARSE_END $tag_stack->pop(); } break; case "DECK": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_DECK, $parser); if ($number_of_decks++ > 0) { error($err[5], $parser, $line); } // determine contructor arguments of HAW_deck if (isset($attrs["TITLE"])) { $title = $attrs["TITLE"]; } else { $title = HAW_NOTITLE; } if (isset($attrs["ALIGN"]) && $attrs["ALIGN"] == "center") { $alignment = HAW_ALIGN_CENTER; } elseif (isset($attrs["ALIGN"]) && $attrs["ALIGN"] == "right") { $alignment = HAW_ALIGN_RIGHT; } else { $alignment = HAW_ALIGN_LEFT; } $output = HAW_OUTPUT_AUTOMATIC; if (isset($attrs["OUTPUT"])) { switch ($attrs["OUTPUT"]) { case "bigscreen": $output = HAW_OUTPUT_BIGSCREEN; break; case "wap": $output = HAW_OUTPUT_WAP; break; case "hdml": $output = HAW_OUTPUT_HDML; break; case "pda": $output = HAW_OUTPUT_PDA; break; case "imode": $output = HAW_OUTPUT_IMODE; break; case "mml": $output = HAW_OUTPUT_MML; break; case "voicexml": $output = HAW_OUTPUT_VOICEXML; break; case "xhtml": $output = HAW_OUTPUT_XHTML; break; } } // initiate HAW_deck object $deck = new HAW_deck($title, $alignment, $output); $markup_language = $deck->ml; // modify HAW_deck objects according attribute list if (isset($attrs["REDIRECTION"])) { $redirection = explode(";", $attrs["REDIRECTION"]); $redirection[0] = trim($redirection[0]); // strip whitespace $redirection[1] = trim($redirection[1]); if (isset($redirection[2])) { $redirection[2] = trim(strtolower($redirection[2])); } if ($redirection[0] < 1 || $redirection[0] > 3600) { error($err[3], $parser, $line); } // invalid time value if (substr(strtolower($redirection[1]), 0, 4) != "url=") { error($err[3], $parser, $line); } // invalid URL declaration if (isset($redirection[2]) && $redirection[2] == "proxy=no") { // redirect directly to target (needed for HawTags) $deck->set_redirection($redirection[0], substr($redirection[1], 4)); } else { // redirect via HAWXY $deck->set_redirection($redirection[0], determine_url(qualify_url(substr($redirection[1], 4)))); } } if (isset($attrs["CACHE"]) && strtolower($attrs["CACHE"]) == "no") { $deck->disable_cache(); } if (isset($attrs["CHARSET"])) { $deck->set_charset($attrs["CHARSET"]); } if (isset($attrs["LANGUAGE"])) { $deck->set_language($attrs["LANGUAGE"]); } if (isset($attrs["CSS"])) { $deck->set_css($attrs["CSS"]); } if (isset($attrs["CSS_CLASS"])) { $deck->set_css_class($attrs["CSS_CLASS"]); } if (isset($attrs["BACKGROUND"])) { $deck->set_background($attrs["BACKGROUND"]); } if (isset($attrs["BGCOLOR"])) { $deck->set_bgcolor($attrs["BGCOLOR"]); } if (isset($attrs["SIZE"])) { $deck->set_size($attrs["SIZE"]); } if (isset($attrs["COLOR"])) { $deck->set_color($attrs["COLOR"]); } if (isset($attrs["LINK_COLOR"])) { $deck->set_link_color($attrs["LINK_COLOR"]); } if (isset($attrs["VLINK_COLOR"])) { $deck->set_vlink_color($attrs["VLINK_COLOR"]); } if (isset($attrs["LINK_BRACKETS"]) && strtolower($attrs["LINK_BRACKETS"]) == "no") { $deck->use_link_brackets(false); } if (isset($attrs["FACE"])) { $deck->set_face($attrs["FACE"]); } if (isset($attrs["WAPHOME"])) { $deck->set_waphome($attrs["WAPHOME"]); } else { $deck->set_waphome("http://" . getenv("HTTP_HOST") . getenv("REQUEST_URI")); } if (isset($attrs["VOICE_JINGLE"])) { $deck->set_voice_jingle($attrs["VOICE_JINGLE"]); } if (isset($attrs["SKIN"]) && $allow_skin_attribute) { if (strtolower($attrs["SKIN"]) == "none") { $deck->use_simulator(HAW_SIM_NONE); } else { if (strtolower($attrs["SKIN"]) == "classic") { $deck->use_simulator(HAW_SIM_CLASSIC); } else { $deck->use_simulator($attrs["SKIN"]); } } } else { $deck->use_simulator($skin); } // display banners on top of simulator device while (list($key, $val) = each($banner)) { // edit config file for banner control $top_banner[$key] = new HAW_banner($val["img"], $val["url"], $val["alt"]); $top_banner[$key]->set_size($val["width"], $val["height"]); $deck->add_banner($top_banner[$key], HAW_TOP); } $tag_stack->push($deck, HAX_TAG_DECK); } else { // HAX_PARSE_END $element = $tag_stack->pop(); $deck = $element["element"]; $deck->create_page(); } break; case "FORM": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_FORM, $parser); if ($number_of_forms++ > 0) { error($err[9], $parser, $line); } if (!isset($attrs["ACTION"])) { error("<form> " . $err[7] . " action", $parser, $line); } // action attribute is missing // initiate HAW_form object if (isset($attrs["PROXY"]) && strtolower($attrs["PROXY"]) == "no") { // send form data to action script (needed for HawTags) $form = new HAW_form($attrs["ACTION"]); } else { // send form data to hawxy server $form = new HAW_form($_SERVER['SCRIPT_NAME']); // add info about XML source where form input has to be propagated to $hidden = new HAW_hidden("code", qualify_url($attrs["ACTION"])); $form->add_hidden($hidden); } $tag_stack->push($form, HAX_TAG_FORM); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_form object $form = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck) $base_element = $element["element"]; $base_element->add_form($form); // add HAW_form to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "TEXT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_TEXT, $parser); $format = "HAW_TEXTFORMAT_NORMAL"; if (isset($attrs["BOLD"]) && strtolower($attrs["BOLD"]) == "yes") { $format |= HAW_TEXTFORMAT_BOLD; } if (isset($attrs["ITALIC"]) && strtolower($attrs["ITALIC"]) == "yes") { $format |= HAW_TEXTFORMAT_ITALIC; } if (isset($attrs["UNDERLINE"]) && strtolower($attrs["UNDERLINE"]) == "yes") { $format |= HAW_TEXTFORMAT_UNDERLINE; } if (isset($attrs["BIG"]) && strtolower($attrs["BIG"]) == "yes") { $format |= HAW_TEXTFORMAT_BIG; } if (isset($attrs["SMALL"]) && strtolower($attrs["SMALL"]) == "yes") { $format |= HAW_TEXTFORMAT_SMALL; } if (isset($attrs["BOXED"]) && strtolower($attrs["BOXED"]) == "yes") { $format |= HAW_TEXTFORMAT_BOXED; } $text = new HAW_text("", $format); if (isset($attrs["BR"]) && $attrs["BR"] >= 0) { $text->set_br($attrs["BR"] + 0); } // convert string to int! if (isset($attrs["CSS_CLASS"])) { $text->set_css_class($attrs["CSS_CLASS"]); } if (isset($attrs["COLOR"])) { $textcolor = $attrs["COLOR"]; if (isset($attrs["BOXCOLOR"])) { $boxcolor = $attrs["BOXCOLOR"]; } else { $boxcolor = ""; } $text->set_color($textcolor, $boxcolor); } $tag_stack->push($text, HAX_TAG_TEXT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_text object $text = $element["element"]; if (!$text->voice_text) { $text->voice_text = $text->text; } // update voice_text if not already set $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_form, ...) $base_element = $element["element"]; if ($element["tag"] == HAX_TAG_TD) { // include HAW_text object in HAX_td pseudo class $base_element->element = $text; $base_element->tag = HAX_TAG_TEXT; } else { $base_element->add_text($text); } // add HAW_text to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "IMG": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_IMAGE, $parser); if (!($alt = $attrs["ALT"])) { error("<img> " . $err[7] . " alt", $parser, $line); } // alt attribute is missing if (isset($attrs["SRC"])) { // source attribute ==> perform automatic image conversion if (!$img_conversion_enabled) { error($err[13], $parser, $line); } // image conversion deactivated per config if (!function_exists("ImageTypes")) { error($err[13], $parser, $line); } // GD is not loaded if (!(ImageTypes() & (IMG_PNG | IMG_WBMP))) { error($err[13], $parser, $line); } // not all necessary image types supported $source = $attrs["SRC"]; $extension = strtolower(substr($source, -4)); $accept = strtolower($_SERVER['HTTP_ACCEPT']); if ($extension == ".gif" && (strstr($accept, "image/gif") || $markup_language == HAW_HTML && !strstr($accept, "image/png")) || $extension == ".png" && (strstr($accept, "image/png") || $markup_language == HAW_HTML) || $extension == "wbmp" && $markup_language == HAW_WML) { // requesting browser accepts given src image file // ==> no conversion required $src_html = $source; $src_wbmp = $source; } else { // session-controlled image conversion // convert images of HAWHAW XML files only // (we don't want to act as conversion server for the whole world!) static $img_counter = 0; $varname = "i" . $img_counter; session_register($varname); $_SESSION[$varname] = $attrs["SRC"]; $_SESSION['img_ml'] = $markup_language; //$url = sprintf("%s?index=%d", $_SERVER['PHP_SELF'] , $img_counter); // auto-appending of SID does not work in some environments ?!?!? // PHPSESSID may appear twice in url - and if? ... $url = sprintf("%s?index=%d&%s", $_SERVER['PHP_SELF'], $img_counter, SID); // create image with session ID instead of image URL's // ==> hawxy script will immediately receive a new request // and will create appropriate image on the fly $src_html = $url; $src_wbmp = $url; $img_counter++; } } if (!isset($src_wbmp) && !isset($attrs["WBMP"])) { error("<img> " . $err[7] . " wbmp", $parser, $line); } elseif (isset($attrs["WBMP"])) { $src_wbmp = $attrs["WBMP"]; } // explicitely given WBMP file has precedence if (!isset($src_html) && !isset($attrs["HTML"])) { error("<img> " . $err[7] . " html", $parser, $line); } elseif (isset($attrs["HTML"])) { $src_html = $attrs["HTML"]; } // explicitely given HTML file has precedence if (isset($attrs["BMP"])) { $image = new HAW_image($src_wbmp, $src_html, $alt, $attrs["BMP"]); } else { $image = new HAW_image($src_wbmp, $src_html, $alt); } if (isset($attrs["HTML"]) && isset($attrs["HTML_WIDTH"])) { $image->set_html_width($attrs["HTML_WIDTH"]); } if (isset($attrs["HTML"]) && isset($attrs["HTML_HEIGHT"])) { $image->set_html_height($attrs["HTML_HEIGHT"]); } if (isset($attrs["BR"]) && $attrs["BR"] >= 0) { $image->set_br($attrs["BR"] + 0); } // convert string to int! if (isset($attrs["LOCALSRC"])) { $image->use_localsrc($attrs["LOCALSRC"]); } if (isset($attrs["CHTML_ICON"])) { $image->use_chtml_icon($attrs["CHTML_ICON"] + 0); } // convert string to int! if (isset($attrs["MML_ICON"]) && strlen($attrs["MML_ICON"]) == 2) { $image->use_mml_icon($attrs["MML_ICON"]); } $tag_stack->push($image, HAX_TAG_IMAGE); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_image object $image = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_form, ...) $base_element = $element["element"]; if ($element["tag"] == HAX_TAG_TD) { // include HAW_text object in HAX_td pseudo class $base_element->element = $image; $base_element->tag = HAX_TAG_IMAGE; } else { $base_element->add_image($image); } // add HAW_image to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "INPUT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_INPUT, $parser); if (!($name = $attrs["NAME"])) { error("<input> " . $err[7] . " name", $parser, $line); } // name attribute is missing if (isset($attrs["FORMAT"])) { $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"], $attrs["FORMAT"]); } else { $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"]); } if (isset($attrs["SIZE"])) { $input->set_size($attrs["SIZE"]); } if (isset($attrs["MAXLENGTH"])) { $input->set_maxlength($attrs["MAXLENGTH"]); } if (isset($attrs["TYPE"]) && strtolower($attrs["TYPE"]) == "password") { $input->set_type(HAW_INPUT_PASSWORD); } if (isset($attrs["MODE"])) { if (strtolower($attrs["MODE"]) == "alphabet") { $input->set_mode(HAW_INPUT_ALPHABET); } if (strtolower($attrs["MODE"]) == "katakana") { $input->set_mode(HAW_INPUT_KATAKANA); } if (strtolower($attrs["MODE"]) == "hiragana") { $input->set_mode(HAW_INPUT_HIRAGANA); } if (strtolower($attrs["MODE"]) == "numeric") { $input->set_mode(HAW_INPUT_NUMERIC); } } if (isset($attrs["BR"]) && $attrs["BR"] >= 0) { $input->set_br($attrs["BR"] + 0); } // convert string to int! if (isset($attrs["VOICE_TYPE"])) { $input->set_voice_type($attrs["VOICE_TYPE"]); } if (isset($attrs["VOICE_GRAMMAR_SRC"])) { // set external grammar if (isset($attrs["VOICE_GRAMMAR_TYPE"])) { $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"], $attrs["VOICE_GRAMMAR_TYPE"]); } else { $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"]); } // requires HAWHAW V5.5 or higher! } $tag_stack->push($input, HAX_TAG_INPUT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_input object $input = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_input($input); // add HAW_input to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "RADIO": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_RADIO, $parser); if (!($name = $attrs["NAME"])) { error("<radio> " . $err[7] . " name", $parser, $line); } // name attribute is missing $radio = new HAW_radio($name); $tag_stack->push($radio, HAX_TAG_RADIO); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_radio object $radio = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_radio($radio); // add HAW_radio to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "BUTTON": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_BUTTON, $parser); if (!($label = $attrs["LABEL"])) { error("<button> " . $err[7] . " label", $parser, $line); } // label attribute is missing if (!($value = $attrs["VALUE"])) { error("<button> " . $err[7] . " value", $parser, $line); } // value attribute is missing if (isset($attrs["CHECKED"]) && strtolower($attrs["CHECKED"]) == "yes") { $checked = HAW_CHECKED; } else { $checked = HAW_NOTCHECKED; } $element = $tag_stack->pop(); // pop base object (HAW_radio) $base_element = $element["element"]; $base_element->add_button($label, $value, $checked); // add button properties $tag_stack->push($base_element, $element["tag"]); // re-push base object } else { // HAX_PARSE_END // nothing to do any more } break; case "CHECKBOX": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_CHECKBOX, $parser); if (!($name = $attrs["NAME"])) { error("<checkbox> " . $err[7] . " name", $parser, $line); } // name attribute is missing if (!($value = $attrs["VALUE"])) { error("<checkbox> " . $err[7] . " value", $parser, $line); } // value attribute is missing if (!($label = $attrs["LABEL"])) { error("<checkbox> " . $err[7] . " label", $parser, $line); } // label attribute is missing if (isset($attrs["CHECKED"]) && strtolower($attrs["CHECKED"]) == "yes") { $checked = HAW_CHECKED; } else { $checked = HAW_NOTCHECKED; } $checkbox = new HAW_checkbox($name, $value, $label, $checked); $tag_stack->push($checkbox, HAX_TAG_CHECKBOX); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_checkbox object $checkbox = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_checkbox($checkbox); // add HAW_checkbox to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "SELECT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_SELECT, $parser); if (!($name = $attrs["NAME"])) { error("<select> " . $err[7] . " name", $parser, $line); } // name attribute is missing if (strtolower($attrs["TYPE"]) == "popup") { $select = new HAW_select($name, HAW_SELECT_POPUP); } elseif (strtolower($attrs["TYPE"]) == "spin") { $select = new HAW_select($name, HAW_SELECT_SPIN); } else { $select = new HAW_select($name); } $tag_stack->push($select, HAX_TAG_SELECT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_select object $select = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_select($select); // add HAW_select to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "OPTION": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_OPTION, $parser); if (!($label = $attrs["LABEL"])) { error("<option> " . $err[7] . " label", $parser, $line); } // label attribute is missing if (!($value = $attrs["VALUE"])) { error("<option> " . $err[7] . " value", $parser, $line); } // value attribute is missing if (isset($attrs["SELECTED"]) && strtolower($attrs["SELECTED"]) == "yes") { $selected = HAW_SELECTED; } else { $selected = HAW_NOTSELECTED; } $element = $tag_stack->pop(); // pop base object (HAW_select) $base_element = $element["element"]; $base_element->add_option($label, $value, $selected); // add option properties $tag_stack->push($base_element, $element["tag"]); // re-push base object } else { // HAX_PARSE_END // nothing to do any more } break; case "HIDDEN": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_HIDDEN, $parser); if (!($name = $attrs["NAME"])) { error("<hidden> " . $err[7] . " name", $parser, $line); } // name attribute is missing if (!($value = $attrs["VALUE"])) { error("<hidden> " . $err[7] . " value", $parser, $line); } // value attribute is missing $hidden = new HAW_hidden($name, $value); $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_hidden($hidden); // add HAW_hidden to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } else { // HAX_PARSE_END // nothing to do any more } break; case "SUBMIT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_SUBMIT, $parser); if (!($label = $attrs["LABEL"])) { error("<submit> " . $err[7] . " label", $parser, $line); } // label attribute is missing if (isset($attrs["NAME"])) { $submit = new HAW_submit($label, $attrs["NAME"]); } else { $submit = new HAW_submit($label); } $tag_stack->push($submit, HAX_TAG_SUBMIT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_submit object $submit = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_submit($submit); // add HAW_submit to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "A": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_LINK, $parser); if (!isset($attrs["HREF"])) { error("<a> " . $err[7] . " href", $parser, $line); } // href attribute is missing if (isset($attrs["PROXY"]) && strtolower($attrs["PROXY"]) == "no") { $url = $attrs["HREF"]; } else { $url = determine_url(qualify_url($attrs["HREF"])); } // let HAWHAW proxy retrieve href if (isset($attrs["TITLE"])) { $link = new HAW_link("", $url, $attrs["TITLE"]); } else { $link = new HAW_link("", $url); } if (isset($attrs["BR"]) && $attrs["BR"] >= 0) { $link->set_br($attrs["BR"] + 0); } // convert string to int! if (isset($attrs["CSS_CLASS"])) { $link->set_css_class($attrs["CSS_CLASS"]); } if (isset($attrs["VOICE_DTMF"])) { $link->set_voice_dtmf($attrs["VOICE_DTMF"]); } if (isset($attrs["VOICE_INPUT"])) { $link->set_voice_input($attrs["VOICE_INPUT"]); } else { unset($link->voice_input); } // we must destinguish missing attr from empty string if (isset($attrs["VOICE_TIMEOUT"])) { $link->set_voice_timeout($attrs["VOICE_TIMEOUT"] + 0); } // convert string to int! $tag_stack->push($link, HAX_TAG_LINK); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_link object $link = $element["element"]; if (!$link->voice_text) { $link->voice_text = $link->label; } // update voice_text if not already set $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_linkset, ...) $base_element = $element["element"]; if ($element["tag"] == HAX_TAG_TD) { // include HAW_link object in HAX_td pseudo class $base_element->element = $link; $base_element->tag = HAX_TAG_LINK; } else { $base_element->add_link($link); } // add HAW_link to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "LINKSET": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_LINKSET, $parser); if ($number_of_linksets++ > 0) { error($err[8], $parser, $line); } $linkset = new HAW_linkset(); $tag_stack->push($linkset, HAX_TAG_LINKSET); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_linkset object $linkset = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck) $base_element = $element["element"]; $base_element->add_linkset($linkset); // add HAW_linkset to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "TABLE": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_TABLE, $parser); $table = new HAW_table(); $tag_stack->push($table, HAX_TAG_TABLE); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_table object $table = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_form, ...) $base_element = $element["element"]; $base_element->add_table($table); // add HAW_table to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "TR": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_ROW, $parser); $row = new HAW_row(); $tag_stack->push($row, HAX_TAG_ROW); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_row object $row = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_table) $base_element = $element["element"]; $base_element->add_row($row); // add HAW_row to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "TD": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_TD, $parser); $td = new HAX_td(); $tag_stack->push($td, HAX_TAG_TD); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAX_td object $td = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_row) $base_element = $element["element"]; $base_element->add_column($td->element); // add included element of HAX_td to row $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "HR": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_RULE, $parser); if (isset($attrs["WIDTH"]) && isset($attrs["SIZE"])) { $rule = new HAW_rule($attrs["WIDTH"], $attrs["SIZE"]); } elseif (isset($attrs["WIDTH"])) { $rule = new HAW_rule($attrs["WIDTH"]); } elseif (isset($attrs["SIZE"])) { $rule = new HAW_rule("100%", $attrs["SIZE"]); } else { $rule = new HAW_rule(); } $tag_stack->push($rule, HAX_TAG_RULE); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_rule object $rule = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck or HAW_form) $base_element = $element["element"]; $base_element->add_rule($rule); // add HAW_rule to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "PHONE": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_PHONE, $parser); if (isset($attrs["TITLE"])) { $phone = new HAW_phone("", $attrs["TITLE"]); } else { $phone = new HAW_phone(""); } if (isset($attrs["CSS_CLASS"])) { $phone->set_css_class($attrs["CSS_CLASS"]); } if (isset($attrs["VOICE_INPUT"])) { $phone->set_voice_input($attrs["VOICE_INPUT"]); } if (isset($attrs["VOICE_DTMF"])) { $phone->set_voice_dtmf($attrs["VOICE_DTMF"]); } if (isset($attrs["VOICE_TIMEOUT"])) { $phone->set_voice_timeout($attrs["VOICE_TIMEOUT"] + 0); } // convert string to int! if (isset($attrs["BR"]) && $attrs["BR"] >= 0) { $phone->set_br($attrs["BR"] + 0); } // convert string to int! $tag_stack->push($phone, HAX_TAG_PHONE); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_phone object $phone = $element["element"]; if (!$phone->voice_text) { $phone->voice_text = $phone->label; } // update voice_text if not already set $element = $tag_stack->pop(); // pop base object (HAW_deck) $base_element = $element["element"]; $base_element->add_phone($phone); // add HAW_phone to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "VOICE_TEXT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_VOICE_TEXT, $parser); if (isset($attrs["AUDIO_SRC"])) { $audio_src = $attrs["AUDIO_SRC"]; } else { $audio_src = ""; } $event = new HAX_voice_event(HAX_TAG_VOICE_TEXT, "", $audio_src); $tag_stack->push($event, HAX_TAG_VOICE_TEXT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAX_voice_event object $event = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_input, ...) $base_element = $element["element"]; // set voice text for base element $base_element->set_voice_text($event->text, $event->audio_src); $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "VOICE_HELP": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_VOICE_HELP, $parser); if (isset($attrs["AUDIO_SRC"])) { $audio_src = $attrs["AUDIO_SRC"]; } else { $audio_src = ""; } if (isset($attrs["URL"])) { $url = $attrs["URL"]; } else { $url = ""; } $event = new HAX_voice_event(HAX_TAG_VOICE_HELP, "", $audio_src, $url); $tag_stack->push($event, HAX_TAG_VOICE_HELP); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAX_voice_event object $event = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_input, ...) $base_element = $element["element"]; // activate voice help for base element $base_element->set_voice_help($event->text, $event->audio_src, $event->url); $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "VOICE_NOMATCH": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_VOICE_NOMATCH, $parser); if (isset($attrs["AUDIO_SRC"])) { $audio_src = $attrs["AUDIO_SRC"]; } else { $audio_src = ""; } if (isset($attrs["URL"])) { $url = $attrs["URL"]; } else { $url = ""; } $event = new HAX_voice_event(HAX_TAG_VOICE_NOMATCH, "", $audio_src, $url); $tag_stack->push($event, HAX_TAG_VOICE_NOMATCH); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAX_voice_event object $event = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_input, ...) $base_element = $element["element"]; // activate voice nomatch for base element $base_element->set_voice_nomatch($event->text, $event->audio_src, $event->url); $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "VOICE_NOINPUT": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_VOICE_NOINPUT, $parser); if (isset($attrs["AUDIO_SRC"])) { $audio_src = $attrs["AUDIO_SRC"]; } else { $audio_src = ""; } if (isset($attrs["URL"])) { $url = $attrs["URL"]; } else { $url = ""; } $event = new HAX_voice_event(HAX_TAG_VOICE_NOINPUT, "", $audio_src, $url); $tag_stack->push($event, HAX_TAG_VOICE_NOINPUT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAX_voice_event object $event = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_input, ...) $base_element = $element["element"]; // activate voice noinput for base element $base_element->set_voice_noinput($event->text, $event->audio_src, $event->url); $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; case "RAW": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_RAW, $parser); if (!isset($attrs["MARKUP_LANGUAGE"])) { error("<raw> " . $err[7] . " markup_language", $parser, $line); } // markup_language attribute is missing if (strtolower($attrs["MARKUP_LANGUAGE"]) == "html") { if (HAX_RAW_HTML_ALLOWED == false) { error($err[4], $parser, $line); } // raw html not allowed $raw = new HAW_raw(HAW_HTML, ""); } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "wml") { if (HAX_RAW_WML_ALLOWED == false) { error($err[4], $parser, $line); } // raw wml not allowed $raw = new HAW_raw(HAW_WML, ""); } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "hdml") { if (HAX_RAW_HDML_ALLOWED == false) { error($err[4], $parser, $line); } // raw hdml not allowed $raw = new HAW_raw(HAW_HDML, ""); } elseif (strtolower($attrs["MARKUP_LANGUAGE"]) == "voicexml") { if (HAX_RAW_VXML_ALLOWED == false) { error($err[4], $parser, $line); } // raw VoiceXML not allowed $raw = new HAW_raw(HAW_VXML, ""); } else { error("<raw> " . $err[14] . " markup_language", $parser, $line); } // invalid markup_language attribute $tag_stack->push($raw, HAX_TAG_RAW); $raw_mode = true; } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_raw object $raw = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck or HAW_form) $base_element = $element["element"]; $base_element->add_raw($raw); // add HAW_raw to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object $raw_mode = false; } break; case "PLUGIN": if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_RAW, $parser); if (!isset($attrs["NAME"])) { error("<plugin> " . $err[7] . " name", $parser, $line); } // markup_language attribute is missing // determine filename of plugin php script // must be located in the same directory as hawxy.php $plugin_filename = dirname(__FILE__) . '/' . HAX_PLUGIN_PREFIX . $attrs["NAME"] . '.php'; // security check 1: test if plugin file exists if (!file_exists($plugin_filename)) { error($err[15] . $attrs["NAME"], $parser, $line); } // plugin not found // setup php instructions $php_cmd = "require_once(\"{$plugin_filename}\");" . '$udef = new ' . HAX_PLUGIN_PREFIX . $attrs["NAME"] . "();"; while (list($key, $val) = each($attrs)) { // security check 2: allow alphanumeric characters only! $param = preg_replace('/[^\\w]/', "", $val); if (strtolower($key) != "name") { $php_cmd .= '$udef->set_' . strtolower($key) . '(\'' . $param . '\');'; } } // create user-defined object and call set methods if (eval($php_cmd) === false) { // eval might exit silently in case of fatal errors within the plugin! error($err[16] . " " . $attrs["NAME"], $parser, $line); } // error in plugin's php code $tag_stack->push($udef, HAX_TAG_PLUGIN); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_plugin object $udef = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck or HAW_form) $base_element = $element["element"]; $base_element->add_userdefined($udef); // add HAW_plugin to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; default: if ($raw_mode == true) { // only in raw mode unknown tags will be handled $element = $tag_stack->pop(); if ($element["tag"] == HAX_TAG_RAW) { if ($pos == HAX_PARSE_BEGIN) { // copy opening (raw) tag with all its attributes $element["element"]->code .= "<" . strtolower($name); while (list($key, $value) = each($attrs)) { $element["element"]->code .= " " . strtolower($key) . "=\"" . $value . "\""; } $element["element"]->code .= ">"; } else { // HAX_PARSE_END $element["element"]->code .= "</" . strtolower($name) . ">"; } } $tag_stack->push($element["element"], $element["tag"]); } break; } }