/** * Makes sure that the PRNG has been seeded with a fairly secure value * * @return void */ private static function seedRandom() { static $seeded = FALSE; if ($seeded) { return; } $old_level = error_reporting(error_reporting() & ~E_WARNING); $bytes = NULL; // On linux/unix/solaris we should be able to use /dev/urandom if (!fCore::checkOS('windows') && ($handle = fopen('/dev/urandom', 'rb'))) { $bytes = fread($handle, 32); fclose($handle); // On windows we should be able to use the Cryptographic Application Programming Interface COM object } elseif (fCore::checkOS('windows') && class_exists('COM', FALSE)) { try { // This COM object no longer seems to work on PHP 5.2.9+, no response on the bug report yet $capi = new COM('CAPICOM.Utilities.1'); $bytes = base64_decode($capi->getrandom(32, 0)); unset($capi); } catch (Exception $e) { } } // If we could not use the OS random number generators we get some of the most unique info we can if (!$bytes) { $bytes = microtime(TRUE) . uniqid('', TRUE) . join('', stat(__FILE__)) . disk_free_space(__FILE__); } error_reporting($old_level); $seed = md5($bytes); $seed = base_convert($seed, 16, 10); $seed = (double) substr($seed, 0, 13) + (double) substr($seed, 14, 13); mt_srand($seed); $seeded = TRUE; }
/** * Connects to the database specified if no connection exists * * @return void */ private function connectToDatabase() { // Don't try to reconnect if we are already connected if ($this->connection) { return; } // Establish a connection to the database if ($this->extension == 'pdo') { $odbc = strtolower(substr($this->database, 0, 4)) == 'dsn:'; if ($this->type == 'mssql') { if ($odbc) { $dsn = 'odbc:' . substr($this->database, 4); } else { $separator = fCore::checkOS('windows') ? ',' : ':'; $port = $this->port ? $separator . $this->port : ''; $driver = fCore::checkOs('windows') ? 'mssql' : 'dblib'; $dsn = $driver . ':host=' . $this->host . $port . ';dbname=' . $this->database; } } elseif ($this->type == 'mysql') { if (substr($this->host, 0, 5) == 'sock:') { $dsn = 'mysql:unix_socket=' . substr($this->host, 5) . ';dbname=' . $this->database; } else { $port = $this->port ? ';port=' . $this->port : ''; $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->database . $port; } } elseif ($this->type == 'oracle') { if ($odbc) { $dsn = 'odbc:' . substr($this->database, 4); } else { $port = $this->port ? ':' . $this->port : ''; $dsn = 'oci:dbname=' . $this->host . $port . '/' . $this->database . ';charset=AL32UTF8'; } } elseif ($this->type == 'postgresql') { $dsn = 'pgsql:dbname=' . $this->database; if ($this->host && $this->host != 'sock:') { $dsn .= ' host=' . $this->host; } if ($this->port) { $dsn .= ' port=' . $this->port; } } elseif ($this->type == 'sqlite') { $dsn = 'sqlite:' . $this->database; } try { $this->connection = new PDO($dsn, $this->username, $this->password); if ($this->type == 'mysql') { $this->connection->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); } } catch (PDOException $e) { $this->connection = FALSE; } } if ($this->extension == 'sqlite') { $this->connection = sqlite_open($this->database); } if ($this->extension == 'mssql') { $separator = fCore::checkOS('windows') ? ',' : ':'; $this->connection = mssql_connect($this->port ? $this->host . $separator . $this->port : $this->host, $this->username, $this->password); if ($this->connection !== FALSE && mssql_select_db($this->database, $this->connection) === FALSE) { $this->connection = FALSE; } } if ($this->extension == 'mysql') { if (substr($this->host, 0, 5) == 'sock:') { $host = substr($this->host, 4); } elseif ($this->port) { $host = $this->host . ':' . $this->port; } else { $host = $this->host; } $this->connection = mysql_connect($host, $this->username, $this->password); if ($this->connection !== FALSE && mysql_select_db($this->database, $this->connection) === FALSE) { $this->connection = FALSE; } } if ($this->extension == 'mysqli') { if (substr($this->host, 0, 5) == 'sock:') { $this->connection = mysqli_connect('localhost', $this->username, $this->password, $this->database, $this->port, substr($this->host, 5)); } elseif ($this->port) { $this->connection = mysqli_connect($this->host, $this->username, $this->password, $this->database, $this->port); } else { $this->connection = mysqli_connect($this->host, $this->username, $this->password, $this->database); } } if ($this->extension == 'oci8') { $this->connection = oci_connect($this->username, $this->password, $this->host . ($this->port ? ':' . $this->port : '') . '/' . $this->database, 'AL32UTF8'); } if ($this->extension == 'odbc') { $this->connection = odbc_connect(substr($this->database, 4), $this->username, $this->password); } if ($this->extension == 'pgsql') { $connection_string = "dbname='" . addslashes($this->database) . "'"; if ($this->host && $this->host != 'sock:') { $connection_string .= " host='" . addslashes($this->host) . "'"; } if ($this->username) { $connection_string .= " user='******'"; } if ($this->password) { $connection_string .= " password='******'"; } if ($this->port) { $connection_string .= " port='" . $this->port . "'"; } $this->connection = pg_connect($connection_string); } if ($this->extension == 'sqlsrv') { $options = array('Database' => $this->database, 'UID' => $this->username, 'PWD' => $this->password); $this->connection = sqlsrv_connect($this->host, $options); } // Ensure the connection was established if ($this->connection === FALSE) { throw new fConnectivityException('Unable to connect to database'); } // Make MySQL act more strict and use UTF-8 if ($this->type == 'mysql') { $this->query("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'"); $this->query("SET NAMES 'utf8'"); $this->query("SET CHARACTER SET utf8"); } // Make SQLite behave like other DBs for assoc arrays if ($this->type == 'sqlite') { $this->query('PRAGMA short_column_names = 1'); } // Fix some issues with mssql if ($this->type == 'mssql') { if (!isset($this->schema_info['character_set'])) { $this->determineCharacterSet(); } $this->query('SET TEXTSIZE 65536'); } // Make PostgreSQL use UTF-8 if ($this->type == 'postgresql') { $this->query("SET NAMES 'UTF8'"); } // Oracle has different date and timestamp defaults if ($this->type == 'oracle') { $this->query("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'"); $this->query("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"); $this->query("ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZR'"); $this->query("ALTER SESSION SET NLS_TIME_FORMAT = 'HH24:MI:SS'"); $this->query("ALTER SESSION SET NLS_TIME_TZ_FORMAT = 'HH24:MI:SS TZR'"); } }
/** * Reads responses from the server * * @param integer|string $expect The expected number of lines of response or a regex of the last line * @return array The lines of response from the server */ private function read($expect = NULL) { $read = array($this->connection); $write = NULL; $except = NULL; $response = array(); // PHP 5.2.0 to 5.2.5 has a bug on amd64 linux where stream_select() // fails, so we have to fake it - http://bugs.php.net/bug.php?id=42682 static $broken_select = NULL; if ($broken_select === NULL) { $broken_select = strpos(php_uname('m'), '64') !== FALSE && fCore::checkVersion('5.2.0') && !fCore::checkVersion('5.2.6'); } // Fixes an issue with stream_select throwing a warning on PHP 5.3 on Windows if (fCore::checkOS('windows') && fCore::checkVersion('5.3.0')) { $select = @stream_select($read, $write, $except, $this->timeout); } elseif ($broken_select) { $broken_select_buffer = NULL; $start_time = microtime(TRUE); $i = 0; do { if ($i) { usleep(50000); } $char = fgetc($this->connection); if ($char != "" && $char !== FALSE) { $broken_select_buffer = $char; } $i++; } while ($broken_select_buffer === NULL && microtime(TRUE) - $start_time < $this->timeout); $select = $broken_select_buffer !== NULL; } else { $select = stream_select($read, $write, $except, $this->timeout); } if ($select) { while (!feof($this->connection)) { $line = fgets($this->connection); if ($line === FALSE) { break; } $line = substr($line, 0, -2); // When we fake select, we have to handle what we've retrieved if ($broken_select && $broken_select_buffer !== NULL) { $line = $broken_select_buffer . $line; $broken_select_buffer = NULL; } $response[] = $line; // Automatically stop at the termination octet or a bad response if ($this->type == 'pop3' && ($line == '.' || count($response) == 1 && $response[0][0] == '-')) { break; } if ($expect !== NULL) { $matched_number = is_int($expect) && sizeof($response) == $expect; $matched_regex = is_string($expect) && preg_match($expect, $line); if ($matched_number || $matched_regex) { break; } } } } if (fCore::getDebug($this->debug)) { fCore::debug("Received:\n" . join("\r\n", $response), $this->debug); } if ($this->type == 'pop3') { // Remove the termination octet if ($response && $response[sizeof($response) - 1] == '.') { $response = array_slice($response, 0, -1); } // Remove byte-stuffing $lines = count($response); for ($i = 0; $i < $lines; $i++) { if (strlen($response[$i]) && $response[$i][0] == '.') { $response[$i] = substr($response[$i], 1); } } } return $response; }
/** * Executes an SQL query * * @param string|fStatement $statement The statement to perform * @param fResult $result The result object for the query * @param array $params The parameters for prepared statements * @return void */ private function performQuery($statement, $result, $params) { fCore::startErrorCapture(); $extra = NULL; if (is_object($statement)) { $statement->executeQuery($result, $params, $extra, $statement != $this->statement); } elseif ($this->extension == 'ibm_db2') { $extra = db2_exec($this->connection, $statement, array('cursor' => DB2_FORWARD_ONLY)); if (is_resource($extra)) { $rows = array(); while ($row = db2_fetch_assoc($extra)) { $rows[] = $row; } $result->setResult($rows); unset($rows); } else { $result->setResult($extra); } } elseif ($this->extension == 'mssql') { $result->setResult(mssql_query($result->getSQL(), $this->connection)); } elseif ($this->extension == 'mysql') { $result->setResult(mysql_query($result->getSQL(), $this->connection)); } elseif ($this->extension == 'mysqli') { $result->setResult(mysqli_query($this->connection, $result->getSQL())); } elseif ($this->extension == 'oci8') { $extra = oci_parse($this->connection, $result->getSQL()); if ($extra && oci_execute($extra, $this->inside_transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS)) { oci_fetch_all($extra, $rows, 0, -1, OCI_FETCHSTATEMENT_BY_ROW + OCI_ASSOC); $result->setResult($rows); unset($rows); } else { $result->setResult(FALSE); } } elseif ($this->extension == 'pgsql') { $result->setResult(pg_query($this->connection, $result->getSQL())); } elseif ($this->extension == 'sqlite') { $result->setResult(sqlite_query($this->connection, $result->getSQL(), SQLITE_ASSOC, $extra)); } elseif ($this->extension == 'sqlsrv') { $extra = sqlsrv_query($this->connection, $result->getSQL()); if (is_resource($extra)) { $rows = array(); while ($row = sqlsrv_fetch_array($extra, SQLSRV_FETCH_ASSOC)) { $rows[] = $row; } $result->setResult($rows); unset($rows); } else { $result->setResult($extra); } } elseif ($this->extension == 'pdo') { if (preg_match('#^\\s*CREATE(\\s+OR\\s+REPLACE)?\\s+TRIGGER#i', $result->getSQL())) { $this->connection->exec($result->getSQL()); $extra = FALSE; $returned_rows = array(); } else { $extra = $this->connection->query($result->getSQL()); if (is_object($extra)) { // This fixes a segfault issue with blobs and fetchAll() for pdo_ibm if ($this->type == 'db2') { $returned_rows = array(); while (($row = $extra->fetch(PDO::FETCH_ASSOC)) !== FALSE) { foreach ($row as $key => $value) { if (is_resource($value)) { $row[$key] = stream_get_contents($value); } } $returned_rows[] = $row; } // pdo_dblib doesn't throw an exception on error when executing // a prepared statement when compiled against FreeTDS, so we have // to manually check the error info to see if something went wrong } elseif ($this->type == 'mssql' && !fCore::checkOS('windows') && preg_match('#^\\s*EXEC(UTE)?\\s+#i', $result->getSQL())) { $error_info = $extra->errorInfo(); if ($error_info && strpos($error_info[2], '(null) [0] (severity 0)') !== 0) { $returned_rows = FALSE; } } else { $returned_rows = $extra->fetchAll(PDO::FETCH_ASSOC); } } else { $returned_rows = $extra; } // The pdo_pgsql driver likes to return empty rows equal to the number of affected rows for insert and deletes if ($this->type == 'postgresql' && $returned_rows && $returned_rows[0] == array()) { $returned_rows = array(); } } $result->setResult($returned_rows); } $this->statement = $statement; $this->handleErrors(fCore::stopErrorCapture()); // The mssql extension will sometimes not return FALSE even if there are errors if (strlen($this->error) && strpos($this->error, 'WARNING!') !== 0) { $result->setResult(FALSE); } $this->checkForError($result, $extra); if ($this->extension == 'mssql') { $this->error = ''; } if ($this->extension == 'ibm_db2') { $this->setAffectedRows($result, $extra); if ($extra && !is_object($statement)) { db2_free_result($extra); } } elseif ($this->extension == 'pdo') { $this->setAffectedRows($result, $extra); if ($extra && !is_object($statement)) { $extra->closeCursor(); } } elseif ($this->extension == 'oci8') { $this->setAffectedRows($result, $extra); if ($extra && !is_object($statement)) { oci_free_statement($extra); } } elseif ($this->extension == 'sqlsrv') { $this->setAffectedRows($result, $extra); if ($extra && !is_object($statement)) { sqlsrv_free_stmt($extra); } } else { $this->setAffectedRows($result, $extra); } $this->setReturnedRows($result); $this->handleAutoIncrementedValue($result, $extra); }
/** * Warns the user about bugs in the DBLib driver for MSSQL, fixes some bugs * * @param array $row The row from the database * @return array The fixed row */ private function fixDblibMSSQLDriver($row) { static $using_dblib = array(); if (!isset($using_dblib[$this->extension])) { // If it is not a windows box we are definitely not using dblib if (!fCore::checkOS('windows')) { $using_dblib[$this->extension] = FALSE; // Check this windows box for dblib } else { ob_start(); phpinfo(INFO_MODULES); $module_info = ob_get_contents(); ob_end_clean(); if ($this->extension == 'pdo_mssql') { $using_dblib[$this->extension] = preg_match('#MSSQL_70#i', $module_info, $match); } else { $using_dblib[$this->extension] = !preg_match('#FreeTDS#i', $module_info, $match); } } } if (!$using_dblib[$this->extension]) { return $row; } foreach ($row as $key => $value) { if ($value === ' ') { $row[$key] = ''; if (!self::$silence_notices) { trigger_error(self::compose('A single space was detected coming out of the database and was converted into an empty string - see %s for more information', 'http://bugs.php.net/bug.php?id=26315'), E_USER_NOTICE); } } if (!self::$silence_notices && strlen($key) == 30) { trigger_error(self::compose('A column name exactly 30 characters in length was detected coming out of the database - this column name may be truncated, see %s for more information.', 'http://bugs.php.net/bug.php?id=23990'), E_USER_NOTICE); } if (!self::$silence_notices && strlen($value) == 256) { trigger_error(self::compose('A value exactly 255 characters in length was detected coming out of the database - this value may be truncated, see %s for more information.', 'http://bugs.php.net/bug.php?id=37757'), E_USER_NOTICE); } } return $row; }
/** * Reads responses from the server * * @param integer|string $expect The expected number of lines of response or a regex of the last line * @return array The lines of response from the server */ private function read($expect = NULL) { $read = array($this->connection); $write = NULL; $except = NULL; $response = array(); // Fixes an issue with stream_select throwing a warning on PHP 5.3 on Windows if (fCore::checkOS('windows') && fCore::checkVersion('5.3.0')) { $select = @stream_select($read, $write, $except, $this->timeout); } else { $select = stream_select($read, $write, $except, $this->timeout); } if ($select) { while (!feof($this->connection)) { $line = substr(fgets($this->connection), 0, -2); $response[] = $line; // Automatically stop at the termination octet or a bad response if ($this->type == 'pop3' && ($line == '.' || count($response) == 1 && $response[0][0] == '-')) { break; } if ($expect !== NULL) { $matched_number = is_int($expect) && sizeof($response) == $expect; $matched_regex = is_string($expect) && preg_match($expect, $line); if ($matched_number || $matched_regex) { break; } } } } if (fCore::getDebug($this->debug)) { fCore::debug("Recieved:\n" . join("\r\n", $response), $this->debug); } if ($this->type == 'pop3') { // Remove the termination octet if ($response && $response[sizeof($response) - 1] == '.') { $response = array_slice($response, 0, -1); } // Remove byte-stuffing $lines = count($response); for ($i = 0; $i < $lines; $i++) { if (strlen($response[$i]) && $response[$i][0] == '.') { $response[$i] = substr($response[$i], 1); } } } return $response; }
/** * Sends the email * * @throws fValidationException When ::validate() throws an exception * * @return void */ public function send() { $this->validate(); $to = trim($this->buildMultiAddressHeader("", $this->to_emails)); $top_level_boundary = $this->createBoundary(); $headers = $this->createHeaders($top_level_boundary); $subject = str_replace(array("\r", "\n"), '', $this->subject); $subject = $this->makeEncodedWord($subject); $body = $this->createBody($top_level_boundary); if ($this->smime_encrypt || $this->smime_sign) { list($headers, $body) = $this->createSMIMEBody($to, $subject, $headers, $body); } // Sendmail when not in safe mode will allow you to set the envelope from address via the -f parameter $parameters = NULL; if (!fCore::checkOS('windows') && $this->bounce_to_email && !ini_get('safe_mode')) { preg_match(self::EMAIL_REGEX, $this->bounce_to_email, $matches); $parameters = '-f ' . $matches[0]; } // Windows takes the Return-Path email from the sendmail_from ini setting if (fCore::checkOS('windows') && $this->bounce_to_email) { $old_sendmail_from = ini_get('sendmail_from'); preg_match(self::EMAIL_REGEX, $this->bounce_to_email, $matches); ini_set('sendmail_from', $matches[0]); } // Apparently SMTP server strip a leading . from lines if (fCore::checkOS('windows')) { $body = str_replace("\r\n.", "\r\n..", $body); } // Remove extra line breaks $headers = trim($headers); $body = trim($body); // This is a gross qmail fix that is a last resort if (self::$popen_sendmail || self::$convert_crlf) { $to = str_replace("\r\n", "\n", $to); $subject = str_replace("\r\n", "\n", $subject); $body = str_replace("\r\n", "\n", $body); $headers = str_replace("\r\n", "\n", $headers); } // If the user is using qmail and wants to try to fix the \r\r\n line break issue if (self::$popen_sendmail) { $sendmail_command = ini_get('sendmail_path'); if ($parameters) { $sendmail_command .= ' ' . $parameters; } $sendmail_process = popen($sendmail_command, 'w'); fprintf($sendmail_process, "To: %s\n", $to); fprintf($sendmail_process, "Subject: %s\n", $subject); if ($headers) { fprintf($sendmail_process, "%s\n", $headers); } fprintf($sendmail_process, "\n%s\n", $body); $error = pclose($sendmail_process); // This is the normal way to send mail } else { $error = !mail($to, $subject, $body, $headers, $parameters); } if (fCore::checkOS('windows') && $this->bounce_to_email) { ini_set('sendmail_from', $old_sendmail_from); } if ($error) { throw new fConnectivityException('An error occured while trying to send the email entitled %s', $this->subject); } }
/** * Executes the statement without returning a result * * @internal * * @param array $params The parameters for the statement * @param mixed &$extra A variable to place extra information needed by some database extensions * @param boolean $different If this statement is different than the last statement run on the fDatabase instance * @return mixed The (usually boolean) result of the extension function/method call */ public function execute($params, &$extra, $different) { if (is_array($params) && count($params) == 1 && is_array($params[0]) && count($this->placeholders) > 1) { $params = $params[0]; } if ($different && $this->used) { $this->regenerateStatement(); } $this->used = TRUE; $extension = $this->database->getExtension(); if ($extension == 'pdo' && $this->database->getType() == 'mssql') { $extension = 'pdo_dblib'; } $connection = $this->database->getConnection(); $statement = $this->statement; $params = $this->prepareParams($params); switch ($extension) { case 'ibm_db2': $extra = $statement; $result = db2_execute($statement, $params); break; case 'mssql': $result = mssql_query($this->database->escape($statement, $params), $connection); break; case 'mysql': $result = mysql_unbuffered_query($this->database->escape($statement, $params), $connection); break; case 'mysqli': $result = mysqli_stmt_execute($statement); break; case 'oci8': $result = oci_execute($statement, $this->database->isInsideTransaction() ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS); $extra = $this->statement; break; case 'pgsql': $result = pg_execute($connection, $this->identifier, $params); break; case 'sqlite': $result = sqlite_exec($connection, $this->database->escape($statement, $params), $extra); break; case 'sqlsrv': $result = sqlsrv_execute($this->statement); break; case 'pdo': $extra = $statement; $result = $statement->execute(); break; case 'pdo_dblib': $sql = $this->database->escape($statement, $params); if (!fCore::checkOS('windows')) { $result = $connection->query($sql); if ($result instanceof PDOStatement) { $extra = $result; $result->closeCursor(); $result = TRUE; } else { $result = FALSE; } } else { $result = $connection->exec($sql); } break; } return $result; }
/** * Performs a "fixed" stream_select() for the connection * * @param integer $timeout The number of seconds in the timeout * @param integer $utimeout The number of microseconds in the timeout * @return boolean|string TRUE (or a character) is the connection is ready to be read from, FALSE if not */ private function select($timeout, $utimeout) { $read = array($this->connection); $write = NULL; $except = NULL; // PHP 5.2.0 to 5.2.5 had a bug on amd64 linux where stream_select() // fails, so we have to fake it - http://bugs.php.net/bug.php?id=42682 static $broken_select = NULL; if ($broken_select === NULL) { $broken_select = strpos(php_uname('m'), '64') !== FALSE && fCore::checkVersion('5.2.0') && !fCore::checkVersion('5.2.6'); } // Fixes an issue with stream_select throwing a warning on PHP 5.3 on Windows if (fCore::checkOS('windows') && fCore::checkVersion('5.3.0')) { $select = @stream_select($read, $write, $except, $timeout, $utimeout); } elseif ($broken_select) { $broken_select_buffer = NULL; $start_time = microtime(TRUE); $i = 0; do { if ($i) { usleep(50000); } $char = fgetc($this->connection); if ($char != "" && $char !== FALSE) { $broken_select_buffer = $char; } $i++; if ($i > 2) { break; } } while ($broken_select_buffer === NULL && microtime(TRUE) - $start_time < $timeout + $utimeout / 1000000); $select = $broken_select_buffer === NULL ? FALSE : $broken_select_buffer; } else { $select = stream_select($read, $write, $except, $timeout, $utimeout); } return $select; }
/** * Makes sure that the PRNG has been seeded with a fairly secure value * * @return void */ private static function seedRandom() { static $seeded = FALSE; if ($seeded) { return; } fCore::startErrorCapture(E_WARNING); $bytes = NULL; // On linux/unix/solaris we should be able to use /dev/urandom if (!fCore::checkOS('windows') && ($handle = fopen('/dev/urandom', 'rb'))) { $bytes = fread($handle, 4); fclose($handle); // On windows we should be able to use the Cryptographic Application Programming Interface COM object } elseif (fCore::checkOS('windows') && class_exists('COM', FALSE)) { try { // This COM object no longer seems to work on PHP 5.2.9+, no response on the bug report yet $capi = new COM('CAPICOM.Utilities.1'); $bytes = base64_decode($capi->getrandom(4, 0)); unset($capi); } catch (Exception $e) { } } // If we could not use the OS random number generators we get some of the most unique info we can if (!$bytes) { $string = microtime(TRUE) . uniqid('', TRUE) . join('', stat(__FILE__)) . disk_free_space(dirname(__FILE__)); $bytes = substr(pack('H*', md5($string)), 0, 4); } fCore::stopErrorCapture(); $seed = (int) (base_convert(bin2hex($bytes), 16, 10) - 2147483647); mt_srand($seed); $seeded = TRUE; }
/** * Reads lines from the SMTP server * * @param integer|string $expect The expected number of lines of response or a regex of the last line * @return array The lines of response from the server */ private function read($expect) { $read = array($this->connection); $write = NULL; $except = NULL; $response = array(); // Fixes an issue with stream_select throwing a warning on PHP 5.3 on Windows if (fCore::checkOS('windows') && fCore::checkVersion('5.3.0')) { $select = @stream_select($read, $write, $except, $this->timeout); } else { $select = stream_select($read, $write, $except, $this->timeout); } if ($select) { while (!feof($this->connection)) { $read = array($this->connection); $write = $except = NULL; $response[] = substr(fgets($this->connection), 0, -2); if ($expect !== NULL) { $matched_number = is_int($expect) && sizeof($response) == $expect; $matched_regex = is_string($expect) && preg_match($expect, $response[sizeof($response) - 1]); if ($matched_number || $matched_regex) { break; } } elseif (!stream_select($read, $write, $except, 0, 200000)) { break; } } } if (fCore::getDebug($this->debug)) { fCore::debug("Received:\n" . join("\r\n", $response), $this->debug); } $this->handleErrors($response); return $response; }
/** * Processes the current image using ImageMagick * * @param string $output_file The file to save the image to * @param integer $jpeg_quality The JPEG quality to use * @return void */ private function processWithImageMagick($output_file, $jpeg_quality) { $type = self::getImageType($this->file); if (fCore::checkOS('windows')) { $command_line = str_replace(' ', '" "', self::$imagemagick_dir . 'convert.exe'); } else { $command_line = escapeshellarg(self::$imagemagick_dir . 'convert'); } if (self::$imagemagick_temp_dir) { $command_line .= ' -set registry:temporary-path ' . escapeshellarg(self::$imagemagick_temp_dir) . ' '; } $command_line .= ' ' . escapeshellarg($this->file) . ' '; // Animated gifs need to be coalesced if ($this->isAnimatedGif()) { $command_line .= ' -coalesce '; } // TIFF files should be set to a depth of 8 if ($type == 'tif') { $command_line .= ' -depth 8 '; } foreach ($this->pending_modifications as $mod) { // Perform the resize operation if ($mod['operation'] == 'resize') { $command_line .= ' -resize "' . $mod['width'] . 'x' . $mod['height']; if ($mod['old_width'] < $mod['width'] || $mod['old_height'] < $mod['height']) { $command_line .= '<'; } $command_line .= '" '; // Perform the crop operation } elseif ($mod['operation'] == 'crop') { $command_line .= ' -crop ' . $mod['width'] . 'x' . $mod['height']; $command_line .= '+' . $mod['start_x'] . '+' . $mod['start_y']; $command_line .= ' -repage ' . $mod['width'] . 'x' . $mod['height'] . '+0+0 '; // Perform the desaturate operation } elseif ($mod['operation'] == 'desaturate') { $command_line .= ' -colorspace GRAY '; } } // Default to the RGB colorspace if (strpos($command_line, ' -colorspace ')) { $command_line .= ' -colorspace RGB '; } // Set up jpeg compression $path_info = fFilesystem::getPathInfo($output_file); $new_type = $path_info['extension']; $new_type = $new_type == 'jpeg' ? 'jpg' : $new_type; if (!in_array($new_type, array('gif', 'jpg', 'png'))) { $new_type = $type; } if ($new_type == 'jpg') { $command_line .= ' -compress JPEG -quality ' . $jpeg_quality . ' '; } $command_line .= ' ' . escapeshellarg($new_type . ':' . $output_file); exec($command_line); }
/** * Checks if the path specified is restricted by open basedir * * @param string $path The path to check * @return boolean If the path is restricted by the `open_basedir` ini setting */ private static function isOpenBaseDirRestricted($path) { if (ini_get('open_basedir')) { $open_basedirs = explode(fCore::checkOS('windows') ? ';' : ':', ini_get('open_basedir')); $found = FALSE; foreach ($open_basedirs as $open_basedir) { if (strpos($path, $open_basedir) === 0) { $found = TRUE; } } if (!$found) { return TRUE; } } return FALSE; }
/** * Adds the email address the email will be bounced to * * This email address will be set to the `Return-Path` header. * * @param string $email The email address to bounce to * @return void */ public function setBounceToEmail($email) { if (ini_get('safe_mode') && !fCore::checkOS('windows')) { throw new fProgrammerException('It is not possible to set a Bounce-To Email address when safe mode is enabled on a non-Windows server'); } if (!$email) { return; } $this->bounce_to_email = $this->combineNameEmail('', $email); }
public function tearDown() { // There seems to be an issue with the sybase driver on netbsd which this // test triggers, causing a segfault if (DB_TYPE == 'mssql' && fCore::checkOS('netbsd')) { return; } if (defined('SKIPPING')) { return; } fORMDatabase::retrieve()->enableDebugging(FALSE); fORMRelated::reset(); }
/** * Executes a SQL statement * * @param string|fStatement $statement The statement to perform * @param array $params The parameters for prepared statements * @return void */ private function perform($statement, $params) { fCore::startErrorCapture(); $extra = NULL; if (is_object($statement)) { $result = $statement->execute($params, $extra, $statement != $this->statement); } elseif ($this->extension == 'ibm_db2') { $result = db2_exec($this->connection, $statement, array('cursor' => DB2_FORWARD_ONLY)); } elseif ($this->extension == 'mssql') { $result = mssql_query($statement, $this->connection); } elseif ($this->extension == 'mysql') { $result = mysql_unbuffered_query($statement, $this->connection); } elseif ($this->extension == 'mysqli') { $result = mysqli_query($this->connection, $statement, MYSQLI_USE_RESULT); } elseif ($this->extension == 'oci8') { $extra = oci_parse($this->connection, $statement); $result = oci_execute($extra, $this->inside_transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS); } elseif ($this->extension == 'pgsql') { $result = pg_query($this->connection, $statement); } elseif ($this->extension == 'sqlite') { $result = sqlite_exec($this->connection, $statement, $extra); } elseif ($this->extension == 'sqlsrv') { $result = sqlsrv_query($this->connection, $statement); } elseif ($this->extension == 'pdo') { if ($this->type == 'mssql' && !fCore::checkOS('windows')) { $result = $this->connection->query($statement); if ($result instanceof PDOStatement) { $result->closeCursor(); } } else { $result = $this->connection->exec($statement); } } $this->statement = $statement; $this->handleErrors(fCore::stopErrorCapture()); if ($result === FALSE) { $this->checkForError($result, $extra, is_object($statement) ? $statement->getSQL() : $statement); } elseif (!is_bool($result) && $result !== NULL) { if ($this->extension == 'ibm_db2') { db2_free_result($result); } elseif ($this->extension == 'mssql') { mssql_free_result($result); } elseif ($this->extension == 'mysql') { mysql_free_result($result); } elseif ($this->extension == 'mysqli') { mysqli_free_result($result); } elseif ($this->extension == 'oci8') { oci_free_statement($oci_statement); } elseif ($this->extension == 'pgsql') { pg_free_result($result); } elseif ($this->extension == 'sqlsrv') { sqlsrv_free_stmt($result); } } }
/** * Processes the current image using ImageMagick * * @param string $output_file The file to save the image to * @param integer $jpeg_quality The JPEG quality to use * @return void */ private function processWithImageMagick($output_file, $jpeg_quality) { $type = self::getImageType($this->file); if (fCore::checkOS('windows')) { $command_line = str_replace(' ', '" "', self::$imagemagick_dir . 'convert.exe'); } else { $command_line = escapeshellarg(self::$imagemagick_dir . 'convert'); } if (self::$imagemagick_temp_dir) { $command_line .= ' -set registry:temporary-path ' . escapeshellarg(self::$imagemagick_temp_dir) . ' '; } // Determining in what format the file is going to be saved $path_info = fFilesystem::getPathInfo($output_file); $new_type = $path_info['extension']; $new_type = $new_type == 'jpeg' ? 'jpg' : $new_type; if (!in_array($new_type, array('gif', 'jpg', 'png'))) { $new_type = $type; } $file = $this->file; if ($type != 'gif' || $new_type != 'gif') { $file .= '[0]'; } $command_line .= ' ' . escapeshellarg(str_replace('tif', 'tiff', $type) . ':' . $file) . ' '; // Animated gifs need to be coalesced if ($this->isAnimatedGif()) { $command_line .= ' -coalesce '; } // TIFF files should be set to a depth of 8 if ($type == 'tif') { $command_line .= ' -depth 8 '; } foreach ($this->pending_modifications as $mod) { // Perform the resize operation if ($mod['operation'] == 'resize') { $command_line .= ' -resize "' . $mod['width'] . 'x' . $mod['height']; if ($mod['old_width'] < $mod['width'] || $mod['old_height'] < $mod['height']) { $command_line .= '<'; } $command_line .= '" '; // Perform the crop operation } elseif ($mod['operation'] == 'crop') { $command_line .= ' -crop ' . $mod['width'] . 'x' . $mod['height']; $command_line .= '+' . $mod['start_x'] . '+' . $mod['start_y']; $command_line .= ' -repage ' . $mod['width'] . 'x' . $mod['height'] . '+0+0 '; // Perform the desaturate operation } elseif ($mod['operation'] == 'desaturate') { $command_line .= ' -colorspace GRAY '; // Perform the rotate operation } elseif ($mod['operation'] == 'rotate') { $command_line .= ' -rotate ' . $mod['degrees'] . ' '; } } // Default to the RGB colorspace if (strpos($command_line, ' -colorspace ') === FALSE) { $command_line .= ' -colorspace RGB '; } if ($new_type == 'jpg') { $command_line .= ' -compress JPEG -quality ' . $jpeg_quality . ' '; } $command_line .= ' ' . escapeshellarg($new_type . ':' . $output_file) . ' 2>&1'; exec($command_line, $output, $return_value); if ($return_value !== 0) { throw new fEnvironmentException("An error occurred running the command, %1\$s, to modify the image. The error output was:\n%2\$s", $command_line, join("\n", $output)); } }