diff --git a/kldap/ldif.cpp b/kldap/ldif.cpp index cdb817649..bcd7edb17 100644 --- a/kldap/ldif.cpp +++ b/kldap/ldif.cpp @@ -1,451 +1,451 @@ /* This file is part of libkldap. Copyright (c) 2004-2006 Szombathelyi György This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ldif.h" #include using namespace KLDAP; class Ldif::LdifPrivate { public: int mModType; bool mDelOldRdn, mUrl; LdapDN mDn; QString mAttr, mNewRdn, mNewSuperior, mOid; QByteArray mLdif, mValue; EntryType mEntryType; bool mIsNewLine, mIsComment, mCritical; ParseValue mLastParseValue; uint mPos, mLineNumber; QByteArray mLine; }; Ldif::Ldif() : d( new LdifPrivate ) { startParsing(); } Ldif::Ldif( const Ldif &that ) : d( new LdifPrivate ) { *d = *that.d; startParsing(); } Ldif &Ldif::operator=( const Ldif &that ) { if ( this == &that ) { return *this; } *d = *that.d; return *this; } Ldif::~Ldif() { delete d; } QByteArray Ldif::assembleLine( const QString &fieldname, const QByteArray &value, uint linelen, bool url ) { bool safe = false; bool isDn; QByteArray result; if ( url ) { result = fieldname.toUtf8() + ":< " + value; } else { isDn = fieldname.toLower() == "dn"; //SAFE-INIT-CHAR if ( value.size() > 0 && value[0] > 0 && value[0] != '\n' && value[0] != '\r' && value[0] != ':' && value[0] != '<' ) safe = true; //SAFE-CHAR if ( safe ) { for ( int i=1; i < value.size(); i++ ) { //allow utf-8 in Distinguished Names if ( ( isDn && value[i] == 0 ) || ( !isDn && value[i] <= 0 ) || value[i] == '\r' || value[i] == '\n' ) { safe = false; break; } } } if ( value.size() == 0 ) { safe = true; } if ( safe ) { result = fieldname.toUtf8() + ": " + value; } else { result = fieldname.toUtf8() + ":: " + value.toBase64(); } if ( linelen > 0 ) { int i = (uint)( fieldname.length() + 2 ) > linelen ? fieldname.length() + 2 : linelen; while ( i < result.length() ) { result.insert( i, "\n " ); i += linelen+2; } } } return result; } QByteArray Ldif::assembleLine( const QString &fieldname, const QString &value, uint linelen, bool url ) { return assembleLine( fieldname, value.toUtf8(), linelen, url ); } bool Ldif::splitLine( const QByteArray &line, QString &fieldname, QByteArray &value ) { int position; QByteArray tmp; int linelen; // kDebug() << "line:" << QString::fromUtf8(line); position = line.indexOf( ":" ); if ( position == -1 ) { // strange: we did not find a fieldname fieldname = ""; value = line.trimmed(); // kDebug() << "value :" << value[0]; return false; } linelen = line.size(); fieldname = QString::fromUtf8( line.left( position ).trimmed() ); if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) { // String is BASE64 encoded -> decode it now. if ( linelen <= ( position + 3 ) ) { value.resize( 0 ); return false; } value = QByteArray::fromBase64( line.mid( position + 3 ) ); return false; } if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) { // String is an URL. if ( linelen <= ( position + 3 ) ) { value.resize( 0 ); return false; } value = QByteArray::fromBase64( line.mid( position + 3 ) ); return true; } if ( linelen <= ( position + 2 ) ) { value.resize( 0 ); return false; } value = line.mid( position + 2 ); return false; } bool Ldif::splitControl( const QByteArray &line, QString &oid, bool &critical, QByteArray &value ) { QString tmp; critical = false; bool url = splitLine( line, tmp, value ); kDebug() << "value:" << QString::fromUtf8( value, value.size() ); if ( tmp.isEmpty() ) { tmp = QString::fromUtf8( value, value.size() ); value.resize( 0 ); } - if ( tmp.endsWith( "true" ) ) { + if ( tmp.endsWith( QLatin1String( "true" ) ) ) { critical = true; tmp.truncate( tmp.length() - 5 ); - } else if ( tmp.endsWith( "false" ) ) { + } else if ( tmp.endsWith( QLatin1String( "false" ) ) ) { critical = false; tmp.truncate( tmp.length() - 6 ); } oid = tmp; return url; } Ldif::ParseValue Ldif::processLine() { if ( d->mIsComment ) { return None; } ParseValue retval = None; if ( d->mLastParseValue == EndEntry ) { d->mEntryType = Entry_None; } d->mUrl = splitLine( d->mLine, d->mAttr, d->mValue ); QString attrLower = d->mAttr.toLower(); switch ( d->mEntryType ) { case Entry_None: if ( attrLower == "version" ) { if ( !d->mDn.isEmpty() ) { retval = Err; } } else if ( attrLower == "dn" ) { kDebug() << "ldapentry dn:" << QString::fromUtf8( d->mValue, d->mValue.size() ); d->mDn = LdapDN( QString::fromUtf8( d->mValue, d->mValue.size() ) ); d->mModType = Mod_None; retval = NewEntry; } else if ( attrLower == "changetype" ) { if ( d->mDn.isEmpty() ) { retval = Err; } else { QString tmpval = QString::fromUtf8( d->mValue, d->mValue.size() ); kDebug() << "changetype:" << tmpval; if ( tmpval == "add" ) { d->mEntryType = Entry_Add; } else if ( tmpval == "delete" ) { d->mEntryType = Entry_Del; } else if ( tmpval == "modrdn" || tmpval == "moddn" ) { d->mNewRdn = ""; d->mNewSuperior = ""; d->mDelOldRdn = true; d->mEntryType = Entry_Modrdn; } else if ( tmpval == "modify" ) { d->mEntryType = Entry_Mod; } else { retval = Err; } } } else if ( attrLower == "control" ) { d->mUrl = splitControl( d->mValue, d->mOid, d->mCritical, d->mValue ); retval = Control; } else if ( !d->mAttr.isEmpty() && d->mValue.size() > 0 ) { d->mEntryType = Entry_Add; retval = Item; } break; case Entry_Add: if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) { retval = EndEntry; } else { retval = Item; } break; case Entry_Del: if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) { retval = EndEntry; } else { retval = Err; } break; case Entry_Mod: if ( d->mModType == Mod_None ) { kDebug() << "new modtype" << d->mAttr; if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) { retval = EndEntry; } else if ( attrLower == "add" ) { d->mModType = Mod_Add; } else if ( attrLower == "replace" ) { d->mModType = Mod_Replace; d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() ); d->mValue = QByteArray(); retval = Item; } else if ( attrLower == "delete" ) { d->mModType = Mod_Del; d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() ); d->mValue = QByteArray(); retval = Item; } else { retval = Err; } } else { if ( d->mAttr.isEmpty() ) { if ( QString::fromUtf8( d->mValue, d->mValue.size() ) == "-" ) { d->mModType = Mod_None; } else if ( d->mValue.size() == 0 ) { retval = EndEntry; } else { retval = Err; } } else { retval = Item; } } break; case Entry_Modrdn: if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) { retval = EndEntry; } else if ( attrLower == "newrdn" ) { d->mNewRdn = QString::fromUtf8( d->mValue, d->mValue.size() ); } else if ( attrLower == "newsuperior" ) { d->mNewSuperior = QString::fromUtf8( d->mValue, d->mValue.size() ); } else if ( attrLower == "deleteoldrdn" ) { if ( d->mValue.size() > 0 && d->mValue[0] == '0' ) { d->mDelOldRdn = false; } else if ( d->mValue.size() > 0 && d->mValue[0] == '1' ) { d->mDelOldRdn = true; } else { retval = Err; } } else { retval = Err; } break; } return retval; } Ldif::ParseValue Ldif::nextItem() { ParseValue retval = None; char c=0; while ( retval == None ) { if ( d->mPos < (uint)d->mLdif.size() ) { c = d->mLdif[d->mPos]; d->mPos++; if ( d->mIsNewLine && c == '\r' ) { continue; //handle \n\r line end } if ( d->mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding d->mIsNewLine = false; continue; } if ( d->mIsNewLine ) { d->mIsNewLine = false; retval = processLine(); d->mLastParseValue = retval; d->mLine.resize( 0 ); d->mIsComment = ( c == '#' ); } if ( c == '\n' || c == '\r' ) { d->mLineNumber++; d->mIsNewLine = true; continue; } } else { retval = MoreData; break; } if ( !d->mIsComment ) { d->mLine += c; } } return retval; } void Ldif::endLdif() { QByteArray tmp( 3, '\n' ); d->mLdif = tmp; d->mPos = 0; } void Ldif::startParsing() { d->mPos = d->mLineNumber = 0; d->mDelOldRdn = false; d->mEntryType = Entry_None; d->mModType = Mod_None; d->mDn = LdapDN(); d->mNewRdn.clear(); d->mNewSuperior.clear(); d->mLine = QByteArray(); d->mIsNewLine = false; d->mIsComment = false; d->mLastParseValue = None; } void Ldif::setLdif( const QByteArray &ldif ) { d->mLdif = ldif; d->mPos = 0; } Ldif::EntryType Ldif::entryType() const { return d->mEntryType; } int Ldif::modType() const { return d->mModType; } LdapDN Ldif::dn() const { return d->mDn; } QString Ldif::newRdn() const { return d->mNewRdn; } QString Ldif::newSuperior() const { return d->mNewSuperior; } bool Ldif::delOldRdn() const { return d->mDelOldRdn; } QString Ldif::attr() const { return d->mAttr; } QByteArray Ldif::value() const { return d->mValue; } bool Ldif::isUrl() const { return d->mUrl; } bool Ldif::isCritical() const { return d->mCritical; } QString Ldif::oid() const { return d->mOid; } uint Ldif::lineNumber() const { return d->mLineNumber; }