]> git.sur5r.net Git - openldap/commitdiff
Improved error handling
authorRalf Haferkamp <ralf@openldap.org>
Thu, 20 Mar 2008 16:10:37 +0000 (16:10 +0000)
committerRalf Haferkamp <ralf@openldap.org>
Thu, 20 Mar 2008 16:10:37 +0000 (16:10 +0000)
contrib/ldapc++/src/LdifReader.cpp
contrib/ldapc++/src/LdifReader.h

index 171378c2b6bba9d41e56b71a3a4dbb100e9ccee9..dce0a632317fa58a85980baf756ca37e5df6cfe9 100644 (file)
 
 #include <string>
 #include <sstream>
+#include <stdexcept>
 
 #include <sasl/saslutil.h> // For base64 routines
 
 typedef std::pair<std::string, std::string> stringpair;
-LdifReader::LdifReader( std::istream &input ) : m_ldifstream(input)
+
+LdifReader::LdifReader( std::istream &input ) 
+        : m_ldifstream(input), m_lineNumber(0)
 {
     DEBUG(LDAP_DEBUG_TRACE, "<> LdifReader::LdifReader()" << std::endl);
     this->m_version = 0;
     // read the first record to find out version and type of the LDIF
-    if ( this->readNextRecord(true) )
-    {
-        this->m_currentIsFirst = true;
-    }
+    this->readNextRecord(true);
+    this->m_currentIsFirst = true;
 }
 
 int LdifReader::readNextRecord( bool first )
@@ -60,12 +61,9 @@ int LdifReader::readNextRecord( bool first )
             // End of Entry
             break;
         }
-        int rc = this->splitLine(line, type, value);
-        if ( rc )
-        {
-            DEBUG(LDAP_DEBUG_TRACE, " Error while splitting ldif line" 
-                    << std::endl);
-        }
+
+        this->splitLine(line, type, value);
+
         if ( numLine == 0 )
         {
             if ( type == "version" )
@@ -74,7 +72,10 @@ int LdifReader::readNextRecord( bool first )
                 valuestream >> this->m_version;
                 if ( this->m_version != 1 ) // there is no other Version than LDIFv1 
                 {
-                    //throw LdifException();
+                    std::ostringstream err;
+                    err << "Line " << this->m_lineNumber 
+                        << ": Unsuported LDIF Version";
+                    throw( std::runtime_error(err.str()) );
                 }
                 continue;
             }
@@ -87,16 +88,27 @@ int LdifReader::readNextRecord( bool first )
                 DEBUG(LDAP_DEBUG_TRACE, " Include directive: " << value << std::endl);
                 if ( this->m_version == 1 )
                 {
-                    // "include" is not an LDIFv1 feature
+                    std::ostringstream err;
+                    err << "Line " << this->m_lineNumber 
+                        << ": \"include\" not allowed in LDIF version 1.";
+                    throw( std::runtime_error(err.str()) );
+                }
+                else
+                {
+                    std::ostringstream err;
+                    err << "Line " << this->m_lineNumber 
+                        << ": \"include\" not yet suppported.";
+                    throw( std::runtime_error(err.str()) );
                 }
-                //this->readIncludeLine(value);
-                return 0;
             }
             else
             {
                 DEBUG(LDAP_DEBUG_TRACE, " Record doesn't start with a DN" 
                             << std::endl);
-                return 0;
+                std::ostringstream err;
+                err << "Line " << this->m_lineNumber 
+                    << ": LDIF record does not start with a DN.";
+                throw( std::runtime_error(err.str()) );
             }
         }
         if ( numLine == 1 ) // might contain "changtype" to indicate a change request
@@ -110,6 +122,10 @@ int LdifReader::readNextRecord( bool first )
                 else if (! this->m_ldifTypeRequest )
                 {
                     // Change Request in Entry record LDIF, should we accept it?
+                    std::ostringstream err;
+                    err << "Line " << this->m_lineNumber 
+                        << ": Change Request in an entry-only LDIF.";
+                    throw( std::runtime_error(err.str()) );
                 }
                 if ( value == "modify" )
                 {
@@ -131,7 +147,10 @@ int LdifReader::readNextRecord( bool first )
                 {
                     DEBUG(LDAP_DEBUG_TRACE, " Unknown change request <" 
                             << value << ">" << std::endl);
-                    return 0;
+                    std::ostringstream err;
+                    err << "Line " << this->m_lineNumber 
+                        << ": Unknown changetype: \"" << value << "\".";
+                    throw( std::runtime_error(err.str()) );
                 }
             }
             else
@@ -179,6 +198,11 @@ LDAPEntry LdifReader::getEntryRecord()
             if ( curAl->getAttributeByName( i->first ) )
             {
                 // Attribute exists already -> Syntax Error
+                std::ostringstream err;
+                err << "Line " << this->m_lineNumber 
+                    << ": Attribute \"" << i->first 
+                    << "\" specified multiple times.";
+                throw( std::runtime_error(err.str()) );
             }
             else
             {
@@ -196,11 +220,11 @@ int LdifReader::getLdifLine(std::string &ldifline)
 {
     DEBUG(LDAP_DEBUG_TRACE, "-> LdifReader::getLdifLine()" << std::endl);
 
+    this->m_lineNumber++;
     if ( ! getline(m_ldifstream, ldifline) )
     {
         return -1;
     }
-
     while ( m_ldifstream &&
         (m_ldifstream.peek() == ' ' || m_ldifstream.peek() == '\t'))
     {
@@ -208,36 +232,43 @@ int LdifReader::getLdifLine(std::string &ldifline)
         m_ldifstream.ignore();
         getline(m_ldifstream, cat);
         ldifline += cat;
+        this->m_lineNumber++;
     }
 
     DEBUG(LDAP_DEBUG_TRACE, "<- LdifReader::getLdifLine()" << std::endl);
     return 0;
 }
 
-int LdifReader::splitLine(const std::string& line, 
+void LdifReader::splitLine(
+            const std::string& line, 
             std::string &type,
-            std::string &value)
+            std::string &value) const
 {
     std::string::size_type pos = line.find(':');
     if ( pos == std::string::npos )
     {
-        DEBUG(LDAP_DEBUG_ANY, "Invalid LDIF line. Not `:` separator" 
+        DEBUG(LDAP_DEBUG_ANY, "Invalid LDIF line. No `:` separator" 
                 << std::endl );
-        return -1;
+        std::ostringstream err;
+        err << "Line " << this->m_lineNumber << ": Invalid LDIF line. No `:` separator";
+        throw( std::runtime_error( err.str() ));
     }
+
     type = line.substr(0, pos);
     if ( pos == line.size() )
     {
         // empty value
         value = "";
-        return 0;
+        return;
     }
+
     pos++;
     char delim = line[pos];
     if ( delim == ':' || delim == '<' )
     {
         pos++;
     }
+
     for( ; pos < line.size() && isspace(line[pos]); pos++ )
     { /* empty */ }
 
@@ -258,21 +289,29 @@ int LdifReader::splitLine(const std::string& line,
         {
             value = "";
             DEBUG( LDAP_DEBUG_TRACE, " invalid base64 content" << std::endl );
-            return -1;
+            std::ostringstream err;
+            err << "Line " << this->m_lineNumber << ": Can't decode Base64 data";
+            throw( std::runtime_error( err.str() ));
         }
         else if ( rc == SASL_BUFOVER )
         {
             value = "";
             DEBUG( LDAP_DEBUG_TRACE, " not enough space in output buffer" 
                     << std::endl );
-            return -1;
+            std::ostringstream err;
+            err << "Line " << this->m_lineNumber 
+                << ": Can't decode Base64 data. Buffer too small";
+            throw( std::runtime_error( err.str() ));
         }
     }
     else if ( delim == '<' )
     {
         // URL value
         DEBUG(LDAP_DEBUG_TRACE, "  url value" << std::endl );
-        return -1;
+        std::ostringstream err;
+        err << "Line " << this->m_lineNumber 
+            << ": URLs are currently not supported";
+        throw( std::runtime_error( err.str() ));
     }
     else 
     {
@@ -281,7 +320,7 @@ int LdifReader::splitLine(const std::string& line,
     }
     DEBUG(LDAP_DEBUG_TRACE, "  Type: <" << type << ">" << std::endl );
     DEBUG(LDAP_DEBUG_TRACE, "  Value: <" << value << ">" << std::endl );
-    return 0;
+    return;
 }
 
 std::string LdifReader::readIncludeLine( const std::string& line ) const
index 8d0e751f032854bcd8945dd0e959db3db0f88ba9..16c0e455be57edf201d76e20285dea49aa9ca9aa 100644 (file)
@@ -38,9 +38,9 @@ class LdifReader
     private:
         int getLdifLine(std::string &line);
 
-        int splitLine(const std::string& line, 
+        void splitLine(const std::string& line, 
                     std::string &type,
-                    std::string &value );
+                    std::string &value ) const;
 
         std::string readIncludeLine( const std::string &line) const;
 
@@ -48,6 +48,7 @@ class LdifReader
         LdifRecord m_currentRecord;
         int m_version;
         int m_curRecType;
+        int m_lineNumber;
         bool m_ldifTypeRequest;
         bool m_currentIsFirst;
 };