~ubuntu-branches/ubuntu/breezy/koffice/breezy-security

« back to all changes in this revision

Viewing changes to kexi/kexidb/drivers/pqxx/pqxxcursor.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-10-11 14:49:50 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051011144950-lwpngbifzp8nk0ds
Tags: 1:1.4.1-0ubuntu7
* SECURITY UPDATE: fix heap based buffer overflow in the RTF importer of KWord
* Opening specially crafted RTF files in KWord can cause
  execution of abitrary code.
* Add kubuntu_01_rtfimport_heap_overflow.diff
* References:
  CAN-2005-2971
  CESA-2005-005
  http://www.koffice.org/security/advisory-20051011-1.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Implementation: pqxxsqlcursor
 
3
//
 
4
// Description: 
 
5
//
 
6
//
 
7
// Author: Adam Pigg <piggz@defiant.piggz.co.uk>, (C) 2003
 
8
//
 
9
// Copyright: See COPYING file that comes with this distribution
 
10
//
 
11
//
 
12
#include "pqxxcursor.h"
 
13
#include "pqxxconnection.h"
 
14
 
 
15
#include <kexidb/error.h>
 
16
#include <kexidb/global.h>
 
17
 
 
18
#include <klocale.h>
 
19
#include <kdebug.h>
 
20
 
 
21
using namespace KexiDB;
 
22
 
 
23
 
 
24
unsigned int pqxxSqlCursor_trans_num=0; //!< debug helper
 
25
 
 
26
//==================================================================================
 
27
//Constructor based on query statement
 
28
pqxxSqlCursor::pqxxSqlCursor(KexiDB::Connection* conn, const QString& statement, uint options):
 
29
        Cursor(conn,statement, options)
 
30
{
 
31
KexiDBDrvDbg << "PQXXSQLCURSOR: constructor for query statement" << endl;
 
32
my_conn = static_cast<pqxxSqlConnection*>(conn)->m_pqxxsql;
 
33
m_options = Buffered;
 
34
m_res = 0;
 
35
m_tran = 0;
 
36
}
 
37
 
 
38
//==================================================================================
 
39
//Constructor base on query object
 
40
pqxxSqlCursor::pqxxSqlCursor(Connection* conn, QuerySchema& query, uint options )
 
41
        : Cursor( conn, query, options )
 
42
{
 
43
KexiDBDrvDbg << "PQXXSQLCURSOR: constructor for query schema" << endl;
 
44
my_conn = static_cast<pqxxSqlConnection*>(conn)->m_pqxxsql;
 
45
m_options = Buffered;
 
46
m_res = 0;
 
47
m_tran = 0;
 
48
}
 
49
 
 
50
//==================================================================================
 
51
//Destructor
 
52
pqxxSqlCursor::~pqxxSqlCursor()
 
53
{
 
54
        close();
 
55
}
 
56
 
 
57
//==================================================================================
 
58
//Create a cursor result set 
 
59
bool pqxxSqlCursor::drv_open(const QString& statement)
 
60
{
 
61
        KexiDBDrvDbg << "pqxxSqlCursor::drv_open:" << statement << endl;
 
62
 
 
63
        if (!my_conn->is_open())
 
64
        {
 
65
                //should never happen, but who knows
 
66
                setError(ERR_NO_CONNECTION,i18n("No connection for cursor open operation specified"));
 
67
                return false;
 
68
        }
 
69
                
 
70
        QCString cur_name;
 
71
        //Set up a transaction
 
72
        try
 
73
        {
 
74
                //m_tran = new pqxx::work(*my_conn, "cursor_open");
 
75
                cur_name.sprintf("cursor_transaction%d", pqxxSqlCursor_trans_num++);
 
76
                
 
77
                m_tran = new pqxx::nontransaction(*my_conn, (const char*)cur_name);
 
78
 
 
79
                m_res = new pqxx::result(m_tran->exec(statement.utf8()));
 
80
                m_tran->commit();
 
81
                KexiDBDrvDbg << "pqxxSqlCursor::drv_open: trans. commited: " << cur_name <<endl;
 
82
 
 
83
                //We should now be placed before the first row, if any
 
84
                m_fieldCount = m_res->columns();
 
85
//js            m_opened=true;
 
86
                m_afterLast=false;
 
87
                m_records_in_buf = m_res->size();
 
88
                m_buffering_completed = true;
 
89
                return true;
 
90
        }
 
91
        catch (const std::exception &e)
 
92
        {
 
93
                        setError(ERR_DB_SPECIFIC,e.what());
 
94
                        KexiDBDrvDbg << "pqxxSqlCursor::drv_open:exception - " << e.what() << endl;
 
95
        }
 
96
        catch(...)
 
97
        {
 
98
                setError();
 
99
        }
 
100
        delete m_tran;
 
101
        m_tran = 0;
 
102
        KexiDBDrvDbg << "pqxxSqlCursor::drv_open: trans. rolled back! - " << cur_name <<endl;
 
103
        return false;
 
104
}
 
105
 
 
106
//==================================================================================
 
107
//Delete objects
 
108
bool pqxxSqlCursor::drv_close()
 
109
{
 
110
//js    m_opened=false;
 
111
 
 
112
        delete m_res;
 
113
        m_res = 0;
 
114
                
 
115
        delete m_tran;
 
116
        m_tran = 0;
 
117
 
 
118
        return true;
 
119
}
 
120
 
 
121
//==================================================================================
 
122
//Gets the next record...doesnt need to do much, just return fetchend if at end of result set
 
123
void pqxxSqlCursor::drv_getNextRecord()
 
124
{
 
125
KexiDBDrvDbg << "pqxxSqlCursor::drv_getNextRecord, size is " <<m_res->size() << " Current Position is " << (long)at() << endl;
 
126
if(at() < m_res->size() && at() >=0)
 
127
{       
 
128
        m_result = FetchOK;
 
129
}
 
130
else if (at() >= m_res->size())
 
131
{
 
132
        m_result = FetchEnd;
 
133
}
 
134
else
 
135
{
 
136
        m_result = FetchError;
 
137
}
 
138
}
 
139
 
 
140
//==================================================================================
 
141
//Check the current position is within boundaries
 
142
void pqxxSqlCursor::drv_getPrevRecord()
 
143
{
 
144
KexiDBDrvDbg << "pqxxSqlCursor::drv_getPrevRecord" << endl;
 
145
 
 
146
if(at() < m_res->size() && at() >=0)
 
147
{       
 
148
        m_result = FetchOK;
 
149
}
 
150
else if (at() >= m_res->size())
 
151
{
 
152
        m_result = FetchEnd;
 
153
}
 
154
else
 
155
{
 
156
        m_result = FetchError;
 
157
}
 
158
}
 
159
 
 
160
//==================================================================================
 
161
//Return the value for a given column for the current record
 
162
QVariant pqxxSqlCursor::value(uint pos)
 
163
{
 
164
        if (pos < m_fieldCount)
 
165
                return pValue(pos);
 
166
        else
 
167
                return QVariant();
 
168
}
 
169
 
 
170
//==================================================================================
 
171
//Return the value for a given column for the current record - Private const version
 
172
QVariant pqxxSqlCursor::pValue(uint pos) const
 
173
{
 
174
        if (!m_res->size() > 0)
 
175
        {
 
176
                KexiDBDrvDbg << "pqxxSqlCursor::value - ERROR: result size not greater than 0" << endl;
 
177
                return QVariant();
 
178
        }
 
179
 
 
180
        if (pos>=m_fieldCount)
 
181
        {
 
182
                KexiDBDrvDbg << "pqxxSqlCursor::value - ERROR: requested position is greater than the number of fields" << endl;
 
183
                return QVariant();
 
184
        }
 
185
 
 
186
        KexiDB::Field *f = m_fieldsExpanded ? m_fieldsExpanded->at(pos)->field : 0;
 
187
        //from most to least frequently used types:
 
188
        if (!f || f->isTextType())
 
189
        {
 
190
                return QVariant((*m_res)[at()][pos].c_str());
 
191
        }
 
192
        else if (f->isIntegerType())
 
193
        {
 
194
                return QVariant((*m_res)[at()][pos].as(int()));
 
195
        }
 
196
        else if (f->isFPNumericType())
 
197
        {
 
198
                return QVariant((*m_res)[at()][pos].as(double()));
 
199
        }
 
200
        
 
201
        return QVariant((*m_res)[at()][pos].c_str());
 
202
}
 
203
 
 
204
//==================================================================================
 
205
//Return the current record as a char**
 
206
//who'd have thought we'd be using char** in this day and age :o)
 
207
const char** pqxxSqlCursor::rowData() const
 
208
{
 
209
        KexiDBDrvDbg << "pqxxSqlCursor::recordData" << endl;
 
210
        
 
211
        const char** row;
 
212
        
 
213
        row = (const char**)malloc(m_res->columns()+1);
 
214
        row[m_res->columns()] = NULL;
 
215
        if (at() >= 0 && at() < m_res->size())
 
216
        {
 
217
                for(int i = 0; i < m_res->columns(); i++)
 
218
                {
 
219
                        row[i] = (char*)malloc(strlen((*m_res)[at()][i].c_str())+1);
 
220
                        strcpy((char*)(*m_res)[at()][i].c_str(), row[i]);
 
221
                        KexiDBDrvDbg << row[i] << endl;
 
222
                }
 
223
        }
 
224
        else
 
225
        {
 
226
                KexiDBDrvDbg << "pqxxSqlCursor::recordData: m_at is invalid" << endl;
 
227
        }
 
228
        return row;
 
229
}
 
230
 
 
231
//==================================================================================
 
232
//Store the current record in [data]
 
233
void pqxxSqlCursor::storeCurrentRow(RowData &data) const
 
234
{
 
235
KexiDBDrvDbg << "pqxxSqlCursor::storeCurrentRow: POSITION IS " << (long)m_at<< endl;
 
236
 
 
237
if (!m_res->size()>0)
 
238
        return;
 
239
 
 
240
data.reserve(m_fieldCount);
 
241
 
 
242
for( uint i=0; i<m_fieldCount; i++)
 
243
{
 
244
        data[i] = pValue(i);
 
245
}
 
246
}
 
247
 
 
248
//==================================================================================
 
249
//
 
250
void pqxxSqlCursor::drv_clearServerResult()
 
251
{
 
252
#warning TODO: stuff with server results
 
253
}
 
254
 
 
255
//==================================================================================
 
256
//Add the current record to the internal buffer
 
257
//Implementation required but no need in this driver
 
258
//Result set is a buffer so dont need another
 
259
void pqxxSqlCursor::drv_appendCurrentRecordToBuffer()
 
260
{
 
261
 
 
262
}
 
263
 
 
264
//==================================================================================
 
265
//Move internal pointer to internal buffer +1
 
266
//Implementation required but no need in this driver
 
267
void pqxxSqlCursor::drv_bufferMovePointerNext()
 
268
{
 
269
 
 
270
}
 
271
 
 
272
//==================================================================================
 
273
//Move internal pointer to internal buffer -1
 
274
//Implementation required but no need in this driver
 
275
void pqxxSqlCursor::drv_bufferMovePointerPrev()
 
276
{
 
277
 
 
278
}
 
279
 
 
280
//==================================================================================
 
281
//Move internal pointer to internal buffer to N
 
282
//Implementation required but no need in this driver
 
283
void pqxxSqlCursor::drv_bufferMovePointerTo(Q_LLONG to)
 
284
{
 
285
 
 
286
}