/** * See if the current URL matches the given ocPortal match tags. * * @param string Match tags * @param boolean Check against POSTed data too * @return boolean Whether there is a match */ function match_key_match($match_tag, $support_post = false) { $req_func = $support_post ? 'either_param' : 'get_param'; $potentials = explode(',', $match_tag); foreach ($potentials as $potential) { $parts = explode(':', $potential); if ($parts[0] == '_WILD' || $parts[0] == '_SEARCH') { $parts[0] = get_zone_name(); } if (!array_key_exists(1, $parts) || $parts[1] == '_WILD') { $parts[1] = get_page_name(); } if ($parts[0] == 'site' && get_option('collapse_user_zones') == '1') { $parts[0] = ''; } $zone_matches = $parts[0] == get_zone_name() || strpos($parts[0], '*') !== false && simulated_wildcard_match(get_zone_name(), $parts[0], true); $page_matches = $parts[1] == get_page_name() || strpos($parts[1], '*') !== false && simulated_wildcard_match(get_page_name(), $parts[1], true); if ($zone_matches && $page_matches) { $bad = false; for ($i = 2; $i < count($parts); $i++) { if ($parts[$i] != '') { if ($i == 2 && strpos($parts[$i], '=') === false) { $parts[$i] = 'type=' . $parts[$i]; } elseif ($i == 3 && strpos($parts[$i], '=') === false) { $parts[$i] = 'id=' . $parts[$i]; } } $subparts = explode('=', $parts[$i]); if (count($subparts) != 2 || call_user_func_array($req_func, array($subparts[0], 'misc')) != $subparts[1]) { $bad = true; continue; } } if (!$bad) { return true; } } } return false; }
/** * Standard PHP XML parser function. * * @param object The parser object (same as 'this') * @param string The name of the element found * @param array Array of attributes of the element */ function startElement($parser, $tag, $_attributes) { unset($parser); array_push($this->tag_stack, $tag); $attributes = array(); foreach ($_attributes as $key => $val) { $attributes[strtolower($key)] = $val; } array_push($this->attribute_stack, $attributes); switch (strtolower($tag)) { case 'qualify': if ($this->levels_from_filtered == 0) { $applies = true; if ($applies) { if (array_key_exists('pages', $attributes)) { $applies = false; $pages = explode(',', $attributes['pages']); foreach ($pages as $page) { if (simulated_wildcard_match($this->this_page, trim($page), true)) { $applies = true; } } } } if ($applies) { if (array_key_exists('types', $attributes)) { $applies = false; $types = explode(',', $attributes['types']); foreach ($types as $type) { if (simulated_wildcard_match($this->this_type, trim($type), true)) { $applies = true; } } } } if (!array_key_exists('fields', $attributes)) { $attributes['fields'] = '*'; } array_push($this->field_qualification_stack, $attributes['fields']); if (!$applies) { $this->levels_from_filtered = 1; } } elseif ($this->levels_from_filtered != 0) { $this->levels_from_filtered++; } break; case 'filter': if ($this->levels_from_filtered == 0) { $applies = true; if (array_key_exists('notstaff', $attributes) && $attributes['notstaff'] == '1' && isset($GLOBALS['FORUM_DRIVER']) && $GLOBALS['FORUM_DRIVER']->is_staff(get_member())) { $applies = false; } if ($applies) { if (array_key_exists('groups', $attributes)) { $applies = false; $members_groups = $GLOBALS['FORUM_DRIVER']->get_members_groups(get_member()); $groups = explode(',', $attributes['groups']); foreach ($groups as $group) { if (in_array(intval(trim($group)), $members_groups)) { $applies = true; } } } } if ($applies) { if (array_key_exists('members', $attributes)) { $applies = false; $members = explode(',', $attributes['members']); foreach ($members as $member) { if (intval(trim($member)) == get_member()) { $applies = true; } } } } if (!$applies) { $this->levels_from_filtered = 1; } } elseif ($this->levels_from_filtered != 0) { $this->levels_from_filtered++; } break; default: if ($this->levels_from_filtered != 0) { $this->levels_from_filtered++; } break; } $this->text_so_far = ''; }
/** * Return the contents of the given directory in $this->virtual_fs (i.e. ls without the fancy bits). * * @param ?array Directory (NULL: current directory is used) * @param boolean Whether to use full paths * @return ~array Directory contents (false: failure) */ function _get_current_dir_contents($dir = NULL, $full_paths = false) { if (is_null($dir)) { $dir = $this->pwd; } if (strpos(implode('/', $dir), '*') !== false) { $end_bit = array_pop($dir); // Remove last element $dir_remaining = implode('/', $dir); if ($dir_remaining == '') { $dir_remaining = '/'; } $ret = array(); if (strpos($dir_remaining, '*') !== false) { $before = $this->_get_current_dir_contents($dir, true); foreach ($before as $entry) { $_ret = $this->_get_current_dir_contents(array_merge(explode('/', $entry), array($end_bit)), $full_paths); if ($_ret !== false) { $ret = array_merge($ret, $_ret); } } } else { $before = $this->_get_current_dir_contents($dir, $full_paths); foreach ($before as $i => $entry) { if (is_array($entry)) { $entry = $i; } if (simulated_wildcard_match($entry, $end_bit, true)) { $ret[] = preg_replace('#^.*/#', '', $entry); } } } return $ret; } $meta_dir = array(); $meta_root_node = ''; $meta_root_node_type = ''; $current_dir = $this->_discern_meta_dir($meta_dir, $meta_root_node, $meta_root_node_type, $dir); if (!is_null($meta_root_node)) { //We're underneath a meta root node (a directory which is generated dynamically) require_code('hooks/modules/admin_occle_fs/' . filter_naughty_harsh($meta_root_node_type)); $object = object_factory('Hook_' . filter_naughty_harsh($meta_root_node_type)); $current_dir = $object->listing($meta_dir, $meta_root_node, array(), $this); if ($full_paths) { foreach ($current_dir as $i => $d) { $current_dir[$i] = implode('/', $dir) . '/' . $d; } } } return $current_dir; }
/** * Check the specified text ($a) for banned words. * If any are found, and the member cannot bypass the word filter, an error message is displayed. * * @param string The sentence to check * @param ?ID_TEXT The name of the parameter this is coming from. Certain parameters are not checked, for reasons of efficiency (avoiding loading whole word check list if not needed) (NULL: don't know param, do not check to avoid) * @param boolean Whether to avoid dying on fully blocked words (useful if importing, for instance) * @param boolean Whether to try pattern matching (this takes more resources) * @param boolean Whether to allow permission-based skipping, and length-based skipping * @return string "Fixed" version */ function check_word_filter($a, $name = NULL, $no_die = false, $try_patterns = false, $perm_check = true) { global $WORD_FILTERING_ALREADY; if ($WORD_FILTERING_ALREADY) { return $a; } if ($perm_check) { if (strlen($a) < 3) { return $a; } if (function_exists('has_specific_permission') && $GLOBALS['MICRO_AJAX_BOOTUP'] == 0 && has_specific_permission(get_member(), 'bypass_word_filter')) { return $a; } } // Load filter global $WORDS_TO_FILTER; if (is_null($WORDS_TO_FILTER)) { $WORDS_TO_FILTER = array(); $rows = $GLOBALS['SITE_DB']->query_select('wordfilter', array('*'), NULL, '', NULL, NULL, true); if (!is_null($rows)) { foreach ($rows as $i => $r) { if ($i == 0 && !array_key_exists('w_replacement', $r)) { return $a; } // Safe upgrading $WORDS_TO_FILTER[strtolower($r['word'])] = $r; } } } // Find words $words = str_word_count($a, 2); if (is_null($words)) { $words = array(); } // HPHP issue #113 // Apply filter for complete blocked words $changes = array(); foreach ($words as $pos => $word) { if (array_key_exists(strtolower($word), $WORDS_TO_FILTER) && $WORDS_TO_FILTER[strtolower($word)]['w_substr'] == 0) { $w = $WORDS_TO_FILTER[strtolower($word)]; if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); // In soviet Russia, words filter you } else { $changes[] = array($pos, $word, $w['w_replacement']); } } if ($try_patterns) { // Now try patterns foreach ($WORDS_TO_FILTER as $word2 => $w) { if ($w['w_substr'] == 0 && simulated_wildcard_match($word, $word2, true)) { if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); // In soviet Russia, words filter you } else { $changes[] = array($pos, $word, $w['w_replacement']); } } } } } // Make changes $changes = array_reverse($changes); foreach ($changes as $change) { $before = substr($a, 0, $change[0]); $after = substr($a, $change[0] + strlen($change[1])); $a = $before . $change[2] . $after; } // Apply filter for disallowed substrings foreach ($WORDS_TO_FILTER as $word => $w) { if ($w['w_substr'] == 1 && strpos($a, $word) !== false) { if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); } else { $a = preg_replace('#' . preg_quote($word) . '#i', $w['w_replacement'], $a); } } } return $a; }
/** * Get the value of a scoped field restriction property. Returns "first-found". * * @param string The name of the property * @param string The name of the field it's scoped for * @param ?string The page name scoped for (NULL: current page) * @param ?string The page type scoped for (NULL: current type) * @return ?string The property (NULL: non-existant) */ function get_field_restrict_property($property, $field, $page = NULL, $type = NULL) { if (is_null($page)) { $page = get_page_name(); } if (is_null($type)) { $type = get_param('type', post_param('type', 'misc')); } $restrictions = load_field_restrictions($page, $type); foreach ($restrictions as $_r => $_restrictions) { $_r_exp = explode(',', $_r); foreach ($_r_exp as $__r) { if (simulated_wildcard_match($field, trim($__r), true)) { foreach ($_restrictions as $bits) { list($restriction, $attributes) = $bits; if (strtolower($restriction) == strtolower($field)) { return $bits['embed']; } } } } } return NULL; }
/** * Execute an expression. * * @param array The expression * @param array Bindings available in the execution scope * @param string Query that was executed * @return ?mixed The result (NULL: error/NULL) */ function _execute_expression($expr, $bindings, $query) { switch ($expr[0]) { case 'BRACKETED': return $this->_execute_expression($expr[1], $bindings, $query); case 'LITERAL': return $expr[1]; case 'NULL': return NULL; case 'FIELD': //if (!array_key_exists($expr[1],$bindings)) {@var_dump($bindings);exit($expr[1]);} // Useful for debugging return $bindings[$expr[1]]; case '+': return $this->_execute_expression($expr[1], $bindings, $query) + $this->_execute_expression($expr[2], $bindings, $query); case '-': return $this->_execute_expression($expr[1], $bindings, $query) - $this->_execute_expression($expr[2], $bindings, $query); case '*': return $this->_execute_expression($expr[1], $bindings, $query) * $this->_execute_expression($expr[2], $bindings, $query); case '/': return $this->_execute_expression($expr[1], $bindings, $query) / $this->_execute_expression($expr[2], $bindings, $query); case '>': return $this->_execute_expression($expr[1], $bindings, $query) > $this->_execute_expression($expr[2], $bindings, $query); case '<': return $this->_execute_expression($expr[1], $bindings, $query) < $this->_execute_expression($expr[2], $bindings, $query); case '>=': return $this->_execute_expression($expr[1], $bindings, $query) >= $this->_execute_expression($expr[2], $bindings, $query); case '<=': return $this->_execute_expression($expr[1], $bindings, $query) <= $this->_execute_expression($expr[2], $bindings, $query); case '=': $a = $this->_execute_expression($expr[1], $bindings, $query); $b = $this->_execute_expression($expr[2], $bindings, $query); if ($expr[1][0] == 'FIELD' && $expr[1][0] == 'FIELD') { if (is_integer($a) && !is_integer($b)) { $a = strval($a); } elseif (!is_integer($a) && is_integer($b)) { $b = strval($b); } } return $a == $b; case '<>': return $this->_execute_expression($expr[1], $bindings, $query) != $this->_execute_expression($expr[2], $bindings, $query); case 'LIKE': $value = $this->_execute_expression($expr[1], $bindings, $query); $expr_eval = $this->_execute_expression($expr[2], $bindings, $query); return simulated_wildcard_match($value, $expr_eval, true); case 'EXISTS': return count($expr[1]) != 0; case 'NOT': return !$this->_execute_expression($expr[1], $bindings, $query); case 'AND': return $this->_execute_expression($expr[1], $bindings, $query) && $this->_execute_expression($expr[2], $bindings, $query); case 'OR': return $this->_execute_expression($expr[1], $bindings, $query) || $this->_execute_expression($expr[2], $bindings, $query); case 'IS_NULL': return is_null($this->_execute_expression($expr[1], $bindings, $query)); case 'IS_NOT_NULL': return !is_null($this->_execute_expression($expr[1], $bindings, $query)); case 'BETWEEN': $comp = $this->_execute_expression($expr[1], $bindings, $query); return $comp >= $this->_execute_expression($expr[2], $bindings, $query) && $comp <= $this->_execute_expression($expr[3], $bindings, $query); case 'REPLACE': return str_replace($this->_execute_expression($expr[2], $bindings, $query), $this->_execute_expression($expr[3], $bindings, $query), $this->_execute_expression($expr[1], $bindings, $query)); case 'CONCAT': return $this->_execute_expression($expr[1], $bindings, $query) . $this->_execute_expression($expr[2], $bindings, $query); case 'LENGTH': return strlen($this->_execute_expression($expr[1], $bindings, $query)); case 'IN': $val = $this->_execute_expression($expr[1], $bindings, $query); foreach ($expr[2] as $in) { if ($val == $in) { return true; } } return false; } $this->_bad_query($query, false, 'Internal error evaluating expression, ' . $expr[0] . ' not recognised in evaluation context'); return NULL; }
/** * Perform a database-style in-memory boolean search on single item. * * @param array A map of POST data in search-form style. May contain 'only_titles', 'content' (the critical one!) and 'conjunctive_operator' * @param string The title to try and match * @param ?string The post to try and match (NULL: not used) * @return boolean Whether we have a match */ function in_memory_search_match($filter, $title, $post = NULL) { if (!array_key_exists('content', $filter) || $filter['content'] == '') { return true; } $search_filter = $filter['content']; if (array_key_exists('only_titles', $filter) && $filter['only_titles'] == 1 || is_null($post)) { $context = $title; } else { $context = $title . ' ' . $post; } $boolean_operator = array_key_exists('conjunctive_operator', $filter) ? $filter['conjunctive_operator'] : 'OR'; list($body_words, $include_words, $disclude_words) = _boolean_search_prepare($search_filter); foreach ($include_words as $word) { if (!simulated_wildcard_match($context, $word)) { return false; } } foreach ($disclude_words as $word) { if (simulated_wildcard_match($context, $word)) { return false; } } if ($boolean_operator == 'OR') { $count = 0; foreach ($body_words as $word) { if (simulated_wildcard_match($context, $word)) { $count++; } } if ($count == 0) { return false; } } else { foreach ($body_words as $word) { if (!simulated_wildcard_match($context, $word)) { return false; } } } return true; }