Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.595
diff -u -p -r1.595 common.inc
--- includes/common.inc	5 Dec 2006 05:47:37 -0000	1.595
+++ includes/common.inc	7 Dec 2006 07:54:54 -0000
@@ -960,6 +960,22 @@ function format_plural($count, $singular
 }
 
 /**
+ * Parse a given byte count.
+ *
+ * @param $size
+ *   The size expressed as a number of bytes with optional SI size and unit
+ *   suffix (e.g. 2, 3K, 5MB, 10G).
+ * @return
+ *   An integer representation of the size.
+ */
+function parse_size($size) {
+  $suffixes = array('' => 1, 'k' => 1024, 'm' => 1024 * 1024, 'g' => 1024 * 1024 * 1024);
+  if (preg_match('/([0-9]+)\s*(k|m|g)?(b?(ytes?)?)/i', $size, $match)) {
+    return $match[1] * $suffixes[drupal_strtolower($match[2])];
+  }
+}
+
+/**
  * Generate a string representation for the given byte count.
  *
  * @param $size
Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.86
diff -u -p -r1.86 file.inc
--- includes/file.inc	17 Oct 2006 19:29:26 -0000	1.86
+++ includes/file.inc	7 Dec 2006 07:54:54 -0000
@@ -713,26 +713,6 @@ function file_directory_path() {
 }
 
 /**
- * Helper function for file_upload_max_size().
- */
-function _file_convert_to_mb($val){
-  $val = trim($val);
-  $last = strtolower($val[strlen($val) - 1]);
-  switch ($last) {
-    // The 'G' modifier is available since PHP 5.1.0
-    case 'g':
-      $size = $val * 1024;
-      break;
-    case 'k':
-      $size = $val / 1024;
-      break;
-    default:
-      $size = (int) $val;
-  }
-  return $size;
-}
-
-/**
  * Determine the maximum file upload size by querying the PHP settings.
  *
  * @return
@@ -742,9 +722,9 @@ function file_upload_max_size() {
   static $max_size = -1;
 
   if ($max_size < 0) {
-    $upload_max = _file_convert_to_mb(ini_get('upload_max_filesize'));
+    $upload_max = parse_size(ini_get('upload_max_filesize'));
     // sanity check- a single upload should not be more than 50% the size limit of the total post
-    $post_max = _file_convert_to_mb(ini_get('post_max_size')) / 2;
+    $post_max = parse_size(ini_get('post_max_size')) / 2;
     $max_size = ($upload_max < $post_max) ? $upload_max : $post_max;
   }
   return $max_size;
Index: modules/color/color.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/color/color.module,v
retrieving revision 1.10
diff -u -p -r1.10 color.module
--- modules/color/color.module	4 Dec 2006 22:52:27 -0000	1.10
+++ modules/color/color.module	7 Dec 2006 07:54:55 -0000
@@ -189,6 +189,23 @@ function color_scheme_form_submit($form_
     }
   }
 
+  // Make sure enough memory is available, if PHP's memory limit is compiled in.
+  if (function_exists('memory_get_usage')) {
+    // Fetch source image dimensions.
+    $source = drupal_get_path('theme', $theme) .'/'. $info['base_image'];
+    list($width, $height) = getimagesize($source);
+
+    // We need at least a copy of the source and a target buffer of the same
+    // size (both at 32bpp).
+    $required = $width * $height * 4 * 2;
+    $usage = memory_get_usage();
+    $limit = parse_size(ini_get('memory_limit'));
+    if ($usage + $required > $limit) {
+      drupal_set_message(t('There is not enough memory available to PHP to change this theme\'s color scheme. You need at least %size more. Check the <a href="%url">PHP documentation</a> for more information.', array('%size' => format_size($usage + $required - $limit), '%url' => 'http://www.php.net/manual/en/ini.core.php#ini.sect.resource-limits')), 'error');
+      return;
+    }
+  }
+
   // Delete old files
   foreach (variable_get('color_'. $theme .'_files', array()) as $file) {
     @unlink($file);
