Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.113.2.70.2.73
diff -u -r1.113.2.70.2.73 webform.module
--- webform.module	14 Oct 2008 21:51:45 -0000	1.113.2.70.2.73
+++ webform.module	20 Oct 2008 14:25:24 -0000
@@ -1469,17 +1469,29 @@
   $form_values['submitted'] = _webform_client_form_submit_flatten($node, $form_values['submitted']);
 
   // Convert additional email addresses into actual values.
-  foreach ($node->webform['additional_emails'] as $cid => $value) {
+  foreach ($form_values['submitted'] as $cid => $value) {
     if (is_array($form_values['submitted'][$cid])) {
       $node->webform['additional_emails'][$cid] = array();
       foreach ($form_values['submitted'][$cid] as $submitted_value) {
         if ($submitted_value) {
-          $node->webform['additional_emails'][$cid][] = $submitted_value;
+          // If we find that the value has been hashed, convert it to an email
+          // address.
+          if (strlen($submitted_value) >= 32 && !valid_email_address($submitted_value) && ($email = _webform_get_hash_email($submitted_value))) {
+            $node->webform['additional_emails'][$cid][] = $email;
+          }
+          else {
+            $node->webform['additional_emails'][$cid][] = $submitted_value;
+          }
         }
       }
     }
     else {
-      $node->webform['additional_emails'][$cid] = $form_values['submitted'][$cid];
+      if (strlen($form_values['submitted'][$cid]) >= 32 && !valid_email_address($form_values['submitted'][$cid]) && ($email = _webform_get_hash_email($form_values['submitted'][$cid]))) {
+        $node->webform['additional_emails'][$cid] = $email;
+      }
+      else {
+        $node->webform['additional_emails'][$cid] = $form_values['submitted'][$cid];
+      }
     }
     if (empty($node->webform['additional_emails'][$cid])) {
       unset($node->webform['additional_emails'][$cid]);
Index: webform.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.install,v
retrieving revision 1.14.2.16.2.24
diff -u -r1.14.2.16.2.24 webform.install
--- webform.install	6 Oct 2008 05:55:37 -0000	1.14.2.16.2.24
+++ webform.install	20 Oct 2008 14:25:21 -0000
@@ -72,6 +72,14 @@
         INDEX sid_nid (sid, nid)
         ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */"
       );
+      
+      $success = $success && db_query("CREATE TABLE {webform_email_hashes} (
+        hash varchar(" . EMAIL_MAX_LENGTH . ") NOT NULL,
+        email varchar(255) NOT NULL, 
+        PRIMARY KEY (hash, email)
+        ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */"
+      );
+      
       break;
 
   case 'pgsql':
@@ -137,6 +145,14 @@
       );
       $success = $success && db_query("CREATE INDEX {webform_submitted_data}_nid_idx ON {webform_submitted_data} (sid)");
       $success = $success && db_query("CREATE INDEX {webform_submitted_data}_sid_nid_idx ON {webform_submitted_data} (sid, nid)");
+      
+      $success = $success && db_query("CREATE TABLE {webform_email_hashes} (
+        hash varchar(255) NOT NULL,
+        email varchar(" . EMAIL_MAX_LENGTH . ") NOT NULL, 
+        PRIMARY KEY (hash, email)
+        )"
+      );
+      
       break;
   }
 
@@ -790,6 +806,35 @@
 }
 
 /**
+ * Add a table to store email addresses and their unique hash mappings. This
+ * allows emails to be hidden to the client and for multiple select options to
+ * point to a single email address.
+ */
+function webform_update_5204() {
+  $ret = array();
+  switch ($GLOBALS['db_type']) {
+    case 'mysqli':
+    case 'mysql':
+      $ret[] = update_sql("CREATE TABLE {webform_email_hashes} (
+        hash char(32) NOT NULL,
+        email varchar(" . EMAIL_MAX_LENGTH . ") NOT NULL,
+        PRIMARY KEY (hash, email)
+        ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */"
+      );
+      break;
+    case 'pgsql':
+      $ret[] = update_sql("CREATE TABLE {webform_email_hashes} (
+        hash char(32) NOT NULL,
+        email varchar(" . EMAIL_MAX_LENGTH . ") NOT NULL,
+        PRIMARY KEY (hash, email)
+        )"
+      );
+      break;
+  }
+  return $ret;
+}
+
+/**
  * Recursively delete all files and folders in the specified filepath, then
  * delete the containing folder.
  *
Index: components/select.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/components/select.inc,v
retrieving revision 1.18.2.19.2.22
diff -u -r1.18.2.19.2.22 select.inc
--- components/select.inc	21 Sep 2008 03:20:46 -0000	1.18.2.19.2.22
+++ components/select.inc	20 Oct 2008 14:25:25 -0000
@@ -104,8 +104,15 @@
 
   // Convert the user-entered options list into an array.
   $default_value = _webform_filter_values($component['value'], NULL, NULL, FALSE);
-  $options = _webform_select_options($component['extra']['items']);
-
+  
+  // If email is enabled, hash the email addresses
+  if ($component['extra']['email']) {
+    $options = _webform_select_options($component['extra']['items'], TRUE);
+  }
+  else {
+    $options = _webform_select_options($component['extra']['items'], FALSE);
+  }
+  
   if ($component['extra']['aslist'] == 'Y' && $component['extra']['multiple'] != 'Y') {
     $options = array('' => t('select...')) + $options;
   }
@@ -210,7 +217,13 @@
  *   Nothing.
  */
 function _webform_submit_select(&$data, $component) {
-  $options = drupal_map_assoc(array_flip(_webform_select_options($component['extra']['items'])));
+  // If email is enabled, hash the email addresses
+  if ($component['extra']['email']) {
+    $options = drupal_map_assoc(array_flip(_webform_select_options($component['extra']['items'], TRUE)));
+  }
+  else {
+    $options = drupal_map_assoc(array_flip(_webform_select_options($component['extra']['items'])));
+  }
 
   if (is_array($data)) {
     foreach ($data as $key => $value) {
@@ -240,8 +253,14 @@
  *   Textual output to be included in the email.
  */
 function theme_webform_mail_select($data, $component) {
-  // Convert submitted 'safe' values to un-edited, original form.
-  $options = _webform_select_options($component['extra']['items']);
+  // Convert submitted 'safe' values to un-edited, original form. Hash if email
+  // is enabled.
+  if ($component['extra']['email']) {
+    $options = _webform_select_options($component['extra']['items'], TRUE);
+  }
+  else {
+    $options = _webform_select_options($component['extra']['items'], FALSE);
+  }
 
   // Generate the output.
   if ($component['extra']['multiple']) {
@@ -406,14 +425,34 @@
 /**
  * Utility function to split user-entered values from new-line seperated
  * text into an array of options.
+ * 
+ * @param $text
+ *   The text containing the options for the select element.
+ * @param $hash_emails
+ *   Should detected email addresses be hashed and stored for future use?
+ * @return
+ *   An array containing the parsed options suitable for use by the Form API.
  */
-function _webform_select_options($text) {
+function _webform_select_options($text, $hash_emails = FALSE) {
   $options = array();
   $rows = array_filter(explode("\n", _webform_filter_values(trim($text), NULL, NULL, FALSE)));
+  $count = 0;
   foreach ($rows as $option) {
     $option = trim($option);
     if (preg_match('/^([^|]+)\|(.*)$/', $option, $matches)) {
-      $options[$matches[1]] = $matches[2];
+      if ($hash_emails) {
+        if (valid_email_address($matches[1])) {
+          $hash = _webform_hash_email($matches[1]);
+          if (isset($options[$hash])) {
+            $hash .= '-' . $count;
+            $count ++;
+          }
+          $options[$hash] = $matches[2];
+        }
+      }
+      else {
+        $options[$matches[1]] = $matches[2];
+      }
     }
     else {
       $options[$option] = $option;
@@ -421,3 +460,43 @@
   }
   return $options;
 }
+
+/**
+ * Given an email address, return it's md5 hash, either from the database or
+ * by calculating and storing it.
+ * 
+ * @param $email
+ *   The email address to hash.
+ * @return
+ *   The md5 hash of the email.
+ */
+function _webform_hash_email($email) {
+  $query = "SELECT hash FROM {webform_email_hashes} WHERE email = '%s'";
+  $hash = db_result(db_query($query, $email));
+  
+  if (empty($hash)) {
+    $hash = md5($email);
+    $query = "INSERT INTO {webform_email_hashes} (hash, email) VALUES('%s', '%s')";
+    db_query($query, $hash, $email);
+  }
+  
+  return $hash;
+}
+
+/**
+ * Given an md5 hash, return the email associated with it as stored in the
+ * database.
+ * 
+ * @param $hash
+ *   A 32-character long md5 hash.
+ *   
+ * @return
+ *   The associated email address, or NULL if no address was found.
+ */
+function _webform_get_hash_email($hash) {
+  if (strlen($hash) > 32) {
+    $hash = substr($hash, 0, 32);
+  }
+  $query = "SELECT email FROM {webform_email_hashes} WHERE hash = '%s'";
+  return db_result(db_query($query, $hash));
+}
