Index: modules/field/field.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.test,v
retrieving revision 1.36
diff -u -r1.36 field.test
--- modules/field/field.test	2 Aug 2009 11:24:21 -0000	1.36
+++ modules/field/field.test	5 Aug 2009 22:01:55 -0000
@@ -1363,28 +1363,6 @@
    * Test the creation of a field.
    */
   function testCreateField() {
-    // Check that field type is required.
-    try {
-      $field_definition = array(
-        'field_name' => 'field_1',
-      );
-      field_create_field($field_definition);
-      $this->fail(t('Cannot create a field with no type.'));
-    }
-    catch (FieldException $e) {
-      $this->pass(t('Cannot create a field with no type.'));
-    }
-
-    // Check that field name is required.
-    try {
-      $field_definition = array('type' => 'test_field');
-      field_create_field($field_definition);
-      $this->fail(t('Cannot create an unnamed field.'));
-    }
-    catch (FieldException $e) {
-      $this->pass(t('Cannot create an unnamed field.'));
-    }
-
     $field_definition = array(
       'field_name' => 'field_2',
       'type' => 'test_field',
@@ -1419,19 +1397,68 @@
       $this->pass(t('Cannot create two fields with the same name.'));
     }
 
-    // Check that invalid field names are rejected.
-    $field_definition = array(
-      'field_name' => 'field_#',
-      'type' => 'test_field',
-    );
+    // Check that field type is required.
     try {
+      $field_definition = array(
+        'field_name' => 'field_1',
+      );
+      field_create_field($field_definition);
+      $this->fail(t('Cannot create a field with no type.'));
+    }
+    catch (FieldException $e) {
+      $this->pass(t('Cannot create a field with no type.'));
+    }
+
+    // Check that field name is required.
+    try {
+      $field_definition = array(
+        'type' => 'test_field'
+      );
+      field_create_field($field_definition);
+      $this->fail(t('Cannot create an unnamed field.'));
+    }
+    catch (FieldException $e) {
+      $this->pass(t('Cannot create an unnamed field.'));
+    }
+
+    // Check that field name must start with a letter or _.
+    try {
+      $field_definition = array(
+        'field_name' => '2field_2',
+        'type' => 'test_field',
+      );
+      field_create_field($field_definition);
+      $this->fail(t('Cannot create a field with a name starting with a digit.'));
+    }
+    catch (FieldException $e) {
+      $this->pass(t('Cannot create a field with a name starting with a digit.'));
+    }
+
+    // Check that field name must only contain lowercase alphanumeric or _.
+    try {
+      $field_definition = array(
+        'field_name' => 'field#_3',
+        'type' => 'test_field',
+      );
+      field_create_field($field_definition);
+      $this->fail(t('Cannot create a field with a name containing an illegal character.'));
+    }
+    catch (FieldException $e) {
+      $this->pass(t('Cannot create a field with a name containing an illegal character.'));
+    }
+
+    // Check that field name cannot be longer than 32 characters long.
+    try {
+      $field_definition = array(
+        'field_name' => '_12345678901234567890123456789012',
+        'type' => 'test_field',
+      );
       field_create_field($field_definition);
-      $this->fail(t('Cannot create a field with an invalid name.'));
+      $this->fail(t('Cannot create a field with a name longer than 32 characters.'));
     }
     catch (FieldException $e) {
-      $this->pass(t('Cannot create a field with an invalid name.'));
+      $this->pass(t('Cannot create a field with a name longer than 32 characters.'));
     }
-    // TODO : other failures
   }
 
   /**
Index: modules/field/field.crud.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.crud.inc,v
retrieving revision 1.22
diff -u -r1.22 field.crud.inc
--- modules/field/field.crud.inc	2 Aug 2009 11:24:21 -0000	1.22
+++ modules/field/field.crud.inc	5 Aug 2009 22:01:54 -0000
@@ -208,11 +208,17 @@
     throw new FieldException('Attempt to create a field with no type.');
   }
   // Field name cannot contain invalid characters.
-  if (preg_match('/[^a-z0-9_]/', $field['field_name'])) {
-    throw new FieldException('Attempt to create a field with invalid characters. Only alphanumeric characters and underscores are allowed.');
+  if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $field['field_name'])) {
+    throw new FieldException('Attempt to create a field with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character');
   }
 
-  // TODO: check that field_name < 32 chars.
+  // Field name cannot be longer than 32 characters. We use drupal_strlen()
+  // because the DB layer assumes that column widths are given in characters,
+  // not bytes.
+  if (drupal_strlen($field['field_name']) > 32) {
+    throw new FieldException(t('Attempt to create a field with a name longer than 32 characters: %name',
+      array('%name' => $field['field_name'])));
+  }
 
   // Check that the field type is known.
   $field_type = field_info_field_types($field['type']);
@@ -233,6 +239,7 @@
     'locked' => FALSE,
     'settings' => array(),
   );
+
   // Create all per-field-type properties (needed here as long as we have
   // settings that impact column definitions).
   $field['settings'] += field_info_field_settings($field['type']);
