[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#806165: marked as done (jessie-pu: package zendframework/1.12.9+dfsg-2+deb8u5)



Your message dated Sat, 23 Jan 2016 13:57:15 +0000
with message-id <1453557435.1835.52.camel@adam-barratt.org.uk>
and subject line 8.3 point release cleanup
has caused the Debian Bug report #806165,
regarding jessie-pu: package zendframework/1.12.9+dfsg-2+deb8u5
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
806165: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=806165
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

As agreed with the security team, this update aims to fix a security
issue in zendframework (request for Wheezy follows) via pu. Please find
attached the debdiff, as well as the actual patch with some formating
noise removed.

  * Backport security fix from 1.12.17:
    - ZF2015-09: Fixed entropy issue in word CAPTCHA
      http://framework.zend.com/security/advisory/ZF2015-09

Thanks in advance for considering.

Regards

David
diff --git a/debian/changelog b/debian/changelog
index 915004f..9977720 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+zendframework (1.12.9+dfsg-2+deb8u5) jessie; urgency=medium
+
+  * Backport security fix from 1.12.17
+    - ZF2015-09: Fixed entropy issue in word CAPTCHA
+      http://framework.zend.com/security/advisory/ZF2015-09
+
+ -- David Prévot <taffit@debian.org>  Tue, 24 Nov 2015 18:21:26 -0400
+
 zendframework (1.12.9+dfsg-2+deb8u4) jessie-security; urgency=high
 
   * Backport security fixes from 1.12.16:
diff --git a/debian/patches/0008-ZF2015-09-Fixed-entropy-issue-in-word-CAPTCHA.patch b/debian/patches/0008-ZF2015-09-Fixed-entropy-issue-in-word-CAPTCHA.patch
new file mode 100644
index 0000000..412b779
--- /dev/null
+++ b/debian/patches/0008-ZF2015-09-Fixed-entropy-issue-in-word-CAPTCHA.patch
@@ -0,0 +1,347 @@
+From: Enrico Zimuel <e.zimuel@gmail.com>
+Date: Mon, 9 Nov 2015 17:26:45 +0100
+Subject: ZF2015-09: Fixed entropy issue in word CAPTCHA
+
+This patch fixes a potential entropy fixation vector with `Zend_Captcha_Word`.
+Prior to the fix, when selecting letters for the CAPTCHA, `array_rand()` was
+used, which does not use sufficient entropy during randomization. The patch
+backports randomization routines from ZF2 in order to provide a more
+cryptographically secure RNG.
+
+Origin: upstream, https://github.com/zendframework/zf1/commit/4a41392f89bf510a8ab801eacb117fe7ea25b575
+---
+ library/Zend/Captcha/Word.php |  29 +++++++-----
+ library/Zend/Crypt/Math.php   | 100 +++++++++++++++++++++++++++++++++++++++---
+ tests/Zend/Crypt/MathTest.php |  75 +++++++++++++++++++++++++++++--
+ 3 files changed, 183 insertions(+), 21 deletions(-)
+
+diff --git a/library/Zend/Captcha/Word.php b/library/Zend/Captcha/Word.php
+index 1f0e0fc..ba39580 100644
+--- a/library/Zend/Captcha/Word.php
++++ b/library/Zend/Captcha/Word.php
+@@ -22,6 +22,9 @@
+ /** @see Zend_Captcha_Base */
+ require_once 'Zend/Captcha/Base.php';
+ 
++/** @see Zend_Crypt_Math */
++require_once 'Zend/Crypt/Math.php';
++
+ /**
+  * Word-based captcha adapter
+  *
+@@ -39,10 +42,10 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+     /**#@+
+      * @var array Character sets
+      */
+-    static $V  = array("a", "e", "i", "o", "u", "y");
+-    static $VN = array("a", "e", "i", "o", "u", "y","2","3","4","5","6","7","8","9");
+-    static $C  = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z");
+-    static $CN = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z","2","3","4","5","6","7","8","9");
++    static public $V  = array("a", "e", "i", "o", "u", "y");
++    static public $VN = array("a", "e", "i", "o", "u", "y","2","3","4","5","6","7","8","9");
++    static public $C  = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z");
++    static public $CN = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z","2","3","4","5","6","7","8","9");
+     /**#@-*/
+ 
+     /**
+@@ -175,7 +178,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+      *
+      * @return string
+      */
+-    public function getId ()
++    public function getId()
+     {
+         if (null === $this->_id) {
+             $this->_setId($this->_generateRandomId());
+@@ -189,7 +192,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+      * @param string $id
+      * @return Zend_Captcha_Word
+      */
+-    protected function _setId ($id)
++    protected function _setId($id)
+     {
+         $this->_id = $id;
+         return $this;
+@@ -250,7 +253,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+         $this->_useNumbers = $_useNumbers;
+         return $this;
+     }
+-    
++
+     /**
+      * Get session object
+      *
+@@ -280,7 +283,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+     public function setSession(Zend_Session_Namespace $session)
+     {
+         $this->_session = $session;
+-        if($session) {
++        if ($session) {
+             $this->_keepSession = true;
+         }
+         return $this;
+@@ -326,10 +329,12 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+         $vowels     = $this->_useNumbers ? self::$VN : self::$V;
+         $consonants = $this->_useNumbers ? self::$CN : self::$C;
+ 
++        $totIndexCon = count($consonants) - 1;
++        $totIndexVow = count($vowels) - 1;
+         for ($i=0; $i < $wordLen; $i = $i + 2) {
+             // generate word with mix of vowels and consonants
+-            $consonant = $consonants[array_rand($consonants)];
+-            $vowel     = $vowels[array_rand($vowels)];
++            $consonant = $consonants[Zend_Crypt_Math::randInteger(0, $totIndexCon, true)];
++            $vowel     = $vowels[Zend_Crypt_Math::randInteger(0, $totIndexVow, true)];
+             $word     .= $consonant . $vowel;
+         }
+ 
+@@ -347,7 +352,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+      */
+     public function generate()
+     {
+-        if(!$this->_keepSession) {
++        if (!$this->_keepSession) {
+             $this->_session = null;
+         }
+         $id = $this->_generateRandomId();
+@@ -359,7 +364,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
+ 
+     protected function _generateRandomId()
+     {
+-        return md5(mt_rand(0, 1000) . microtime(true));
++        return md5(Zend_Crypt_Math::randBytes(32));
+     }
+ 
+     /**
+diff --git a/library/Zend/Crypt/Math.php b/library/Zend/Crypt/Math.php
+index 40395f5..8882259 100644
+--- a/library/Zend/Crypt/Math.php
++++ b/library/Zend/Crypt/Math.php
+@@ -57,21 +57,109 @@ class Zend_Crypt_Math extends Zend_Crypt_Math_BigInteger
+         }
+         $rand = '';
+         $i2 = strlen($maximum) - 1;
+-        for ($i = 1;$i < $i2;$i++) {
+-            $rand .= mt_rand(0,9);
++        for ($i = 1; $i < $i2; $i++) {
++            $rand .= mt_rand(0, 9);
+         }
+-        $rand .= mt_rand(0,9);
++        $rand .= mt_rand(0, 9);
+         return $rand;
+     }
+ 
+     /**
++     * Return a random strings of $length bytes
++     *
++     * @param  integer $length
++     * @param  boolean $strong
++     * @return string
++     */
++    public static function randBytes($length, $strong = false)
++    {
++        $length = (int) $length;
++        if ($length <= 0) {
++            return false;
++        }
++        if (function_exists('openssl_random_pseudo_bytes')) {
++            $bytes = openssl_random_pseudo_bytes($length, $usable);
++            if ($strong === $usable) {
++                return $bytes;
++            }
++        }
++        if (function_exists('mcrypt_create_iv')) {
++            $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
++            if ($bytes !== false && strlen($bytes) === $length) {
++                return $bytes;
++            }
++        }
++        if (file_exists('/dev/urandom') && is_readable('/dev/urandom')) {
++            $frandom = fopen('/dev/urandom', 'r');
++            if ($frandom !== false) {
++                return fread($frandom, $length);
++            }
++        }
++        if (true === $strong) {
++            require_once 'Zend/Crypt/Exception.php';
++            throw new Zend_Crypt_Exception(
++                'This PHP environment doesn\'t support secure random number generation. ' .
++                'Please consider installing the OpenSSL and/or Mcrypt extensions'
++            );
++        }
++        $rand = '';
++        for ($i = 0; $i < $length; $i++) {
++            $rand .= chr(mt_rand(0, 255));
++        }
++        return $rand;
++    }
++
++    /**
++     * Return a random integer between $min and $max
++     *
++     * @param  integer $min
++     * @param  integer $max
++     * @param  boolean $strong
++     * @return integer
++     */
++    public static function randInteger($min, $max, $strong = false)
++    {
++        if ($min > $max) {
++            require_once 'Zend/Crypt/Exception.php';
++            throw new Zend_Crypt_Exception(
++                'The min parameter must be lower than max parameter'
++            );
++        }
++        $range = $max - $min;
++        if ($range == 0) {
++            return $max;
++        } elseif ($range > PHP_INT_MAX || is_float($range)) {
++            require_once 'Zend/Crypt/Exception.php';
++            throw new Zend_Crypt_Exception(
++                'The supplied range is too great to generate'
++            );
++        }
++        // calculate number of bits required to store range on this machine
++        $r = $range;
++        $bits = 0;
++        while ($r) {
++            $bits++;
++            $r >>= 1;
++        }
++        $bits   = (int) max($bits, 1);
++        $bytes  = (int) max(ceil($bits / 8), 1);
++        $filter = (int) ((1 << $bits) - 1);
++        do {
++            $rnd  = hexdec(bin2hex(self::randBytes($bytes, $strong)));
++            $rnd &= $filter;
++        } while ($rnd > $range);
++        return ($min + $rnd);
++    }
++
++    /**
+      * Get the big endian two's complement of a given big integer in
+      * binary notation
+      *
+      * @param string $long
+      * @return string
+      */
+-    public function btwoc($long) {
++    public function btwoc($long)
++    {
+         if (ord($long[0]) > 127) {
+             return "\x00" . $long;
+         }
+@@ -84,7 +172,8 @@ class Zend_Crypt_Math extends Zend_Crypt_Math_BigInteger
+      * @param string $binary
+      * @return string
+      */
+-    public function fromBinary($binary) {
++    public function fromBinary($binary)
++    {
+         return $this->_math->binaryToInteger($binary);
+     }
+ 
+@@ -98,5 +187,4 @@ class Zend_Crypt_Math extends Zend_Crypt_Math_BigInteger
+     {
+         return $this->_math->integerToBinary($integer);
+     }
+-
+ }
+diff --git a/tests/Zend/Crypt/MathTest.php b/tests/Zend/Crypt/MathTest.php
+index eeb9325..79bd02e 100644
+--- a/tests/Zend/Crypt/MathTest.php
++++ b/tests/Zend/Crypt/MathTest.php
+@@ -21,7 +21,7 @@
+  */
+ 
+ require_once 'Zend/Crypt/Math.php';
+-
++require_once 'Zend/Crypt/Exception.php';
+ 
+ /**
+  * @category   Zend
+@@ -36,8 +36,7 @@ class Zend_Crypt_MathTest extends PHPUnit_Framework_TestCase
+ 
+     public function testRand()
+     {
+-        if (!extension_loaded('bcmath'))
+-        {
++        if (!extension_loaded('bcmath')) {
+             $this->markTestSkipped('Extension bcmath not loaded');
+         }
+ 
+@@ -59,4 +58,74 @@ class Zend_Crypt_MathTest extends PHPUnit_Framework_TestCase
+         $this->assertTrue(bccomp($result, $lower) !== '-1');
+     }
+ 
++    public function testRandBytes()
++    {
++        for ($length = 1; $length < 4096; $length++) {
++            $rand = Zend_Crypt_Math::randBytes($length);
++            $this->assertTrue(false !== $rand);
++            $this->assertEquals($length, strlen($rand));
++        }
++    }
++
++    public function testRandInteger()
++    {
++        for ($i = 0; $i < 1024; $i++) {
++            $min = rand(1, PHP_INT_MAX/2);
++            $max = $min + rand(1, PHP_INT_MAX/2 - 1);
++            $rand = Zend_Crypt_Math::randInteger($min, $max);
++            $this->assertGreaterThanOrEqual($min, $rand);
++            $this->assertLessThanOrEqual($max, $rand);
++        }
++    }
++
++    public static function provideRandInt()
++    {
++        return [
++            [2, 1, 10000, 100, 0.9, 1.1, false],
++            [2, 1, 10000, 100, 0.8, 1.2, true]
++        ];
++    }
++
++    /**
++     * A Monte Carlo test that generates $cycles numbers from 0 to $tot
++     * and test if the numbers are above or below the line y=x with a
++     * frequency range of [$min, $max]
++     *
++     * @dataProvider provideRandInt
++     */
++    public function testMontecarloRandInteger($num, $valid, $cycles, $tot, $min, $max, $strong)
++    {
++        try {
++            $test = Zend_Crypt_Math::randBytes(1, $strong);
++        } catch (Zend_Crypt_Exception $e) {
++            $this->markTestSkipped($e->getMessage());
++        }
++
++        $i     = 0;
++        $count = 0;
++        do {
++            $up   = 0;
++            $down = 0;
++            for ($i = 0; $i < $cycles; $i++) {
++                $x = Zend_Crypt_Math::randInteger(0, $tot, $strong);
++                $y = Zend_Crypt_Math::randInteger(0, $tot, $strong);
++                if ($x > $y) {
++                    $up++;
++                } elseif ($x < $y) {
++                    $down++;
++                }
++            }
++            $this->assertGreaterThan(0, $up);
++            $this->assertGreaterThan(0, $down);
++            $ratio = $up / $down;
++            if ($ratio > $min && $ratio < $max) {
++                $count++;
++            }
++            $i++;
++        } while ($i < $num && $count < $valid);
++
++        if ($count < $valid) {
++            $this->fail('The random number generator failed the Monte Carlo test');
++        }
++    }
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 6c2191f..f9d3a80 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -5,3 +5,4 @@
 0005-ZF2015-06-Fix-potential-XXE-vector-via-BOM-detection.patch
 0006-ZF2015-07-Use-umask-of-0002.patch
 0007-ZF2015-08-Fix-null-byte-injection-for-PDO-MsSql.patch
+0008-ZF2015-09-Fixed-entropy-issue-in-word-CAPTCHA.patch
diff --git a/library/Zend/Captcha/Word.php b/library/Zend/Captcha/Word.php
index 1f0e0fc..ba39580 100644
--- a/library/Zend/Captcha/Word.php
+++ b/library/Zend/Captcha/Word.php
@@ -22,6 +22,9 @@
 /** @see Zend_Captcha_Base */
 require_once 'Zend/Captcha/Base.php';
 
+/** @see Zend_Crypt_Math */
+require_once 'Zend/Crypt/Math.php';
+
 /**
  * Word-based captcha adapter
  *
@@ -39,10 +42,10 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
     /**#@+
      * @var array Character sets
      */
-    static $V  = array("a", "e", "i", "o", "u", "y");
-    static $VN = array("a", "e", "i", "o", "u", "y","2","3","4","5","6","7","8","9");
-    static $C  = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z");
-    static $CN = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z","2","3","4","5","6","7","8","9");
+    static public $V  = array("a", "e", "i", "o", "u", "y");
+    static public $VN = array("a", "e", "i", "o", "u", "y","2","3","4","5","6","7","8","9");
+    static public $C  = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z");
+    static public $CN = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z","2","3","4","5","6","7","8","9");
     /**#@-*/
 
     /**
@@ -326,10 +329,12 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
         $vowels     = $this->_useNumbers ? self::$VN : self::$V;
         $consonants = $this->_useNumbers ? self::$CN : self::$C;
 
+        $totIndexCon = count($consonants) - 1;
+        $totIndexVow = count($vowels) - 1;
         for ($i=0; $i < $wordLen; $i = $i + 2) {
             // generate word with mix of vowels and consonants
-            $consonant = $consonants[array_rand($consonants)];
-            $vowel     = $vowels[array_rand($vowels)];
+            $consonant = $consonants[Zend_Crypt_Math::randInteger(0, $totIndexCon, true)];
+            $vowel     = $vowels[Zend_Crypt_Math::randInteger(0, $totIndexVow, true)];
             $word     .= $consonant . $vowel;
         }
 
@@ -359,7 +364,7 @@ abstract class Zend_Captcha_Word extends Zend_Captcha_Base
 
     protected function _generateRandomId()
     {
-        return md5(mt_rand(0, 1000) . microtime(true));
+        return md5(Zend_Crypt_Math::randBytes(32));
     }
 
     /**
diff --git a/library/Zend/Crypt/Math.php b/library/Zend/Crypt/Math.php
index 40395f5..8882259 100644
--- a/library/Zend/Crypt/Math.php
+++ b/library/Zend/Crypt/Math.php
@@ -65,13 +65,101 @@ class Zend_Crypt_Math extends Zend_Crypt_Math_BigInteger
     }
 
     /**
+     * Return a random strings of $length bytes
+     *
+     * @param  integer $length
+     * @param  boolean $strong
+     * @return string
+     */
+    public static function randBytes($length, $strong = false)
+    {
+        $length = (int) $length;
+        if ($length <= 0) {
+            return false;
+        }
+        if (function_exists('openssl_random_pseudo_bytes')) {
+            $bytes = openssl_random_pseudo_bytes($length, $usable);
+            if ($strong === $usable) {
+                return $bytes;
+            }
+        }
+        if (function_exists('mcrypt_create_iv')) {
+            $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
+            if ($bytes !== false && strlen($bytes) === $length) {
+                return $bytes;
+            }
+        }
+        if (file_exists('/dev/urandom') && is_readable('/dev/urandom')) {
+            $frandom = fopen('/dev/urandom', 'r');
+            if ($frandom !== false) {
+                return fread($frandom, $length);
+            }
+        }
+        if (true === $strong) {
+            require_once 'Zend/Crypt/Exception.php';
+            throw new Zend_Crypt_Exception(
+                'This PHP environment doesn\'t support secure random number generation. ' .
+                'Please consider installing the OpenSSL and/or Mcrypt extensions'
+            );
+        }
+        $rand = '';
+        for ($i = 0; $i < $length; $i++) {
+            $rand .= chr(mt_rand(0, 255));
+        }
+        return $rand;
+    }
+
+    /**
+     * Return a random integer between $min and $max
+     *
+     * @param  integer $min
+     * @param  integer $max
+     * @param  boolean $strong
+     * @return integer
+     */
+    public static function randInteger($min, $max, $strong = false)
+    {
+        if ($min > $max) {
+            require_once 'Zend/Crypt/Exception.php';
+            throw new Zend_Crypt_Exception(
+                'The min parameter must be lower than max parameter'
+            );
+        }
+        $range = $max - $min;
+        if ($range == 0) {
+            return $max;
+        } elseif ($range > PHP_INT_MAX || is_float($range)) {
+            require_once 'Zend/Crypt/Exception.php';
+            throw new Zend_Crypt_Exception(
+                'The supplied range is too great to generate'
+            );
+        }
+        // calculate number of bits required to store range on this machine
+        $r = $range;
+        $bits = 0;
+        while ($r) {
+            $bits++;
+            $r >>= 1;
+        }
+        $bits   = (int) max($bits, 1);
+        $bytes  = (int) max(ceil($bits / 8), 1);
+        $filter = (int) ((1 << $bits) - 1);
+        do {
+            $rnd  = hexdec(bin2hex(self::randBytes($bytes, $strong)));
+            $rnd &= $filter;
+        } while ($rnd > $range);
+        return ($min + $rnd);
+    }
+
+    /**
      * Get the big endian two's complement of a given big integer in
      * binary notation
      *
      * @param string $long
      * @return string
      */
-    public function btwoc($long) {
+    public function btwoc($long)
+    {
         if (ord($long[0]) > 127) {
             return "\x00" . $long;
         }
diff --git a/tests/Zend/Crypt/MathTest.php b/tests/Zend/Crypt/MathTest.php
index eeb9325..79bd02e 100644
--- a/tests/Zend/Crypt/MathTest.php
+++ b/tests/Zend/Crypt/MathTest.php
@@ -21,7 +21,7 @@
  */
 
 require_once 'Zend/Crypt/Math.php';
-
+require_once 'Zend/Crypt/Exception.php';
 
 /**
  * @category   Zend
@@ -59,4 +58,74 @@ class Zend_Crypt_MathTest extends PHPUnit_Framework_TestCase
         $this->assertTrue(bccomp($result, $lower) !== '-1');
     }
 
+    public function testRandBytes()
+    {
+        for ($length = 1; $length < 4096; $length++) {
+            $rand = Zend_Crypt_Math::randBytes($length);
+            $this->assertTrue(false !== $rand);
+            $this->assertEquals($length, strlen($rand));
+        }
+    }
+
+    public function testRandInteger()
+    {
+        for ($i = 0; $i < 1024; $i++) {
+            $min = rand(1, PHP_INT_MAX/2);
+            $max = $min + rand(1, PHP_INT_MAX/2 - 1);
+            $rand = Zend_Crypt_Math::randInteger($min, $max);
+            $this->assertGreaterThanOrEqual($min, $rand);
+            $this->assertLessThanOrEqual($max, $rand);
+        }
+    }
+
+    public static function provideRandInt()
+    {
+        return [
+            [2, 1, 10000, 100, 0.9, 1.1, false],
+            [2, 1, 10000, 100, 0.8, 1.2, true]
+        ];
+    }
+
+    /**
+     * A Monte Carlo test that generates $cycles numbers from 0 to $tot
+     * and test if the numbers are above or below the line y=x with a
+     * frequency range of [$min, $max]
+     *
+     * @dataProvider provideRandInt
+     */
+    public function testMontecarloRandInteger($num, $valid, $cycles, $tot, $min, $max, $strong)
+    {
+        try {
+            $test = Zend_Crypt_Math::randBytes(1, $strong);
+        } catch (Zend_Crypt_Exception $e) {
+            $this->markTestSkipped($e->getMessage());
+        }
+
+        $i     = 0;
+        $count = 0;
+        do {
+            $up   = 0;
+            $down = 0;
+            for ($i = 0; $i < $cycles; $i++) {
+                $x = Zend_Crypt_Math::randInteger(0, $tot, $strong);
+                $y = Zend_Crypt_Math::randInteger(0, $tot, $strong);
+                if ($x > $y) {
+                    $up++;
+                } elseif ($x < $y) {
+                    $down++;
+                }
+            }
+            $this->assertGreaterThan(0, $up);
+            $this->assertGreaterThan(0, $down);
+            $ratio = $up / $down;
+            if ($ratio > $min && $ratio < $max) {
+                $count++;
+            }
+            $i++;
+        } while ($i < $num && $count < $valid);
+
+        if ($count < $valid) {
+            $this->fail('The random number generator failed the Monte Carlo test');
+        }
+    }
 }

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Version: 8.3

Hi,

The updates referred to in these bugs were included in today's 8.3
Jessie point release.

Regards,

Adam

--- End Message ---

Reply to: