'Opn', 'Not a bug' => 'Nab', 'Feedback' => 'Fbk', 'No Feedback' => 'NoF', 'Wont fix' => 'Wfx', 'Duplicate' => 'Dup', 'Critical' => 'Ctl', 'Assigned' => 'Asn', 'Analyzed' => 'Ana', 'Verified' => 'Ver', 'Suspended' => 'Sus', 'Closed' => 'Csd', 'Spam' => 'Spm', 'Re-Opened' => 'ReO', ); $bug_types = array( 'Bug' => 'Bug', 'Feature/Change Request' => 'Req', 'Documentation Problem' => 'Doc', 'Security' => 'Sec Bug' ); $project_types = array( 'PHP' => 'php', 'PECL' => 'pecl' ); // Used in show_state_options() $state_types = array ( 'Open' => 2, 'Closed' => 2, 'Re-Opened' => 1, 'Duplicate' => 1, 'Critical' => 1, 'Assigned' => 2, 'Not Assigned' => 0, 'Analyzed' => 1, 'Verified' => 1, 'Suspended' => 1, 'Wont fix' => 1, 'No Feedback' => 1, 'Feedback' => 1, 'Old Feedback' => 0, 'Stale' => 0, 'Fresh' => 0, 'Not a bug' => 1, 'Spam' => 1, 'All' => 0, ); /** * Authentication */ function verify_password($user, $pass) { global $errors; $post = http_build_query( array( 'token' => getenv('AUTH_TOKEN'), 'username' => $user, 'password' => $pass, ) ); $opts = array( 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $post, ); $ctx = stream_context_create(array('http' => $opts)); $s = file_get_contents('https://master.php.net/fetch/cvsauth.php', false, $ctx); $a = @unserialize($s); if (!is_array($a)) { $errors[] = "Failed to get authentication information.\nMaybe master is down?\n"; return false; } if (isset($a['errno'])) { $errors[] = "Authentication failed: {$a['errstr']}\n"; return false; } $_SESSION["user"] = $user; return true; } function bugs_has_access ($bug_id, $bug, $pw, $user_flags) { global $auth_user; if ($bug['private'] != 'Y') { return true; } // When the bug is private, only the submitter, trusted devs, security devs and assigned dev // should see the report info if ($user_flags & (BUGS_SECURITY_DEV | BUGS_TRUSTED_DEV)) { // trusted and security dev return true; } else if (($user_flags == BUGS_NORMAL_USER) && $pw != '' && verify_bug_passwd($bug_id, bugs_get_hash($pw))) { // The submitter return true; } else if (($user_flags & BUGS_DEV_USER) && $bug['reporter_name'] != '' && strtolower($bug['reporter_name']) == strtolower($auth_user->handle)) { // The submitter (php developer) return true; } else if (($user_flags & BUGS_DEV_USER) && $bug['assign'] != '' && strtolower($bug['assign']) == strtolower($auth_user->handle)) { // The assigned dev return true; } return false; } function bugs_authenticate (&$user, &$pw, &$logged_in, &$user_flags) { global $auth_user, $ROOT_DIR; // Default values $user = ''; $pw = ''; $logged_in = false; $user_flags = BUGS_NORMAL_USER; // Set username and password if (!empty($_POST['pw'])) { if (empty($_POST['user'])) { $user = ''; } else { $user = htmlspecialchars($_POST['user']); } $user = strtolower($user); $pw = $_POST['pw']; } elseif (isset($auth_user) && is_object($auth_user) && $auth_user->handle) { $user = $auth_user->handle; $pw = $auth_user->password; } // Authentication and user level check // User levels are: reader (0), commenter/patcher/etc. (edit = 3), submitter (edit = 2), developer (edit = 1) if (!empty($_SESSION["user"])) { $user = $_SESSION["user"]; $user_flags = BUGS_DEV_USER; $logged_in = 'developer'; $auth_user = new stdClass; $auth_user->handle = $user; $auth_user->email = "{$user}@php.net"; $auth_user->name = $user; } elseif ($user != '' && $pw != '' && verify_password($user, $pw)) { $user_flags = BUGS_DEV_USER; $logged_in = 'developer'; $auth_user = new stdClass; $auth_user->handle = $user; $auth_user->email = "{$user}@php.net"; $auth_user->name = $user; } else { $auth_user = new stdClass; $auth_user->email = isset($_POST['in']['email']) ? $_POST['in']['email'] : ''; $auth_user->handle = ''; $auth_user->name = ''; } // Check if developer is trusted if ($logged_in == 'developer') { require_once "{$ROOT_DIR}/include/trusted-devs.php"; if (in_array(strtolower($user), $trusted_developers)) { $user_flags |= BUGS_TRUSTED_DEV; } if (in_array(strtolower($user), $security_developers)) { $user_flags |= BUGS_SECURITY_DEV; } } } /** * Fetches pseudo packages from database * * @param string $project define what project pseudo packages are returned * @param bool $return_disabled whether to return read-only items, defaults to true * * @return array array of pseudo packages */ function get_pseudo_packages($project, $return_disabled = true) { global $dbh, $project_types; $pseudo_pkgs = $nodes = $tree = array(); $where = '1=1'; $project = strtolower($project); if ($project !== false && in_array($project, $project_types)) { $where .= " AND project IN ('', '$project')"; } if (!$return_disabled) { $where.= " AND disabled = 0"; } $data = $dbh->queryAll("SELECT * FROM bugdb_pseudo_packages WHERE $where ORDER BY parent, disabled, id", null, MDB2_FETCHMODE_ASSOC); // Convert flat array to nested strucutre foreach ($data as &$node) { $node['children'] = array(); $id = $node['id']; $parent_id = $node['parent']; $nodes[$id] =& $node; if (array_key_exists($parent_id, $nodes)) { $nodes[$parent_id]['children'][] =& $node; } else { $tree[] =& $node; } } foreach ($tree as $data) { if (isset($data['children'])) { $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); $long_names = array(); foreach ($data['children'] as $k => $v) { $long_names[$k] = strtolower($v['long_name']); } array_multisort($long_names, SORT_ASC, SORT_STRING, $data['children']); foreach ($data['children'] as $child) { $pseudo_pkgs[$child['name']] = array("    {$child['long_name']}", $child['disabled']); } } elseif (!isset($pseudo_pkgs[$data['name']])) { $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); } } return $pseudo_pkgs; } /* Primitive check for SPAM. Add more later. */ function is_spam($string) { // @php.net users are given permission to spam... we gotta eat! See also bug #48126 if (!empty($GLOBALS['auth_user']->handle)) { return false; } if (substr_count(strtolower($string), 'http://') > 5) { return true; } $keywords = array( 'spy', 'bdsm', 'massage', 'mortage', 'sex', '11nong', 'oxycontin', 'distance-education', 'sismatech', 'justiceplan', 'prednisolone', 'baclofen', 'diflucan', 'unbra.se', 'objectis', 'angosso', 'colchicine', 'zovirax', 'korsbest', 'coachbags', 'chaneljpoutlet', '\/Members\/', 'michaelkorsshop', 'mkmichaelkors', 'Burberrysale4u', 'gadboisphotos', 'oakleysunglasseslol', 'partydressuk', 'leslunettesdesoleil', 'PaulRGuthrie', '[a-z]*?fuck[a-z]*?', 'jerseys', 'wholesale', 'fashionretailshop01', ); if (preg_match('/\b('. implode('|', $keywords) . ')\b/i', $string)) { return true; } return false; } /** * Obfuscates email addresses to hinder spammer's spiders * * Turns "@" into character entities that get interpreted as "at" and * turns "." into character entities that get interpreted as "dot". * * @param string $txt the email address to be obfuscated * @param string $format how the output will be displayed ('html', 'text', 'reverse') * * @return string the altered email address */ function spam_protect($txt, $format = 'html') { /* php.net addresses are not protected! */ if (preg_match('/^(.+)@php\.net$/i', $txt)) { return $txt; } if ($format == 'html') { $translate = array( '@' => ' at ', '.' => ' dot ', ); } else { $translate = array( '@' => ' at ', '.' => ' dot ', ); if ($format == 'reverse') { $translate = array_flip($translate); } } return strtr($txt, $translate); } /** * Escape strings so they can be used as literals in queries * * @param string|array $in data to be sanitized. If it's an array, each element is sanitized. * * @return string|array the sanitized data * * @see oneof(), field(), txfield() */ function escapeSQL($in) { global $dbh; if (is_array($in)) { $out = array(); foreach ($in as $key => $value) { $out[$key] = $dbh->escape($value); } return $out; } else { return $dbh->escape($in); } } /** * Goes through each variable submitted and returns the value * from the first variable which has a non-empty value * * Handy function for when you're dealing with user input or a default. * * @param mixed as many variables as you wish to check * * @return mixed the value, if any * * @see escapeSQL(), field(), txfield() */ function oneof() { foreach (func_get_args() as $arg) { if ($arg) { return $arg; } } } /** * Returns the data from the field requested and sanitizes * it for use as HTML * * If the data from a form submission exists, that is used. * But if that's not there, the info is obtained from the database. * * @param string $n the name of the field to be looked for * * @return mixed the data requested * * @see escapeSQL(), oneof(), txfield() */ function field($n) { return oneof(isset($_POST['in']) ? htmlspecialchars(isset($_POST['in'][$n]) ? $_POST['in'][$n] : '') : null, htmlspecialchars($GLOBALS['bug'][$n])); } /** * Escape string so it can be used as HTML * * @param string $in the string to be sanitized * * @return string the sanitized string * * @see txfield() */ function clean($in) { return mb_encode_numericentity($in, array( 0x0, 0x8, 0, 0xffffff, 0xb, 0xc, 0, 0xffffff, 0xe, 0x1f, 0, 0xffffff, 0x22, 0x22, 0, 0xffffff, 0x26, 0x27, 0, 0xffffff, 0x3c, 0x3c, 0, 0xffffff, 0x3e, 0x3e, 0, 0xffffff, 0x7f, 0x84, 0, 0xffffff, 0x86, 0x9f, 0, 0xffffff, 0xfdd0, 0xfdef, 0, 0xffffff, 0x1fffe, 0x1ffff, 0, 0xffffff, 0x2fffe, 0x2ffff, 0, 0xffffff, 0x3fffe, 0x3ffff, 0, 0xffffff, 0x4fffe, 0x4ffff, 0, 0xffffff, 0x5fffe, 0x5ffff, 0, 0xffffff, 0x6fffe, 0x6ffff, 0, 0xffffff, 0x7fffe, 0x7ffff, 0, 0xffffff, 0x8fffe, 0x8ffff, 0, 0xffffff, 0x9fffe, 0x9ffff, 0, 0xffffff, 0xafffe, 0xaffff, 0, 0xffffff, 0xbfffe, 0xbffff, 0, 0xffffff, 0xcfffe, 0xcffff, 0, 0xffffff, 0xdfffe, 0xdffff, 0, 0xffffff, 0xefffe, 0xeffff, 0, 0xffffff, 0xffffe, 0xfffff, 0, 0xffffff, 0x10fffe, 0x10ffff, 0, 0xffffff, ), 'UTF-8'); } /** * Returns the data from the field requested and sanitizes * it for use as plain text * * If the data from a form submission exists, that is used. * But if that's not there, the info is obtained from the database. * * @param string $n the name of the field to be looked for * * @return mixed the data requested * * @see clean() */ function txfield($n, $bug = null, $in = null) { $one = (isset($in) && isset($in[$n])) ? $in[$n] : false; if ($one) { return $one; } $two = (isset($bug) && isset($bug[$n])) ? $bug[$n] : false; if ($two) { return $two; } } /** * Prints age \n"; } echo '\n"; } /** * Prints bug project \n"; } elseif (!$current) { $current = 'bug'; } foreach ($bug_types as $k => $v) { $selected = strcasecmp($current, $k) ? '' : ' selected="selected"'; $k = htmlentities($k, ENT_QUOTES); echo ""; } } /** * Prints bug state ' . "\n"; } foreach ($RESOLVE_REASONS as $val) { if (empty($val['package_name'])) { $sel = ($current == $val['name']) ? " selected='selected'" : ''; echo "\n"; } } } /** * Prints PHP version number \n"; } elseif (!$current && $show_any == 1) { $current = 'Any'; } elseif (!$current) { $current = $default; } if (!is_array($bug_items)) { return; } foreach ($bug_items as $key => $value) { if ($show_any == 1 || $key != 'Any') { echo "\n"; } } } /** * Prints a series of radio inputs to determine how the search * term should be looked for * * @param string $current the users present selection * * @return void */ function show_boolean_options($current) { $options = array('any', 'all', 'raw'); while (list($val, $type) = each($options)) { echo '$type \n"; } } /** * Display errors or warnings as a