Index: captcha.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.admin.inc,v retrieving revision 1.27 diff -u -b -u -p -r1.27 captcha.admin.inc --- captcha.admin.inc 19 Jun 2009 13:04:00 -0000 1.27 +++ captcha.admin.inc 21 Jun 2009 18:48:02 -0000 @@ -154,11 +154,15 @@ function captcha_admin_settings() { } // Option for case sensitive/insensitive validation of the responses. - $form['captcha_case_sensitive_validation'] = array( - '#type' => 'checkbox', - '#title' => t('Case sensitive validation'), - '#description' => t('Disable this option to ignore uppercase/lowercase errors in the response.'), - '#default_value' => variable_get('captcha_case_sensitive_validation', TRUE), + $form['captcha_default_validation'] = array( + '#type' => 'radios', + '#title' => t('Default validation'), + '#description' => t('Define how the response should be processed by default. Modules that implement the actual challenge can override or ignore this.'), + '#options' => array( + CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE => t('Case sensitive validation: the response has to exactly match the solution.'), + CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE => t('Case insensitive validation: lowercase/uppercase errors are ignored.'), + ), + '#default_value' => variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE), ); // Field for CAPTCHA persistence. @@ -278,7 +282,7 @@ function captcha_admin_settings_submit($ } } - variable_set('captcha_case_sensitive_validation', $form_state['values']['captcha_case_sensitive_validation']); + variable_set('captcha_default_validation', $form_state['values']['captcha_default_validation']); variable_set('captcha_persistence', $form_state['values']['captcha_persistence']); variable_set('captcha_log_wrong_responses', $form_state['values']['captcha_log_wrong_responses']); Index: captcha.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.module,v retrieving revision 1.95 diff -u -b -u -p -r1.95 captcha.module --- captcha.module 21 Jun 2009 18:46:15 -0000 1.95 +++ captcha.module 21 Jun 2009 18:48:02 -0000 @@ -19,6 +19,9 @@ define('CAPTCHA_STATUS_UNSOLVED', 0); define('CAPTCHA_STATUS_SOLVED', 1); define('CAPTCHA_STATUS_EXAMPLE', 2); +define('CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE', 0); +define('CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE', 1); + /** * Implementation of hook_help(). */ @@ -155,7 +158,7 @@ function captcha_cron() { */ function captcha_elements() { // Define the CAPTCHA form element with default properties. - return array('captcha' => array( + $captcha_element = array( '#input' => TRUE, '#process' => array('captcha_process'), // The type of challenge: e.g. 'default', 'none', 'captcha/Math', 'image_captcha/Image', ... @@ -163,7 +166,14 @@ function captcha_elements() { '#default_value' => '', // CAPTCHA in admin mode: presolve the CAPTCHA and always show it (despite previous successful responses). '#captcha_admin_mode' => FALSE, - )); + // The default CAPTCHA validation function. + '#captcha_validate' => 'captcha_validate_strict_equality', + ); + // Override the default CAPTCHA validation function for case insensitive validation. + if (CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE == variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE)) { + $captcha_element['#captcha_validate'] = 'captcha_validate_case_insensitive_equality'; + } + return array('captcha' => $captcha_element); } /** @@ -216,11 +226,16 @@ function captcha_process($element, $edit // Add form elements from challenge as children to CAPTCHA form element. $element['captcha_widgets'] = $captcha['form']; + // Add a validation callback for the CAPTCHA form element (when not in admin mode). if (!$element['#captcha_admin_mode']) { - // Add a validation callback for the CAPTCHA form element. $element['#element_validate'] = array('captcha_validate'); } + // Set a custom CAPTCHA validate function if requested. + if (isset($captcha['captcha_validate'])) { + $element['#captcha_validate'] = $captcha['captcha_validate']; + } + // Add pre_render callback for additional CAPTCHA processing. $element['#pre_render'] = array('captcha_pre_render_process'); @@ -348,6 +363,26 @@ function captcha_form_alter(&$form, $for } /** + * CAPTCHA validation function to tests strict equality. + * @param $solution the solution of the test. + * @param $response the response to the test. + * @return TRUE when strictly equal, FALSE otherwise. + */ +function captcha_validate_strict_equality($solution, $response) { + return $solution === $response; +} + +/** + * CAPTCHA validation function to tests case insensitive equality. + * @param $solution the solution of the test. + * @param $response the response to the test. + * @return TRUE when case insensitive equal, FALSE otherwise. + */ +function captcha_validate_case_insensitive_equality($solution, $response) { + return strtolower($solution) === strtolower($response); +} + +/** * CAPTCHA validation handler. * * This function is placed in the main captcha.module file to make sure that @@ -380,13 +415,13 @@ function captcha_validate($element, &$fo form_set_error('captcha', t('CAPTCHA test failed (unknown csid).')); } else { - // In case of case insensitive validation: convert solution and response to lower case. - if (!variable_get('captcha_case_sensitive_validation', TRUE)) { - $solution = strtolower($solution); - $captcha_response = strtolower($captcha_response); + // Get CAPTCHA validate function or fall back on strict equality. + $captcha_validate = $element['#captcha_validate']; + if (!function_exists($captcha_validate)) { + $captcha_validate = 'captcha_validate_strict_equality'; } - // Check answer. - if ($captcha_response == $solution) { + // Check the response. + if ($captcha_validate($solution, $captcha_response)) { // Correct answer. $_SESSION['captcha_success_form_ids'][$form_id] = $form_id; // Record success. Index: captcha.test =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.test,v retrieving revision 1.12 diff -u -b -u -p -r1.12 captcha.test --- captcha.test 26 May 2009 21:55:25 -0000 1.12 +++ captcha.test 21 Jun 2009 18:48:03 -0000 @@ -135,14 +135,14 @@ class CapchaTestCase extends DrupalWebTe // Log in as normal user. $this->drupalLogin($this->normal_user); - // Test case sensitive posting (the default) - variable_set('captcha_case_sensitive_validation', TRUE); + // Test case sensitive posting. + variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE); $this->assertCommentPosting('Test 123', TRUE, 'Case sensitive validation of right casing.'); $this->assertCommentPosting('test 123', FALSE, 'Case sensitive validation of wrong casing.'); $this->assertCommentPosting('TEST 123', FALSE, 'Case sensitive validation of wrong casing.'); // Test case insensitive posting (the default) - variable_set('captcha_case_sensitive_validation', FALSE); + variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE); $this->assertCommentPosting('Test 123', TRUE, 'Case insensitive validation of right casing.'); $this->assertCommentPosting('test 123', TRUE, 'Case insensitive validation of wrong casing.'); $this->assertCommentPosting('TEST 123', TRUE, 'Case insensitive validation of wrong casing.'); Index: image_captcha/image_captcha.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/image_captcha/image_captcha.module,v retrieving revision 1.25 diff -u -b -u -p -r1.25 image_captcha.module --- image_captcha/image_captcha.module 14 May 2009 22:47:38 -0000 1.25 +++ image_captcha/image_captcha.module 21 Jun 2009 18:48:03 -0000 @@ -162,7 +162,7 @@ function image_captcha_captcha($op, $cap // Handle the case insesitivity option and change the code to lower case // before saving it as solution. - if (variable_get('captcha_case_sensitive_validation', TRUE)) { + if (CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE == variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE)) { $description = t('Enter the characters shown in the image. Ignore spaces and be careful about upper and lower case.'); } else {