Browse Source

! Updates to read_zip_data moving from Magic Number based parsing to a File Structure / Local Header parsing.
! CSS files were being called as Javascript
! Load theme variants for the init template

Spuds 12 years ago
parent
commit
b2951f6ddf
3 changed files with 78 additions and 75 deletions
  1. 21 20
      Sources/Load.php
  2. 47 45
      Sources/Subs-Package.php
  3. 10 10
      Themes/default/index.template.php

+ 21 - 20
Sources/Load.php

@@ -1566,6 +1566,27 @@ function loadTheme($id_theme = 0, $initialize = true)
 	$context['javascript_files'] = array();
 	$context['css_files'] = array();
 
+	
+	// We allow theme variants, because we're cool.
+	$context['theme_variant'] = '';
+	$context['theme_variant_url'] = '';
+	if (!empty($settings['theme_variants']))
+	{
+		// Overriding - for previews and that ilk.
+		if (!empty($_REQUEST['variant']))
+			$_SESSION['id_variant'] = $_REQUEST['variant'];
+		// User selection?
+		if (empty($settings['disable_user_variant']) || allowedTo('admin_forum'))
+			$context['theme_variant'] = !empty($_SESSION['id_variant']) ? $_SESSION['id_variant'] : (!empty($options['theme_variant']) ? $options['theme_variant'] : '');
+		// If not a user variant, select the default.
+		if ($context['theme_variant'] == '' || !in_array($context['theme_variant'], $settings['theme_variants']))
+			$context['theme_variant'] = !empty($settings['default_variant']) && in_array($settings['default_variant'], $settings['theme_variants']) ? $settings['default_variant'] : $settings['theme_variants'][0];
+	
+		// Do this to keep things easier in the templates.
+		$context['theme_variant'] = '_' . $context['theme_variant'];
+		$context['theme_variant_url'] = $context['theme_variant'] . '/';
+	}
+
 	// Wireless mode?  Load up the wireless stuff.
 	if (WIRELESS)
 	{
@@ -1624,26 +1645,6 @@ function loadTheme($id_theme = 0, $initialize = true)
 	if (!empty($settings['require_theme_strings']))
 		loadLanguage('ThemeStrings', '', false);
 
-	// We allow theme variants, because we're cool.
-	$context['theme_variant'] = '';
-	$context['theme_variant_url'] = '';
-	if (!empty($settings['theme_variants']))
-	{
-		// Overriding - for previews and that ilk.
-		if (!empty($_REQUEST['variant']))
-			$_SESSION['id_variant'] = $_REQUEST['variant'];
-		// User selection?
-		if (empty($settings['disable_user_variant']) || allowedTo('admin_forum'))
-			$context['theme_variant'] = !empty($_SESSION['id_variant']) ? $_SESSION['id_variant'] : (!empty($options['theme_variant']) ? $options['theme_variant'] : '');
-		// If not a user variant, select the default.
-		if ($context['theme_variant'] == '' || !in_array($context['theme_variant'], $settings['theme_variants']))
-			$context['theme_variant'] = !empty($settings['default_variant']) && in_array($settings['default_variant'], $settings['theme_variants']) ? $settings['default_variant'] : $settings['theme_variants'][0];
-
-		// Do this to keep things easier in the templates.
-		$context['theme_variant'] = '_' . $context['theme_variant'];
-		$context['theme_variant_url'] = $context['theme_variant'] . '/';
-	}
-
 	// Let's be compatible with old themes!
 	if (!function_exists('template_html_above') && in_array('html', $context['template_layers']))
 		$context['template_layers'] = array('main');

+ 47 - 45
Sources/Subs-Package.php

@@ -1,11 +1,11 @@
 <?php
 
 /**
- * This file's central purpose of existence is that of making the package 
+ * This file's central purpose of existence is that of making the package
  * manager work nicely.  It contains functions for handling tar.gz and zip
  * files, as well as a simple xml parser to handle the xml package stuff.
  * Not to mention a few functions to make file handling easier.
- * 
+ *
  * Simple Machines Forum (SMF)
  *
  * @package SMF
@@ -60,10 +60,10 @@ function read_tgz_file($gzfilename, $destination, $single_file = false, $overwri
  * requires zlib support be built into PHP.
  * returns an array of the files extracted.
  * if files_to_extract is not equal to null only extracts file within this array.
- * @param string data, 
- * @param string destination, 
- * @param bool single_file = false, 
- * @param bool overwrite = false, 
+ * @param string data,
+ * @param string destination,
+ * @param bool single_file = false,
+ * @param bool overwrite = false,
  * @param array files_to_extract = null
  * @return array
  */
@@ -225,47 +225,52 @@ function read_zip_data($data, $destination, $single_file = false, $overwrite = f
 	if ($destination !== null && !file_exists($destination) && !$single_file)
 		mktree($destination, 0777);
 
-	// Look for the PK header...
-	if (strpos($data, 'PK') !== 0)
+	// Look for the end of directory signature 0x06054b50
+	$data_ecr = explode("\x50\x4b\x05\x06", $data);
+	if (!isset($data_ecr[1]))
 		return false;
 
-	// Find the central whosamawhatsit at the end; if there's a comment it's a pain.
-	if (substr($data, -22, 4) == 'PK' . chr(5) . chr(6))
-		$p = -22;
-	else
-	{
-		// Have to find where the comment begins, ugh.
-		for ($p = -22; $p > -strlen($data); $p--)
-		{
-			if (substr($data, $p, 4) == 'PK' . chr(5) . chr(6))
-				break;
-		}
-	}
 
 	$return = array();
 
-	// Get the basic zip file info.
-	$zip_info = unpack('vfiles/Vsize/Voffset', substr($data, $p + 10, 10));
+	// Get all the basic zip file info since we are here
+	$zip_info = unpack('vdisks/vrecords/vfiles/Vsize/Voffset/vcomment_length/', $data_ecr[1]);
 
-	$p = $zip_info['offset'];
-	for ($i = 0; $i < $zip_info['files']; $i++)
-	{
-		// Make sure this is a file entry...
-		if (substr($data, $p, 4) != 'PK' . chr(1) . chr(2))
-			return false;
+	// Cut file at the central directory file header signature -- 0x02014b50, use unpack if you want any of the data, we don't
+	$file_sections = explode("\x50\x4b\x01\x02", $data);
 
+	// Cut the result on each local file header -- 0x04034b50 so we have each file in the archive as an element.
+	$file_sections = explode("\x50\x4b\x03\x04", $file_sections[0]);
+	array_shift($file_sections);
+
+	// sections and count from the signature must match or the zip file is bad
+	if (count($file_sections) != $zip_info['files'])
+		return false;
+
+	// go though each file in the archive
+	foreach ($file_sections as $data)
+	{
 		// Get all the important file information.
-		$file_info = unpack('Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', substr($data, $p + 16, 30));
-		$file_info['filename'] = substr($data, $p + 46, $file_info['filename_len']);
+		$file_info = unpack("vversion/vgeneral_purpose/vcompress_method/vfile_time/vfile_date/Vcrc/Vcompressed_size/Vsize/vfilename_length/vextrafield_length", $data);
+		$file_info['filename'] = substr($data, 26, $file_info['filename_length']);
+		$file_info['dir'] = $destination . '/' . dirname($file_info['filename']);
 
-		// Skip all the information we don't care about anyway.
-		$p += 46 + $file_info['filename_len'] + $file_info['extra_len'] + $file_info['comment_len'];
+		// If bit 3 (0x08) of the general-purpose flag is set, then the CRC and file size were not available when the header was written
+		// In this case the CRC and size are instead appended in a 12-byte structure immediately after the compressed data
+		if ($file_info['general_purpose'] & 0x0008)
+		{
+			$unzipped2 = unpack("Vcrc/Vcompressed_size/Vsize", substr($$data, -12));
+			$unzipped['crc'] = $unzipped2['crc'];
+			$unzipped['compressed_size'] = $unzipped2['compressed_size'];
+			$unzipped['size'] = $unzipped2['size'];
+			unset($unzipped2);
+		}
 
 		// If this is a file, and it doesn't exist.... happy days!
-		if (substr($file_info['filename'], -1, 1) != '/' && !file_exists($destination . '/' . $file_info['filename']))
+		if (substr($file_info['filename'], -1) != '/' && !file_exists($destination . '/' . $file_info['filename']))
 			$write_this = true;
 		// If the file exists, we may not want to overwrite it.
-		elseif (substr($file_info['filename'], -1, 1) != '/')
+		elseif (substr($file_info['filename'], -1) != '/')
 			$write_this = $overwrite;
 		// This is a directory, so we're gonna want to create it. (probably...)
 		elseif ($destination !== null && !$single_file)
@@ -280,22 +285,19 @@ function read_zip_data($data, $destination, $single_file = false, $overwrite = f
 		else
 			$write_this = false;
 
-		// Check that the data is there and does exist.
-		if (substr($data, $file_info['offset'], 4) != 'PK' . chr(3) . chr(4))
-			return false;
 
 		// Get the actual compressed data.
-		$file_info['data'] = substr($data, $file_info['offset'] + 30 + $file_info['filename_len'], $file_info['compressed_size']);
+		$file_info['data'] = substr($data, 26 + $file_info['filename_length'] + $file_info['extrafield_length']);
 
-		// Only inflate it if we need to ;).
+		// Only inflate it if we need to ;)
 		if ($file_info['compressed_size'] != $file_info['size'])
-			$file_info['data'] = @gzinflate($file_info['data']);
+			$file_info['data'] = gzinflate($file_info['data']);
 
 		// Okay!  We can write this file, looks good from here...
 		if ($write_this && $destination !== null)
 		{
-			if (strpos($file_info['filename'], '/') !== false && !$single_file)
-				mktree($destination . '/' . dirname($file_info['filename']), 0777);
+			if ((strpos($file_info['filename'], '/') !== false && !$single_file) || (!is_dir($file_info['dir'])))
+				mktree($file_info['dir'], 0777);
 
 			// If we're looking for a specific file, and this is it... ka-bam, baby.
 			if ($single_file && ($destination == $file_info['filename'] || $destination == '*/' . basename($file_info['filename'])))
@@ -1366,7 +1368,7 @@ function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install
  * supports comma separated version numbers, with or without whitespace.
  * supports lower and upper bounds. (1.0-1.2)
  * returns true if the version matched.
- * @param string $version 
+ * @param string $version
  * @param string $versions
  * @return bool
  */
@@ -2898,7 +2900,7 @@ function fetch_web_data($url, $post_data = '', $keep_alive = false, $redirection
 		// I want this, from there, and I'm not going to be bothering you for more (probably.)
 		if (empty($post_data))
 		{
-			fwrite($fp, 'GET ' . $match[6] . ' HTTP/1.0' . "\r\n");
+			fwrite($fp, 'GET ' . ($match[6] !== '/' ? $match[6] : '') . ' HTTP/1.0' . "\r\n");
 			fwrite($fp, 'Host: ' . $match[3] . (empty($match[5]) ? ($match[2] ? ':443' : '') : ':' . $match[5]) . "\r\n");
 			fwrite($fp, 'User-Agent: PHP/SMF' . "\r\n");
 			if ($keep_alive)
@@ -2908,7 +2910,7 @@ function fetch_web_data($url, $post_data = '', $keep_alive = false, $redirection
 		}
 		else
 		{
-			fwrite($fp, 'POST ' . $match[6] . ' HTTP/1.0' . "\r\n");
+			fwrite($fp, 'POST ' . ($match[6] !== '/' ? $match[6] : '') . ' HTTP/1.0' . "\r\n");
 			fwrite($fp, 'Host: ' . $match[3] . (empty($match[5]) ? ($match[2] ? ':443' : '') : ':' . $match[5]) . "\r\n");
 			fwrite($fp, 'User-Agent: PHP/SMF' . "\r\n");
 			if ($keep_alive)

+ 10 - 10
Themes/default/index.template.php

@@ -75,23 +75,23 @@ function template_init()
 	$settings['require_theme_strings'] = false;
 
 	// Load the CSS
-	loadCSSFile($settings['theme_url'], '/css/index', $context['theme_variant'], '.css?fin20');
+	loadCSSFile($settings['theme_url'] . '/css/index' . $context['theme_variant'] . '.css?fin20');
 
 	// Some browsers need an extra stylesheet due to bugs/compatibility issues.
 	foreach (array('ie7', 'ie6', 'webkit') as $cssfix)
 		if (isBrowser('is_' . $cssfix))
-			loadCSSFile($settings['default_theme_url'], '/css/', $cssfix, '.css');
+			loadCSSFile($settings['default_theme_url'] . '/css/' . $cssfix . '.css');
 
 	// RTL languages require an additional stylesheet.
-	if ($context['right_to_left'])
-		loadCSSFile($settings['theme_url'], '/css/rtl.css');
+	if (!empty($context['right_to_left']))
+		loadCSSFile($settings['theme_url'] . '/css/rtl.css');
 
 	// Now load the JS
-	loadJavascriptFile($settings['theme_url'], '/scripts/jquery-1.6.4.min.js');
-	loadJavascriptFile($settings['theme_url'], '/scripts/hoverIntent.js');
-	loadJavascriptFile($settings['theme_url'], '/scripts/superfish.js');
-	loadJavascriptFile($settings['default_theme_url'], '/scripts/script.js?fin20');
-	loadJavascriptFile($settings['theme_url'], '/scripts/theme.js?fin20');
+	loadJavascriptFile($settings['theme_url'] . '/scripts/jquery-1.6.4.min.js');
+	loadJavascriptFile($settings['theme_url'] . '/scripts/hoverIntent.js');
+	loadJavascriptFile($settings['theme_url'] . '/scripts/superfish.js');
+	loadJavascriptFile($settings['default_theme_url'] . '/scripts/script.js?fin20');
+	loadJavascriptFile($settings['theme_url'] . '/scripts/theme.js?fin20');
 }
 
 /**
@@ -604,7 +604,7 @@ function template_css()
 
 	foreach ($context['css_files'] as $filename => $options)
 		echo '
-		<script type="text/javascript" src="', $filename, '"></script>';
+	<link rel="stylesheet" type="text/css" href="', $filename, '" />';
 }
 
 ?>