X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fpostgresqlstorage.cpp;h=bb58da17922e082c344bb88810d6ae39eab2d3b1;hp=3965704608ada44b5c5ef08847d7dfbdffb98b81;hb=6d2798ada0b9e770f821e039431cc9dc3b5f85cf;hpb=4c80eeb2d07b5ca75fd399b51c939961fdff1670 diff --git a/src/core/postgresqlstorage.cpp b/src/core/postgresqlstorage.cpp index 39657046..bb58da17 100644 --- a/src/core/postgresqlstorage.cpp +++ b/src/core/postgresqlstorage.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 by the Quassel Project * + * Copyright (C) 2005-2014 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -96,11 +96,47 @@ QVariantMap PostgreSqlStorage::setupDefaults() const } -void PostgreSqlStorage::initDbSession(QSqlDatabase &db) +bool PostgreSqlStorage::initDbSession(QSqlDatabase &db) { - // this blows... but unfortunately Qt's PG driver forces us to this... - db.exec("set standard_conforming_strings = off"); - db.exec("set escape_string_warning = off"); + // check whether the Qt driver performs string escaping or not. + // i.e. test if it doubles slashes. + QSqlField testField; + testField.setType(QVariant::String); + testField.setValue("\\"); + QString formattedString = db.driver()->formatValue(testField); + switch(formattedString.count('\\')) { + case 2: + // yes it does... and we cannot do anything to change the behavior of Qt. + // If this is a legacy DB (Postgres < 8.2), then everything is already ok, + // as this is the expected behavior. + // If it is a newer version, switch to legacy mode. + + quWarning() << "Switching Postgres to legacy mode. (set standard conforming strings to off)"; + // If the following calls fail, it is a legacy DB anyways, so it doesn't matter + // and no need to check the outcome. + db.exec("set standard_conforming_strings = off"); + db.exec("set escape_string_warning = off"); + break; + case 1: + // ok, so Qt does not escape... + // That means we have to ensure that postgres uses standard conforming strings... + { + QSqlQuery query = db.exec("set standard_conforming_strings = on"); + if (query.lastError().isValid()) { + // We cannot enable standard conforming strings... + // since Quassel does no escaping by itself, this would yield a major vulnerability. + quError() << "Failed to enable standard_conforming_strings for the Postgres db!"; + return false; + } + } + break; + default: + // The slash got replaced with 0 or more than 2 slashes! o_O + quError() << "Your version of Qt does something _VERY_ strange to slashes in QSqlQueries! You should consult your trusted doctor!"; + return false; + break; + } + return true; } @@ -770,9 +806,9 @@ QList PostgreSqlStorage::networks(UserId user) net.networkId = networksQuery.value(0).toInt(); net.networkName = networksQuery.value(1).toString(); net.identity = networksQuery.value(2).toInt(); - net.codecForServer = networksQuery.value(3).toString().toAscii(); - net.codecForEncoding = networksQuery.value(4).toString().toAscii(); - net.codecForDecoding = networksQuery.value(5).toString().toAscii(); + net.codecForServer = networksQuery.value(3).toString().toLatin1(); + net.codecForEncoding = networksQuery.value(4).toString().toLatin1(); + net.codecForDecoding = networksQuery.value(5).toString().toLatin1(); net.useRandomServer = networksQuery.value(6).toBool(); net.perform = networksQuery.value(7).toString().split("\n"); net.useAutoIdentify = networksQuery.value(8).toBool(); @@ -987,7 +1023,7 @@ BufferInfo PostgreSqlStorage::bufferInfo(UserId user, const NetworkId &networkId qCritical() << " bound Values:"; QList list = query.boundValues().values(); for (int i = 0; i < list.size(); ++i) - qCritical() << i << ":" << list.at(i).toString().toAscii().data(); + qCritical() << i << ":" << list.at(i).toString().toLatin1().data(); Q_ASSERT(false); } db.commit(); @@ -1480,7 +1516,7 @@ QList PostgreSqlStorage::requestMsgs(UserId user, BufferId bufferId, Ms if (limit != -1) params << limit; else - params << "ALL"; + params << QVariant(QVariant::Int); QSqlQuery query = executePreparedQuery(queryName, params, db); @@ -1567,7 +1603,7 @@ QList PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId // qDebug() << " bound Values:"; // QList list = query.boundValues().values(); // for (int i = 0; i < list.size(); ++i) -// qCritical() << i << ": " << list.at(i).toString().toAscii().data(); +// qCritical() << i << ": " << list.at(i).toString().toLatin1().data(); // query.exec();