diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 77050d360f..acec7e71fd 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -79,6 +79,7 @@ p,ul,td {font-size:10pt;}
  • [Fix] Changed filtering of short search terms
  • [Sec] Improved filtering on language selection (also addresses a number of bug reports related to missing languages)
  • [Change] Backported more efficient highlighting code from Olympus
  • +
  • [Change] Backported zlib emulation code so that there is only a single confirmation image even if zlib is not available
  • diff --git a/phpBB/includes/usercp_confirm.php b/phpBB/includes/usercp_confirm.php index f829833246..d1be3422e9 100644 --- a/phpBB/includes/usercp_confirm.php +++ b/phpBB/includes/usercp_confirm.php @@ -66,108 +66,89 @@ else exit; } -// If we can we will generate a single filtered png else we will have to simply -// output six seperate original pngs ... first way is preferable! -if (@extension_loaded('zlib')) +// We can we will generate a single filtered png +// Thanks to DavidMJ for emulating zlib within the code :) +$_png = define_filtered_pngs(); + +$total_width = 320; +$total_height = 50; +$img_height = 40; +$img_width = 0; +$l = 0; + +list($usec, $sec) = explode(' ', microtime()); +mt_srand($sec * $usec); + +$char_widths = array(); +for ($i = 0; $i < strlen($code); $i++) { - $_png = define_filtered_pngs(); + $char = $code{$i}; - $total_width = 320; - $total_height = 50; - $img_height = 40; - $img_width = 0; - $l = 0; - - list($usec, $sec) = explode(' ', microtime()); - mt_srand($sec * $usec); - - $char_widths = array(); - for ($i = 0; $i < strlen($code); $i++) - { - $char = $code{$i}; - - $width = mt_rand(0, 4); - $char_widths[] = $width; - $img_width += $_png[$char]['width'] - $width; - } - - $offset_x = mt_rand(0, $total_width - $img_width); - $offset_y = mt_rand(0, $total_height - $img_height); - - $image = ''; - $hold_chars = array(); - for ($i = 0; $i < $total_height; $i++) - { - $image .= chr(0); - - if ($i > $offset_y && $i < $offset_y + $img_height) - { - $j = 0; - - for ($k = 0; $k < $offset_x; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - for ($k = 0; $k < strlen($code); $k++) - { - $char = $code{$k}; - - if (empty($hold_chars[$char])) - { - $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); - } - $image .= randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); - $j++; - } - - for ($k = $offset_x + $img_width; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - $l++; - } - else - { - for ($k = 0; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - } - - } - unset($hold); - - $image = create_png(gzcompress($image), $total_width, $total_height); - - // Output image - header('Content-Type: image/png'); - header('Cache-control: no-cache, no-store'); - echo $image; - - unset($image); - unset($_png); - exit; - -} -else -{ - $_png = define_raw_pngs(); - - $c = intval($HTTP_GET_VARS['c']); - $char = substr($code, $c - 1, 1); - - header('Content-Type: image/png'); - header('Cache-control: no-cache, no-store'); - echo base64_decode($_png[$char]); - - unset($_png); - exit; + $width = mt_rand(0, 4); + $char_widths[] = $width; + $img_width += $_png[$char]['width'] - $width; } +$offset_x = mt_rand(0, $total_width - $img_width); +$offset_y = mt_rand(0, $total_height - $img_height); + +$image = ''; +$hold_chars = array(); +for ($i = 0; $i < $total_height; $i++) +{ + $image .= chr(0); + + if ($i > $offset_y && $i < $offset_y + $img_height) + { + $j = 0; + + for ($k = 0; $k < $offset_x; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + for ($k = 0; $k < strlen($code); $k++) + { + $char = $code{$k}; + + if (empty($hold_chars[$char])) + { + $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); + } + $image .= randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); + $j++; + } + + for ($k = $offset_x + $img_width; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + $l++; + } + else + { + for ($k = 0; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + } + +} +unset($hold); + +$image = create_png($image, $total_width, $total_height); + +// Output image +header('Content-Type: image/png'); +header('Cache-control: no-cache, no-store'); +echo $image; + +unset($image); +unset($_png); exit; + // This is designed to randomise the pixels of the image data within // certain limits so as to keep it readable. It also varies the image // width a little @@ -214,7 +195,7 @@ function png_chunk($length, $type, $data) // http://www.libpng.org/pub/png/spec/PNG-Contents.html we use // png because it's a fully recognised open standard and supported // by practically all modern browsers and OSs -function create_png($gzimage, $width, $height) +function create_png($raw_image, $width, $height) { // SIG $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); @@ -223,8 +204,53 @@ function create_png($gzimage, $width, $height) $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); $raw .= pack('C5', 8, 0, 0, 0, 0); $image .= png_chunk(13, 'IHDR', $raw); + + if (@extension_loaded('zlib')) + { + $raw_image = gzcompress($raw_image); + $length = strlen($raw_image); + } + else + { + // The total length of this image, uncompressed, is just a calculation of pixels + $length = ($width + 1) * $height; + + // Adler-32 hash generation + // Optimized Adler-32 loop ported from the GNU Classpath project + $temp_length = $length; + $s1 = 1; + $s2 = $index = 0; + + while ($temp_length > 0) + { + // We can defer the modulo operation: + // s1 maximally grows from 65521 to 65521 + 255 * 3800 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 + $substract_value = ($temp_length < 3800) ? $temp_length : 3800; + $temp_length -= $substract_value; + + while (--$substract_value >= 0) + { + $s1 += ord($raw_image[$index]); + $s2 += $s1; + + $index++; + } + + $s1 %= 65521; + $s2 %= 65521; + } + $adler_hash = pack('N', ($s2 << 16) | $s1); + + // This is the same thing as gzcompress($raw_image, 0) but does not need zlib + $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; + + // The Zlib header + Adler hash make us add on 11 + $length += 11; + } + // IDAT - $image .= png_chunk(strlen($gzimage), 'IDAT', $gzimage); + $image .= png_chunk($length, 'IDAT', $raw_image); // IEND $image .= png_chunk(0, 'IEND', ''); diff --git a/phpBB/includes/usercp_register.php b/phpBB/includes/usercp_register.php index f45ce50eda..05efe1ee21 100644 --- a/phpBB/includes/usercp_register.php +++ b/phpBB/includes/usercp_register.php @@ -991,7 +991,7 @@ else // Generate the required confirmation code // NB 0 (zero) could get confused with O (the letter) so we make change it $code = dss_rand(); - $code = strtoupper(str_replace('0', 'o', substr($code, 2, 6))); + $code = substr(str_replace('0', 'Z', strtoupper(base_convert($code, 16, 35))), 2, 6); $confirm_id = md5(uniqid($user_ip)); @@ -1004,7 +1004,7 @@ else unset($code); - $confirm_image = (@extension_loaded('zlib')) ? '' : ''; + $confirm_image = ''; $s_hidden_fields .= ''; $template->assign_block_vars('switch_confirm', array());