From 687c88785ca42368739415fa1ee9b4253f6da68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20S=CC=8Ckoda?= Date: Thu, 19 Sep 2013 22:02:45 +0200 Subject: [PATCH] MDL-41903 import typo3 4.7.15 --- lib/thirdpartylibs.xml | 2 +- lib/typo3/class.t3lib_cs.php | 16 +- lib/typo3/class.t3lib_div.php | 49 +-- lib/typo3/class.t3lib_utility_debug.php | 387 ++++++++++++++++++++++++ lib/typo3/readme_moodle.txt | 21 +- 5 files changed, 441 insertions(+), 34 deletions(-) create mode 100644 lib/typo3/class.t3lib_utility_debug.php diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 6ec4089fb9f..52fe7b2b5fd 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -193,7 +193,7 @@ typo3 Typo3 GPL - 4.7.4 + 4.7.15 2.0+ diff --git a/lib/typo3/class.t3lib_cs.php b/lib/typo3/class.t3lib_cs.php index 2bb2cc742f4..00dfc697250 100644 --- a/lib/typo3/class.t3lib_cs.php +++ b/lib/typo3/class.t3lib_cs.php @@ -815,8 +815,16 @@ class t3lib_cs { * @return string Output string */ function entities_to_utf8($str, $alsoStdHtmlEnt = FALSE) { + // Workaround for #39287: 3rd parameter for get_html_translation_table() was only added in PHP 5.3.4 and later + // see http://php.net/manual/en/function.get-html-translation-table.php + $applyPhpCompatibilityFix = version_compare(phpversion(), '5.3.4', '<'); + if ($alsoStdHtmlEnt) { - $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'UTF-8')); + if ($applyPhpCompatibilityFix === TRUE) { + $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_COMPAT)); + } else { + $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'UTF-8')); + } } $token = md5(microtime()); @@ -837,7 +845,11 @@ class t3lib_cs { } $parts[$k] = $this->UnumberToChar($v); } elseif ($alsoStdHtmlEnt && isset($trans_tbl['&' . $v . ';'])) { // Other entities: - $parts[$k] = $trans_tbl['&' . $v . ';']; + $v = $trans_tbl['&' . $v . ';']; + if ($applyPhpCompatibilityFix === TRUE) { + $v = $this->utf8_encode($v, 'iso-8859-1'); + } + $parts[$k] = $v; } else { // No conversion: $parts[$k] = '&' . $v . ';'; } diff --git a/lib/typo3/class.t3lib_div.php b/lib/typo3/class.t3lib_div.php index 1d7ddb28f39..3a3ba920197 100644 --- a/lib/typo3/class.t3lib_div.php +++ b/lib/typo3/class.t3lib_div.php @@ -933,26 +933,27 @@ final class t3lib_div { * Returns a proper HMAC on a given input string and secret TYPO3 encryption key. * * @param string $input Input string to create HMAC from + * @param string $additionalSecret additionalSecret to prevent hmac beeing used in a different context * @return string resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1) */ - public static function hmac($input) { + public static function hmac($input, $additionalSecret = '') { $hashAlgorithm = 'sha1'; $hashBlocksize = 64; $hmac = ''; - + $secret = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . $additionalSecret; if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) { - $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']); + $hmac = hash_hmac($hashAlgorithm, $input, $secret); } else { // outer padding $opad = str_repeat(chr(0x5C), $hashBlocksize); // inner padding $ipad = str_repeat(chr(0x36), $hashBlocksize); - if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) { + if (strlen($secret) > $hashBlocksize) { // keys longer than block size are shorten - $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00)); + $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $secret)), $hashBlocksize, chr(0)); } else { // keys shorter than block size are zero-padded - $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00)); + $key = str_pad($secret, $hashBlocksize, chr(0)); } $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input))); } @@ -1860,6 +1861,10 @@ final class t3lib_div { */ public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = FALSE, $includeEmptyValues = TRUE, $enableUnsetFeature = TRUE) { foreach ($arr1 as $key => $val) { + if ($enableUnsetFeature && $val === '__UNSET') { + unset($arr0[$key]); + continue; + } if (is_array($arr0[$key])) { if (is_array($arr1[$key])) { $arr0[$key] = self::array_merge_recursive_overrule( @@ -1870,12 +1875,11 @@ final class t3lib_div { $enableUnsetFeature ); } - } elseif (!$notAddKeys || isset($arr0[$key])) { - if ($enableUnsetFeature && $val === '__UNSET') { - unset($arr0[$key]); - } elseif ($includeEmptyValues || $val) { - $arr0[$key] = $val; - } + } elseif ( + (!$notAddKeys || isset($arr0[$key])) && + ($includeEmptyValues || $val) + ) { + $arr0[$key] = $val; } } @@ -4014,9 +4018,12 @@ final class t3lib_div { * @see upload_to_tempfile(), tempnam() */ public static function unlink_tempfile($uploadedTempFileName) { - if ($uploadedTempFileName && self::validPathStr($uploadedTempFileName) && self::isFirstPartOfStr($uploadedTempFileName, PATH_site . 'typo3temp/') && @is_file($uploadedTempFileName)) { - if (unlink($uploadedTempFileName)) { - return TRUE; + if ($uploadedTempFileName) { + $uploadedTempFileName = self::fixWindowsFilePath($uploadedTempFileName); + if (self::validPathStr($uploadedTempFileName) && self::isFirstPartOfStr($uploadedTempFileName, PATH_site . 'typo3temp/') && @is_file($uploadedTempFileName)) { + if (unlink($uploadedTempFileName)) { + return TRUE; + } } } } @@ -5564,6 +5571,12 @@ final class t3lib_div { return; } + // This require_once is needed for deprecation calls + // thrown early during bootstrap, if the autoloader is + // not instantiated yet. This can happen for example if + // ext_localconf triggers a deprecation. + require_once __DIR__.'/class.t3lib_utility_debug.php'; + $trail = debug_backtrace(); if ($trail[1]['type']) { @@ -5700,8 +5713,8 @@ final class t3lib_div { public static function flushOutputBuffers() { $obContent = ''; - while ($obContent .= ob_get_clean()) { - ; + while ($content = ob_get_clean()) { + $obContent .= $content; } // if previously a "Content-Encoding: whatever" has been set, we have to unset it @@ -5721,4 +5734,4 @@ final class t3lib_div { } } -?> +?> \ No newline at end of file diff --git a/lib/typo3/class.t3lib_utility_debug.php b/lib/typo3/class.t3lib_utility_debug.php new file mode 100644 index 00000000000..a15b3337226 --- /dev/null +++ b/lib/typo3/class.t3lib_utility_debug.php @@ -0,0 +1,387 @@ + + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * A copy is found in the textfile GPL.txt and important notices to the license + * from the author is found in LICENSE.txt distributed with these scripts. + * + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +/** + * Class to handle debug + * + * + * @author Steffen Kamper + * @package TYPO3 + * @subpackage t3lib + */ +final class t3lib_utility_Debug { + + /** + * Template for debug output + * + * @var string + */ + const DEBUG_TABLE_TEMPLATE = ' + + + + + + + +
%s
+ %s +
+ '; + + + public static function debug($var = '', $header = '', $group = 'Debug') { + // buffer the output of debug if no buffering started before + if (ob_get_level() == 0) { + ob_start(); + } + + $debug = self::convertVariableToString($var); + if ($header) { + $debug = sprintf(self::DEBUG_TABLE_TEMPLATE, htmlspecialchars((string) $header), $debug); + } + + if (TYPO3_MODE === 'BE') { + $debugString = self::prepareVariableForJavascript($debug, is_object($var)); + $group = htmlspecialchars($group); + + if ($header !== '') { + $tabHeader = htmlspecialchars($header); + } else { + $tabHeader = 'Debug'; + } + + $script = ' + (function debug() { + var debugMessage = "' . $debugString . '"; + var header = "' . $tabHeader . '"; + var group = "' . $group . '"; + + if (typeof Ext !== "object" && (top && typeof top.Ext !== "object")) { + document.write(debugMessage); + return; + } + + if (top && typeof Ext !== "object") { + Ext = top.Ext; + } + + Ext.onReady(function() { + var TYPO3ViewportInstance = null; + + if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") { + TYPO3ViewportInstance = top.TYPO3.Backend; + } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") { + TYPO3ViewportInstance = TYPO3.Backend; + } + + if (TYPO3ViewportInstance !== null) { + TYPO3ViewportInstance.DebugConsole.addTab(debugMessage, header, group); + } else { + document.write(debugMessage); + } + }); + })(); + '; + echo t3lib_div::wrapJS($script); + } else { + echo $debug; + } + } + + /** + * Replaces special characters for the usage inside javascript + * + * @param string $string + * @param boolean $asObject + * @return string + */ + public static function prepareVariableForJavascript($string, $asObject) { + if ($asObject) { + $string = str_replace(array( + '"', '/', '<', "\n", "\r" + ), array( + '\"', '\/', '\<', '
', '' + ), $string); + } else { + $string = str_replace(array( + '"', '/', '<', "\n", "\r" + ), array( + '\"', '\/', '\<', '', '' + ), $string); + } + + return $string; + } + + /** + * Converts a variable to a string + * + * @param mixed $variable + * @return string + */ + public static function convertVariableToString($variable) { + $string = ''; + if (is_array($variable)) { + $string = self::viewArray($variable); + } elseif (is_object($variable)) { + $string = '|Object:
';
+			$string .= print_r($variable, TRUE);
+			$string .= '
|
'; + } elseif ((string) $variable !== '') { + $string = '|' . htmlspecialchars((string) $variable) . '|'; + } else { + $string = '| debug |'; + } + + return $string; + } + + /** + * Opens a debug message inside a popup window + * + * @param mixed $debugVariable + * @param string $header + * @param string $group + */ + public static function debugInPopUpWindow($debugVariable, $header = 'Debug', $group = 'Debug') { + $debugString = self::prepareVariableForJavascript( + self::convertVariableToString($debugVariable), + is_object($debugVariable) + ); + + $script = ' + (function debug() { + var debugMessage = "' . $debugString . '", + header = "' . htmlspecialchars($header) . '", + group = "' . htmlspecialchars($group) . '", + + browserWindow = function(debug, header, group) { + var newWindow = window.open("", "TYPO3DebugWindow_" + group, + "width=600,height=400,menubar=0,toolbar=1,status=0,scrollbars=1,resizable=1" + ); + if (newWindow.document.body.innerHTML) { + newWindow.document.body.innerHTML = newWindow.document.body.innerHTML + + "
" + debugMessage; + } else { + newWindow.document.writeln( + "Debug: " + header + "(" + group + ")" + + "" + + debugMessage + + "" + ); + } + } + + if (!top.Ext) { + browserWindow(debugMessage, header, group); + } else { + top.Ext.onReady(function() { + if (top && top.TYPO3 && top.TYPO3.Backend) { + top.TYPO3.Backend.DebugConsole.openBrowserWindow(header, debugMessage, group); + } else { + browserWindow(debugMessage, header, group); + } + }); + } + })(); + '; + echo t3lib_div::wrapJS($script); + } + + /** + * Displays the "path" of the function call stack in a string, using debug_backtrace + * + * @return string + */ + public static function debugTrail() { + $trail = debug_backtrace(); + $trail = array_reverse($trail); + array_pop($trail); + + $path = array(); + foreach ($trail as $dat) { + $pathFragment = $dat['class'] . $dat['type'] . $dat['function']; + // add the path of the included file + if (in_array($dat['function'], array('require', 'include', 'require_once', 'include_once'))) { + $pathFragment .= '(' . substr($dat['args'][0], strlen(PATH_site)) . '),' . substr($dat['file'], strlen(PATH_site)); + } + $path[] = $pathFragment . '#' . $dat['line']; + } + + return implode(' // ', $path); + } + + /** + * Displays an array as rows in a table. Useful to debug output like an array of database records. + * + * @param mixed Array of arrays with similar keys + * @param string Table header + * @param boolean If TRUE, will return content instead of echo'ing out. + * @return void Outputs to browser. + */ + public static function debugRows($rows, $header = '', $returnHTML = FALSE) { + if (is_array($rows)) { + $firstEl = reset($rows); + if (is_array($firstEl)) { + $headerColumns = array_keys($firstEl); + $tRows = array(); + + // Header: + $tRows[] = '' . + htmlspecialchars($header) . ''; + $tCells = array(); + foreach ($headerColumns as $key) { + $tCells[] = ' + ' . htmlspecialchars($key) . ''; + } + $tRows[] = ' + ' . implode('', $tCells) . ' + '; + + // Rows: + foreach ($rows as $singleRow) { + $tCells = array(); + foreach ($headerColumns as $key) { + $tCells[] = ' + ' . + (is_array($singleRow[$key]) ? self::debugRows($singleRow[$key], '', TRUE) : htmlspecialchars($singleRow[$key])) . + ''; + } + $tRows[] = ' + ' . implode('', $tCells) . ' + '; + } + + $table = ' + ' . implode('', $tRows) . ' +
'; + if ($returnHTML) { + return $table; + } + else + { + echo $table; + } + } else + { + debug('Empty array of rows', $header); + } + } else { + debug('No array of rows', $header); + } + } + + /** + * Returns a string with a list of ascii-values for the first $characters characters in $string + * + * @param string String to show ASCII value for + * @param integer Number of characters to show + * @return string The string with ASCII values in separated by a space char. + */ + public static function ordinalValue($string, $characters = 100) { + if (strlen($string) < $characters) { + $characters = strlen($string); + } + for ($i = 0; $i < $characters; $i++) { + $valuestring .= ' ' . ord(substr($string, $i, 1)); + } + return trim($valuestring); + } + + /** + * Returns HTML-code, which is a visual representation of a multidimensional array + * use t3lib_div::print_array() in order to print an array + * Returns FALSE if $array_in is not an array + * + * @param mixed Array to view + * @return string HTML output + */ + public static function viewArray($array_in) { + if (is_array($array_in)) { + $result = ' + '; + if (count($array_in) == 0) { + $result .= ''; + } else { + foreach ($array_in as $key => $val) { + $result .= ' + + + '; + } + } + $result .= '
EMPTY!
' . htmlspecialchars((string) $key) . ''; + if (is_array($val)) { + $result .= self::viewArray($val); + } elseif (is_object($val)) { + $string = ''; + if (method_exists($val, '__toString')) { + $string .= get_class($val) . ': ' . (string) $val; + } else { + $string .= print_r($val, TRUE); + } + $result .= '' . + nl2br(htmlspecialchars($string)) . + '
'; + } else { + if (gettype($val) == 'object') { + $string = 'Unknown object'; + } else { + $string = (string) $val; + } + $result .= '' . + nl2br(htmlspecialchars($string)) . + '
'; + } + $result .= '
'; + } else { + $result = ' + + + +
' . + nl2br(htmlspecialchars((string) $array_in)) . + '
'; // Output it as a string. + } + return $result; + } + + /** + * Prints an array + * + * @param mixed Array to print visually (in a table). + * @return void + * @see viewArray() + */ + public static function printArray($array_in) { + echo self::viewArray($array_in); + } +} + +?> \ No newline at end of file diff --git a/lib/typo3/readme_moodle.txt b/lib/typo3/readme_moodle.txt index d45a1835b7b..0e188da4154 100644 --- a/lib/typo3/readme_moodle.txt +++ b/lib/typo3/readme_moodle.txt @@ -1,16 +1,11 @@ -Description of Typo3 libraries (v 4.7.4) import into Moodle +Description of Typo3 libraries (v 4.7.15) import into Moodle -Changes: none +Changes: +1/ hacked relative include of class.t3lib_utility_debug.php -skodak, stronk7 +Procedure: +1/ download latest version form http://typo3.org/download/ +2/ copy csconvtbl/*, unidata/* and all other necessary files we use +3/ run our phpunit tests with and without mbstring PHP extension - -Previous changes: - -25 June 2010 - Martin D (4.3.0RC1) - I renamed getURL to getUrl since it was being called that way everywhere. - I added a check to avoid notices on lib/typo3/class.t3lib_cs.php line 976 - -22 October 2011 - Petr Skoda (4.5.0) - reapplied getURL --> getUrl in class.t3lib_div.php line 2992 - reintroduced check to avoid notices on class.t3lib_cs.php line 1031 +skodak, stronk7, moodler