function _captcha_get_posted_captcha_info in CAPTCHA 6.2
Same name and namespace in other branches
- 8 captcha.module \_captcha_get_posted_captcha_info()
- 7 captcha.module \_captcha_get_posted_captcha_info()
Helper function for getting the posted CAPTCHA info (posted form_id and CAPTCHA sessions ID) from a form in case it is posted.
This function hides the form processing mess for several use cases an browser bug workarounds. For example: $element['#post'] can typically be used to get the posted form_id and captcha_sid, but in the case of node preview situations (with correct CAPTCHA response) that does not work and we can get them from $form_state['clicked_button']['#post']. However with Internet Explorer 7, the latter does not work either when submitting the forms (with only one text field) with the enter key (see http://drupal.org/node/534168), in which case we also have to check $form_state['buttons']['button']['0']['#post'].
@todo for Drupal 7 version: is this IE7 workaround still needed?
Parameters
$element the CAPTCHA element.:
$form_state the form state structure to extract the info from.:
$this_form_id the form ID of the form we are currently processing: (which is not necessarily the form that was posted).
Return value
an array with $posted_form_id and $post_captcha_sid (with NULL values if the values could not be found, e.g. for a fresh form).
1 call to _captcha_get_posted_captcha_info()
- captcha_process in ./
captcha.module - Process callback for CAPTCHA form element.
File
- ./
captcha.module, line 527 - This module enables basic CAPTCHA functionality: administrators can add a CAPTCHA to desired forms that users without the 'skip CAPTCHA' permission (typically anonymous visitors) have to solve.
Code
function _captcha_get_posted_captcha_info($element, $form_state, $this_form_id) {
if (isset($form_state['captcha_info'])) {
// We already determined the posted form ID and CAPTCHA session ID
// for this form, so we reuse this info
$posted_form_id = $form_state['captcha_info']['posted_form_id'];
$posted_captcha_sid = $form_state['captcha_info']['captcha_sid'];
}
else {
// We have to determine the posted form ID and CAPTCHA session ID
// from the post data. We have to consider some sources for the post data.
if (isset($element['#post']) && count($element['#post'])) {
$post_data = $element['#post'];
}
else {
if (isset($form_state['clicked_button']['#post'])) {
$post_data = $form_state['clicked_button']['#post'];
}
else {
if (isset($form_state['buttons']['button']['0']['#post'])) {
$post_data = $form_state['buttons']['button']['0']['#post'];
}
else {
// No posted CAPTCHA info found (probably a fresh form).
$post_data = array();
}
}
}
// Get the posted form_id and CAPTCHA session ID.
// Because we possibly use raw post data here,
// we should be extra cautious and filter this data.
$posted_form_id = isset($post_data['form_id']) ? preg_replace("/[^a-z0-9_]/", "", (string) $post_data['form_id']) : NULL;
$posted_captcha_sid = isset($post_data['captcha_sid']) ? (int) $post_data['captcha_sid'] : NULL;
$posted_captcha_token = isset($post_data['captcha_token']) ? preg_replace("/[^a-zA-Z0-9]/", "", (string) $post_data['captcha_token']) : NULL;
if ($posted_form_id == $this_form_id) {
// Check if the posted CAPTCHA token is valid for the posted CAPTCHA
// session ID. Note that we could just check the validity of the CAPTCHA
// token and extract the CAPTCHA session ID from that (without looking at
// the actual posted CAPTCHA session ID). However, here we check both
// the posted CAPTCHA token and session ID: it is a bit more stringent
// and the database query should also be more efficient (because there is
// an index on the CAPTCHA session ID).
if ($posted_captcha_sid != NULL) {
$expected_captcha_token = db_result(db_query("SELECT token FROM {captcha_sessions} WHERE csid = %d", $posted_captcha_sid));
if ($expected_captcha_token !== $posted_captcha_token) {
drupal_set_message(t('CAPTCHA session reuse attack detected.'), 'error');
// Invalidate the CAPTCHA session.
$posted_captcha_sid = NULL;
}
}
}
else {
// The CAPTCHA session ID is specific to the posted form.
// Return NULL, so a new session will be generated for this other form.
$posted_captcha_sid = NULL;
}
}
return array(
$posted_form_id,
$posted_captcha_sid,
);
}