From 6f466c7fab655ddd35dd6048015f3312b5d49598 Mon Sep 17 00:00:00 2001
From: Marc Bennewitz <marc-bennewitz@arcor.de>
Date: Sun, 29 May 2011 19:55:03 +0200
Subject: [PATCH 1/2] removed own php error handler on reading config data

---
 library/Zend/Config/Config.php       | 26 -------------------------
 library/Zend/Config/Ini.php          | 29 ++++++----------------------
 library/Zend/Config/Json.php         | 17 +++++++---------
 library/Zend/Config/Xml.php          | 29 ++++++++++++++++++++++------
 library/Zend/Config/Yaml.php         | 13 +++++--------
 tests/Zend/Config/XmlTest.php        | 17 ++++++++++++++--
 tests/Zend/Config/_files/invalid.xml |  2 +-
 7 files changed, 57 insertions(+), 76 deletions(-)

diff --git a/library/Zend/Config/Config.php b/library/Zend/Config/Config.php
index 78593ff7788..5fff778378d 100644
--- a/library/Zend/Config/Config.php
+++ b/library/Zend/Config/Config.php
@@ -85,15 +85,6 @@ class Config implements \Countable, \Iterator
      */
     protected $_extends = array();
 
-    /**
-     * Load file error string.
-     *
-     * Is null if there was no error while file loading
-     *
-     * @var string
-     */
-    protected $_loadFileErrorStr = null;
-
     /**
      * Zend_Config provides a property based interface to
      * an array. The data are read-only unless $allowModifications
@@ -434,23 +425,6 @@ protected function _assertValidExtend($extendingSection, $extendedSection)
         $this->_extends[$extendingSection] = $extendedSection;
     }
 
-    /**
-     * Handle any errors from simplexml_load_file or parse_ini_file
-     *
-     * @param integer $errno
-     * @param string $errstr
-     * @param string $errfile
-     * @param integer $errline
-     */
-    protected function _loadFileErrorHandler($errno, $errstr, $errfile, $errline)
-    {
-        if ($this->_loadFileErrorStr === null) {
-            $this->_loadFileErrorStr = $errstr;
-        } else {
-            $this->_loadFileErrorStr .= (PHP_EOL . $errstr);
-        }
-    }
-
     /**
      * Merge two arrays recursively, overwriting keys of the same name
      * in $firstArray with the value in $secondArray.
diff --git a/library/Zend/Config/Ini.php b/library/Zend/Config/Ini.php
index b1b2da46cdd..5ea267ec6bc 100644
--- a/library/Zend/Config/Ini.php
+++ b/library/Zend/Config/Ini.php
@@ -148,28 +148,6 @@ public function __construct($filename, $section = null, $options = false)
 
         $this->_loadedSection = $section;
     }
-    
-    /**
-     * Load the INI file from disk using parse_ini_file(). Use a private error
-     * handler to convert any loading errors into a Zend_Config_Exception
-     * 
-     * @param string $filename
-     * @throws \Zend\Config\Exception
-     * @return array
-     */
-    protected function _parseIniFile($filename)
-    {
-        set_error_handler(array($this, '_loadFileErrorHandler'));
-        $iniArray = parse_ini_file($filename, true); // Warnings and errors are suppressed
-        restore_error_handler();
-        
-        // Check if there was a error while loading file
-        if ($this->_loadFileErrorStr !== null) {
-            throw new Exception\RuntimeException($this->_loadFileErrorStr);
-        }
-        
-        return $iniArray;
-    }
 
     /**
      * Load the ini file and preprocess the section separator (':' in the
@@ -185,7 +163,12 @@ protected function _parseIniFile($filename)
      */
     protected function _loadIniFile($filename)
     {
-        $loaded = $this->_parseIniFile($filename);
+        $loaded = @parse_ini_file($filename, true);
+        if ($loaded === false) {
+            $err = error_get_last();
+            throw new Exception\RuntimeException($err['message']);
+        }
+
         $iniArray = array();
         foreach ($loaded as $key => $data)
         {
diff --git a/library/Zend/Config/Json.php b/library/Zend/Config/Json.php
index 97a61d30bd4..d008b46ce1b 100755
--- a/library/Zend/Config/Json.php
+++ b/library/Zend/Config/Json.php
@@ -102,15 +102,12 @@ public function __construct($json, $section = null, $options = false)
             }
         }
 
-        set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed
         if ($json[0] != '{') {
-            $json = file_get_contents($json);
-        }
-        restore_error_handler();
-
-        // Check if there was a error while loading file
-        if ($this->_loadFileErrorStr !== null) {
-            throw new Exception\RuntimeException($this->_loadFileErrorStr);
+            $json = @file_get_contents($json);
+            if ($json === false) {
+                $err = error_get_last();
+                throw new Exception\RuntimeException($err['message']);
+            }
         }
 
         // Replace constants
@@ -229,8 +226,8 @@ protected function _getConstants()
 
     /**
      * Flatten JSON object structure to associative array
-     * 
-     * @param  object|array $config 
+     *
+     * @param  object|array $config
      * @return array
      */
     protected function flattenObjects($config)
diff --git a/library/Zend/Config/Xml.php b/library/Zend/Config/Xml.php
index fe236bb6249..79613b7206c 100644
--- a/library/Zend/Config/Xml.php
+++ b/library/Zend/Config/Xml.php
@@ -84,17 +84,34 @@ public function __construct($xml, $section = null, $options = false)
             }
         }
 
-        set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed
+        // load XML and throw exception of each failure using previous exception
+        $oldUseInternalErrors = libxml_use_internal_errors(true);
+        if ($oldUseInternalErrors) {
+            libxml_clear_errors();
+        }
         if (strstr($xml, '<' . '?xml')) { // string concat to fix syntax highlighting
             $config = simplexml_load_string($xml);
         } else {
             $config = simplexml_load_file($xml);
         }
-
-        restore_error_handler();
-        // Check if there was a error while loading file
-        if ($this->_loadFileErrorStr !== null) {
-            throw new Exception\InvalidArgumentException($this->_loadFileErrorStr);
+        $xmlErrors = libxml_get_errors();
+        if (!$oldUseInternalErrors) {
+            libxml_use_internal_errors(false);
+        }
+        if ( ($xmlErrorCnt = count($xmlErrors)) ) {
+            libxml_clear_errors();
+
+            // create and throw exception stack
+            $e = null;
+            foreach ($xmlErrors as $xmlError) {
+                $e = new Exception\InvalidArgumentException(
+                    trim($xmlError->message)
+                    . ' @ line/column ' . $xmlError->line . '/' . $xmlError->column,
+                    0,
+                    $e
+                );
+            }
+            throw $e;
         }
 
         if ($section === null) {
diff --git a/library/Zend/Config/Yaml.php b/library/Zend/Config/Yaml.php
index 47f38b399d5..ce2c49a0603 100755
--- a/library/Zend/Config/Yaml.php
+++ b/library/Zend/Config/Yaml.php
@@ -158,14 +158,11 @@ public function __construct($yaml, $section = null, $options = false)
             }
         }
 
-        // Suppress warnings and errors while loading file
-        set_error_handler(array($this, '_loadFileErrorHandler'));
-        $yaml = file_get_contents($yaml);
-        restore_error_handler();
-
-        // Check if there was a error while loading file
-        if ($this->_loadFileErrorStr !== null) {
-            throw new Exception\RuntimeException($this->_loadFileErrorStr);
+        // read the yaml file
+        $yaml = @file_get_contents($yaml);
+        if ($yaml === false) {
+            $err = error_get_last();
+            throw new Exception\RuntimeException($err['message']);
         }
 
         // Override static value for ignore_constants if provided in $options
diff --git a/tests/Zend/Config/XmlTest.php b/tests/Zend/Config/XmlTest.php
index 562b126e4b5..e51349a63da 100644
--- a/tests/Zend/Config/XmlTest.php
+++ b/tests/Zend/Config/XmlTest.php
@@ -181,11 +181,24 @@ public function testZF2437_ArraysWithMultipleChildren()
 
     /**
      * @group ZF-3578
+     * @group ZF2-13
      */
     public function testInvalidXmlFile()
     {
-        $this->setExpectedException('Zend\Config\Exception\InvalidArgumentException', 'parser error');
-        $config = new Xml($this->_xmlFileInvalid);
+        try {
+            $config = new Xml($this->_xmlFileInvalid);
+            $this->fail('Missing expected exception');
+        } catch (\Zend\Config\Exception\InvalidArgumentException $e) {
+            // read exception stack
+            do {
+                $stack[] = $e;
+            } while ( ($e = $e->getPrevious()) );
+
+            // test two thrown xml errors
+            $this->assertEquals(2, count($stack));
+            $this->assertContains('tag mismatch', $stack[0]->getMessage());
+            $this->assertContains('undefined', $stack[1]->getMessage());
+        }
     }
 
     /**
diff --git a/tests/Zend/Config/_files/invalid.xml b/tests/Zend/Config/_files/invalid.xml
index 82769b38035..ad5f2247709 100644
--- a/tests/Zend/Config/_files/invalid.xml
+++ b/tests/Zend/Config/_files/invalid.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <config>
     <a extends="c">
-        <someKey>value_A</someKey>
+        <someKey>InvalidValue &undefined;</someKey>
     </a>
     <b extends="a">
         <someKey>value_B</someKey>

From 54380b847b8a78b8c82802aad29904977c626759 Mon Sep 17 00:00:00 2001
From: Marc Bennewitz <marc-bennewitz@arcor.de>
Date: Fri, 22 Jul 2011 17:20:51 +0200
Subject: [PATCH 2/2] ZF2-13:  - better error handling on reading/parsing
 config files  - throw exception stack on more than one error  - fixed test
 names

---
 library/Zend/Config/Config.php       |  46 +++++++++++-
 library/Zend/Config/Ini.php          |  12 +++-
 library/Zend/Config/Json.php         |  16 +++--
 library/Zend/Config/Xml.php          |  10 +--
 library/Zend/Config/Yaml.php         |  17 +++--
 tests/Zend/Config/IniTest.php        | 104 ++++++++++++++++++++-------
 tests/Zend/Config/JsonTest.php       |   1 -
 tests/Zend/Config/XmlTest.php        |  47 ++++++++----
 tests/Zend/Config/YamlTest.php       |  54 +++++++++++---
 tests/Zend/Config/_files/invalid.ini |   1 +
 10 files changed, 238 insertions(+), 70 deletions(-)

diff --git a/library/Zend/Config/Config.php b/library/Zend/Config/Config.php
index 5fff778378d..f854d9a6881 100644
--- a/library/Zend/Config/Config.php
+++ b/library/Zend/Config/Config.php
@@ -85,6 +85,13 @@ class Config implements \Countable, \Iterator
      */
     protected $_extends = array();
 
+    /**
+     * Internal error messages
+     *
+     * @var null|array
+     */
+    protected $_errorMessages = array();
+
     /**
      * Zend_Config provides a property based interface to
      * an array. The data are read-only unless $allowModifications
@@ -320,7 +327,6 @@ public function areAllSectionsLoaded()
         return $this->_loadedSection === null;
     }
 
-
     /**
      * Merge another Zend_Config with this one. The items
      * in $merge will override the same named items in
@@ -453,4 +459,42 @@ protected function _arrayMergeRecursive($firstArray, $secondArray)
 
         return $firstArray;
     }
+
+    /**
+     * Set internal error handler
+     *
+     * @return void
+     */
+    protected function _setErrorHandler()
+    {
+        set_error_handler(array($this, '_handleError'));
+    }
+
+    /**
+     * Restore internal error handler
+     *
+     * @return array Handled error messages
+     */
+    protected function _restoreErrorHandler()
+    {
+        restore_error_handler();
+        $errorMessages = $this->_errorMessages;
+        $this->_errorMessages = array();
+        return $errorMessages;
+    }
+
+    /**
+     * Handle internal errors
+     *
+     * @param integer $errno
+     * @param string $errstr
+     * @param string $errfile
+     * @param integer $errline
+     * @return void
+     */
+    protected function _handleError($errno, $errstr, $errfile, $errline)
+    {
+        $this->_errorMessages[] = trim($errstr);
+    }
+
 }
diff --git a/library/Zend/Config/Ini.php b/library/Zend/Config/Ini.php
index 5ea267ec6bc..d2ff3890426 100644
--- a/library/Zend/Config/Ini.php
+++ b/library/Zend/Config/Ini.php
@@ -163,10 +163,16 @@ public function __construct($filename, $section = null, $options = false)
      */
     protected function _loadIniFile($filename)
     {
-        $loaded = @parse_ini_file($filename, true);
+        $this->_setErrorHandler();
+        $loaded = parse_ini_file($filename, true);
+        $errorMessages = $this->_restoreErrorHandler();
         if ($loaded === false) {
-            $err = error_get_last();
-            throw new Exception\RuntimeException($err['message']);
+            $e = null;
+            foreach ($errorMessages as $errMsg) {
+                $e = new Exception\RuntimeException($errMsg, 0, $e);
+            }
+            $e = new Exception\RuntimeException("Can't parse ini file '{$filename}'", 0, $e);
+            throw $e;
         }
 
         $iniArray = array();
diff --git a/library/Zend/Config/Json.php b/library/Zend/Config/Json.php
index d008b46ce1b..6bf48319d58 100755
--- a/library/Zend/Config/Json.php
+++ b/library/Zend/Config/Json.php
@@ -103,11 +103,19 @@ public function __construct($json, $section = null, $options = false)
         }
 
         if ($json[0] != '{') {
-            $json = @file_get_contents($json);
-            if ($json === false) {
-                $err = error_get_last();
-                throw new Exception\RuntimeException($err['message']);
+            // read json file
+            $this->_setErrorHandler();
+            $content = file_get_contents($json, true);
+            $errorMessages = $this->_restoreErrorHandler();
+            if ($content === false) {
+                $e = null;
+                foreach ($errorMessages as $errMsg) {
+                    $e = new Exception\RuntimeException($errMsg, 0, $e);
+                }
+                $e = new Exception\RuntimeException("Can't read file '{$json}'", 0, $e);
+                throw $e;
             }
+            $json = $content;
         }
 
         // Replace constants
diff --git a/library/Zend/Config/Xml.php b/library/Zend/Config/Xml.php
index 79613b7206c..26046cfdce0 100644
--- a/library/Zend/Config/Xml.php
+++ b/library/Zend/Config/Xml.php
@@ -104,11 +104,11 @@ public function __construct($xml, $section = null, $options = false)
             // create and throw exception stack
             $e = null;
             foreach ($xmlErrors as $xmlError) {
-                $e = new Exception\InvalidArgumentException(
-                    trim($xmlError->message)
-                    . ' @ line/column ' . $xmlError->line . '/' . $xmlError->column,
-                    0,
-                    $e
+                $msg  = trim($xmlError->message);
+                $line = $xmlError->line;
+                $col  = $xmlError->column;
+                $e = new Exception\RuntimeException(
+                    $msg . ' @ line/column ' . $line . '/' . $col, 0, $e
                 );
             }
             throw $e;
diff --git a/library/Zend/Config/Yaml.php b/library/Zend/Config/Yaml.php
index ce2c49a0603..8225308d4f0 100755
--- a/library/Zend/Config/Yaml.php
+++ b/library/Zend/Config/Yaml.php
@@ -158,12 +158,19 @@ public function __construct($yaml, $section = null, $options = false)
             }
         }
 
-        // read the yaml file
-        $yaml = @file_get_contents($yaml);
-        if ($yaml === false) {
-            $err = error_get_last();
-            throw new Exception\RuntimeException($err['message']);
+        // read yaml file
+        $this->_setErrorHandler();
+        $content = file_get_contents($yaml, true);
+        $errorMessages = $this->_restoreErrorHandler();
+        if ($content === false) {
+            $e = null;
+            foreach ($errorMessages as $errMsg) {
+                $e = new Exception\RuntimeException($errMsg, 0, $e);
+            }
+            $e = new Exception\RuntimeException("Can't read file '{$yaml}'", 0, $e);
+            throw $e;
         }
+        $yaml = $content;
 
         // Override static value for ignore_constants if provided in $options
         self::setIgnoreConstants($ignoreConstants);
diff --git a/tests/Zend/Config/IniTest.php b/tests/Zend/Config/IniTest.php
index 3c5e230d63a..c2cefb66d28 100644
--- a/tests/Zend/Config/IniTest.php
+++ b/tests/Zend/Config/IniTest.php
@@ -124,13 +124,19 @@ public function testInvalidKeys()
         }
     }
 
-    public function testZF426()
+    /**
+     * @group ZF-426
+     */
+    public function testErrorCreateSubKey()
     {
         $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'Cannot create sub-key for');
         $config = new Ini($this->_iniFileConfig, 'zf426');
     }
 
-    public function testZF413_MultiSections()
+    /**
+     * @group ZF-413
+     */
+    public function testMultiSections()
     {
         $config = new Ini($this->_iniFileAllSectionsConfig, array('staging','other_staging'));
 
@@ -139,14 +145,20 @@ public function testZF413_MultiSections()
 
     }
 
-    public function testZF413_AllSections()
+    /**
+     * @group ZF-413
+     */
+    public function testAllSections()
     {
         $config = new Ini($this->_iniFileAllSectionsConfig, null);
         $this->assertEquals('otherStaging', $config->other_staging->only_in);
         $this->assertEquals('staging', $config->staging->hostname);
     }
 
-    public function testZF414()
+    /**
+     * @group ZF-414
+     */
+    public function testGetSectionNameAndAreAllSectionsLoaded()
     {
         $config = new Ini($this->_iniFileAllSectionsConfig, null);
         $this->assertEquals(null, $config->getSectionName());
@@ -161,7 +173,10 @@ public function testZF414()
         $this->assertEquals(false, $config->areAllSectionsLoaded());
     }
 
-    public function testZF415()
+    /**
+     * @group ZF-415
+     */
+    public function testErrorCircularInheritance()
     {
         $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'circular inheritance');
         $config = new Ini($this->_iniFileCircularConfig, null);
@@ -173,6 +188,25 @@ public function testErrorNoFile()
         $config = new Ini('','');
     }
 
+    public function testErrorFileNotFound()
+    {
+        try {
+            $file = '/tmp/notFoundFile';
+            $config = new Ini($file);
+            $this->fail('Missing expected exception');
+        } catch (\Zend\Config\Exception\RuntimeException $e) {
+            // read exception stack
+            do {
+                $stack[] = $e;
+            } while ( ($e = $e->getPrevious()) );
+
+            // test two thrown exceptions
+            $this->assertEquals(2, count($stack));
+            $this->assertContains($file, $stack[0]->getMessage());
+            $this->assertContains('parse_ini_file', $stack[1]->getMessage());
+        }
+    }
+
     public function testErrorMultipleExensions()
     {
         $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'may not extend multiple sections');
@@ -192,7 +226,33 @@ public function testErrorNoSectionFoundWhenMultipleSectionsProvided()
         $config = new Ini($this->_iniFileConfig,array('all', 'notthere'));
     }
 
-    public function testZF2508NoSections()
+    /**
+     * @group ZF-3196
+     * @group ZF2-13
+     */
+    public function testErrorInvalidIniFile()
+    {
+        try {
+            $config = new Ini($this->_iniFileInvalid);
+            $this->fail('Missing expected exception');
+        } catch (\Zend\Config\Exception\RuntimeException $e) {
+            // read exception stack
+            do {
+                $stack[] = $e;
+            } while ( ($e = $e->getPrevious()) );
+
+            // test three thrown exceptions
+            $this->assertEquals(3, count($stack));
+            $this->assertContains($this->_iniFileInvalid, $stack[0]->getMessage());
+            $this->assertContains('syntax error', $stack[1]->getMessage());
+            $this->assertContains('deprecated', $stack[2]->getMessage());
+        }
+    }
+
+    /**
+     * @group ZF-2508
+     */
+    public function testNoSections()
     {
         $config = new Ini($this->_iniFileNoSectionsConfig);
 
@@ -202,7 +262,10 @@ public function testZF2508NoSections()
         $this->assertEquals('5', $config->one->three->five);
     }
 
-    public function testZF2843NoSectionNoTree()
+    /**
+     * @group ZF-2843
+     */
+    public function testNoSectionNoTree()
     {
         $filename = __DIR__ . '/_files/zf2843.ini';
         $config = new Ini($filename, null, array('nestSeparator' => '.'));
@@ -211,40 +274,28 @@ public function testZF2843NoSectionNoTree()
         $this->assertEquals('jkl', $config->ghi);
     }
 
-    public function testZF3196_InvalidIniFile()
-    {
-        try {
-            $config = new Ini($this->_iniFileInvalid);
-            $this->fail('An expected Zend\Config\Exception has not been raised');
-        } catch (\Zend\Config\Exception\RuntimeException $expected) {
-            $this->assertRegexp('/(Error parsing|syntax error, unexpected)/', $expected->getMessage());
-        }
-
-    }
-    
     /**
      * @group ZF-8159
      */
-    public function testZF8159()
+    public function testLoadMultipleSections()
     {
         $config = new Ini(
             __DIR__ . '/_files/zf8159.ini',
             array('first', 'second')
         );
-        
+
         $this->assertTrue(isset(
            $config->user->login->elements->password
         ));
-        
+
         $this->assertEquals(
             'password',
             $config->user->login->elements->password->type
         );
     }
 
-    /*
+    /**
      * @group ZF-5800
-     *
      */
     public function testArraysOfKeysCreatedUsingAttributesAndKeys()
     {
@@ -254,8 +305,8 @@ public function testArraysOfKeysCreatedUsingAttributesAndKeys()
         $this->assertEquals('1', $config->receiver->{0}->html);
         $this->assertNull($config->receiver->mail);
     }
-    
-    /*
+
+    /**
      * @group ZF-6508
      */
     public function testPreservationOfIntegerKeys()
@@ -263,8 +314,7 @@ public function testPreservationOfIntegerKeys()
         $filename = __DIR__ . '/_files/zf6508.ini';
         $config = new Ini($filename, 'all');
         $this->assertEquals(true, isset($config->{1002}));
-        
+
     }
-    
 
 }
diff --git a/tests/Zend/Config/JsonTest.php b/tests/Zend/Config/JsonTest.php
index f4a9418bba1..1c1c098653e 100644
--- a/tests/Zend/Config/JsonTest.php
+++ b/tests/Zend/Config/JsonTest.php
@@ -173,7 +173,6 @@ public function testRaisesErrorWhenSectionNotFound()
         }
     }
 
-
     public function testCanLoadConfigWithNoSections()
     {
         $config = new JsonConfig($this->_iniFileNoSectionsConfig);
diff --git a/tests/Zend/Config/XmlTest.php b/tests/Zend/Config/XmlTest.php
index e51349a63da..61a2293a478 100644
--- a/tests/Zend/Config/XmlTest.php
+++ b/tests/Zend/Config/XmlTest.php
@@ -102,7 +102,10 @@ public function testErrorNoExtendsSection()
         $config = new Xml($this->_xmlFileConfig, 'extendserror');
     }
 
-    public function testZF413_MultiSections()
+    /**
+     * @group ZF-413
+     */
+    public function testMultiSections()
     {
         $config = new Xml($this->_xmlFileAllSectionsConfig, array('staging','other_staging'));
 
@@ -110,14 +113,20 @@ public function testZF413_MultiSections()
         $this->assertEquals('staging', $config->hostname);
     }
 
-    public function testZF413_AllSections()
+    /**
+     * @group ZF-413
+     */
+    public function testAllSections()
     {
         $config = new Xml($this->_xmlFileAllSectionsConfig, null);
         $this->assertEquals('otherStaging', $config->other_staging->only_in);
         $this->assertEquals('staging', $config->staging->hostname);
     }
 
-    public function testZF414()
+    /**
+     * @group ZF-414
+     */
+    public function testGetSectionNameAndAreAllSectionsLoaded()
     {
         $config = new Xml($this->_xmlFileAllSectionsConfig, null);
         $this->assertEquals(null, $config->getSectionName());
@@ -132,7 +141,10 @@ public function testZF414()
         $this->assertEquals(false, $config->areAllSectionsLoaded());
     }
 
-    public function testZF415()
+    /**
+     * @group ZF-415
+     */
+    public function testErrorCircularInheritance()
     {
         $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'circular inheritance');
         $config = new Xml($this->_xmlFileCircularConfig, null);
@@ -144,7 +156,10 @@ public function testErrorNoFile()
         $config = new Xml('',null);
     }
 
-    public function testZF2162_TopLevelString()
+    /**
+     * @group ZF-2162
+     */
+    public function testTopLevelString()
     {
         $config = new Xml($this->_xmlFileTopLevelStringConfig, null);
         $this->assertEquals('one', $config->one);
@@ -159,7 +174,10 @@ public function testZF2162_TopLevelString()
 
     }
 
-    public function testZF2285_MultipleKeysOfTheSameName()
+    /**
+     * @group ZF-2285
+     */
+    public function testMultipleKeysOfTheSameName()
     {
         $config = new Xml($this->_xmlFileSameNameKeysConfig, null);
         $this->assertEquals('2a', $config->one->two->{0});
@@ -168,7 +186,10 @@ public function testZF2285_MultipleKeysOfTheSameName()
         $this->assertEquals('5', $config->three->four->{0}->five);
     }
 
-    public function testZF2437_ArraysWithMultipleChildren()
+    /**
+     * @group ZF-2437
+     */
+    public function testArraysWithMultipleChildren()
     {
         $config = new Xml($this->_xmlFileSameNameKeysConfig, null);
         $this->assertEquals('1', $config->six->seven->{0}->eight);
@@ -188,7 +209,7 @@ public function testInvalidXmlFile()
         try {
             $config = new Xml($this->_xmlFileInvalid);
             $this->fail('Missing expected exception');
-        } catch (\Zend\Config\Exception\InvalidArgumentException $e) {
+        } catch (\Zend\Config\Exception\RuntimeException $e) {
             // read exception stack
             do {
                 $stack[] = $e;
@@ -206,7 +227,7 @@ public function testInvalidXmlFile()
      */
     public function testMissingXmlFile()
     {
-        $this->setExpectedException('Zend\Config\Exception\InvalidArgumentException', 'failed to load');
+        $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'failed to load');
         $config = new Xml('I/dont/exist');
     }
 
@@ -284,9 +305,8 @@ public function testNamespacedExtends()
         $this->assertEquals('bar', $config->staging->foo);
     }
 
-    /*
-     * @group 3702
-     *
+    /**
+     * @group ZF-3702
      */
     public function testLoadAnXMLString()
     {
@@ -318,9 +338,8 @@ public function testLoadAnXMLString()
 
     }
 
-    /*
+    /**
      * @group ZF-5800
-     *
      */
     public function testArraysOfKeysCreatedUsingAttributesAndKeys()
     {
diff --git a/tests/Zend/Config/YamlTest.php b/tests/Zend/Config/YamlTest.php
index 4c1e5738594..941a94d34f4 100755
--- a/tests/Zend/Config/YamlTest.php
+++ b/tests/Zend/Config/YamlTest.php
@@ -112,7 +112,10 @@ public function testErrorNoExtendsSection()
         $config = new YamlConfig($this->_iniFileConfig, 'extendserror');
     }
 
-    public function testZF413_MultiSections()
+    /**
+     * @group ZF-413
+     */
+    public function testMultiSections()
     {
         $config = new YamlConfig($this->_iniFileAllSectionsConfig, array('staging','other_staging'));
 
@@ -121,14 +124,20 @@ public function testZF413_MultiSections()
 
     }
 
-    public function testZF413_AllSections()
+    /**
+     * @group ZF-413
+     */
+    public function testAllSections()
     {
         $config = new YamlConfig($this->_iniFileAllSectionsConfig, null);
         $this->assertEquals('otherStaging', $config->other_staging->only_in);
         $this->assertEquals('staging', $config->staging->hostname);
     }
 
-    public function testZF414()
+    /**
+     * @group ZF-414
+     */
+    public function testGetSectionNameAndAreAllSectionsLoaded()
     {
         $config = new YamlConfig($this->_iniFileAllSectionsConfig, null);
         $this->assertEquals(null, $config->getSectionName());
@@ -143,7 +152,10 @@ public function testZF414()
         $this->assertEquals(false, $config->areAllSectionsLoaded());
     }
 
-    public function testZF415()
+    /**
+     * @group ZF-415
+     */
+    public function testErrorCircularInheritance()
     {
         $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'circular inheritance');
         $config = new YamlConfig($this->_iniFileCircularConfig, null);
@@ -173,7 +185,10 @@ public function testErrorNoSectionFound()
 
     }
 
-    public function testZF3196_InvalidIniFile()
+    /**
+     * @group ZF-3196
+     */
+    public function testInvalidIniFile()
     {
         try {
             $config = new YamlConfig($this->_iniFileInvalid);
@@ -184,7 +199,10 @@ public function testZF3196_InvalidIniFile()
 
     }
 
-    public function testZF2285_MultipleKeysOfTheSameName()
+    /**
+     * @group ZF-2285
+     */
+    public function testMultipleKeysOfTheSameName()
     {
         $config = new YamlConfig($this->_iniFileSameNameKeysConfig, null);
         $this->assertEquals('2a', $config->one->two->{0});
@@ -193,7 +211,10 @@ public function testZF2285_MultipleKeysOfTheSameName()
         $this->assertEquals('5', $config->three->four->{0}->five);
     }
 
-    public function testZF2437_ArraysWithMultipleChildren()
+    /**
+     * @group ZF-2437
+     */
+    public function testArraysWithMultipleChildren()
     {
         $config = new YamlConfig($this->_iniFileSameNameKeysConfig, null);
         $this->assertEquals('1', $config->six->seven->{0}->eight);
@@ -223,10 +244,23 @@ public function testHonorsOptionsProvidedToConstructor()
         $this->assertEquals(array($this, 'yamlDecoder'), $config->getYamlDecoder());
     }
 
-    public function testConstructorRaisesExceptionWhenUnableToLoadFile()
+    public function testFileNotFound()
     {
-        $this->setExpectedException('Zend\Config\Exception\RuntimeException', 'file_get_contents');
-        $config = new YamlConfig('__foo__');
+        try {
+            $file = '__foo__';
+            $config = new YamlConfig($file);
+            $this->fail('Missing expected exception');
+        } catch (Exception\RuntimeException $e) {
+            // read exception stack
+            do {
+                $stack[] = $e;
+            } while ( ($e = $e->getPrevious()) );
+
+            // test two thrown exceptions
+            $this->assertEquals(2, count($stack));
+            $this->assertContains($file, $stack[0]->getMessage());
+            $this->assertContains('file_get_contents', $stack[1]->getMessage());
+        }
     }
 
     public function testBadIndentationRaisesException()
diff --git a/tests/Zend/Config/_files/invalid.ini b/tests/Zend/Config/_files/invalid.ini
index 5e3f8f94840..bc90cb1f993 100644
--- a/tests/Zend/Config/_files/invalid.ini
+++ b/tests/Zend/Config/_files/invalid.ini
@@ -1,2 +1,3 @@
 [default]
+#deprecated comment
 foo = /("bar)