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

« back to all changes in this revision

Viewing changes to kexi/widget/tableview/kexitableviewpropertybuffer.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
/* This file is part of the KDE project
 
2
   Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl>
 
3
 
 
4
   This program is free software; you can redistribute it and/or
 
5
   modify it under the terms of the GNU Library General Public
 
6
   License as published by the Free Software Foundation; either
 
7
   version 2 of the License, or (at your option) any later version.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
   Library General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU Library General Public License
 
15
   along with this program; see the file COPYING.  If not, write to
 
16
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
   Boston, MA 02111-1307, USA.
 
18
*/
 
19
 
 
20
#include "kexitableviewpropertybuffer.h"
 
21
#include "kexitableviewdata.h"
 
22
#include "kexidataawareobjectiface.h"
 
23
 
 
24
#include <kexiviewbase.h>
 
25
 
 
26
#define MAX_FIELDS 101 //nice prime number (default buffer vector size)
 
27
 
 
28
KexiDataAwarePropertyBuffer::KexiDataAwarePropertyBuffer(KexiViewBase *view, 
 
29
        KexiDataAwareObjectInterface* dataObject)
 
30
 : QObject( view, QCString(view->name())+"KexiDataAwarePropertyBuffer" )
 
31
 , m_view(view)
 
32
 , m_dataObject(dataObject)
 
33
 , m_row(-99)
 
34
{
 
35
        m_buffers.setAutoDelete(true);
 
36
 
 
37
//      connect(m_dataObject, SIGNAL(dataSet(KexiTableViewData*)),
 
38
//              this, SLOT(slotDataSet(KexiTableViewData*)));
 
39
        m_dataObject->connectDataSetSignal(this, SLOT(slotDataSet(KexiTableViewData*)));
 
40
//      connect(m_dataObject, SIGNAL(cellSelected(int,int)), 
 
41
//              this, SLOT(slotCellSelected(int,int)));
 
42
        m_dataObject->connectCellSelectedSignal(this, SLOT(slotCellSelected(int,int)));
 
43
//
 
44
        slotDataSet( m_dataObject->data() );
 
45
        const bool wasDirty = view->dirty();
 
46
        clear();
 
47
        if (!wasDirty)
 
48
                view->setDirty(false);
 
49
}
 
50
 
 
51
KexiDataAwarePropertyBuffer::~KexiDataAwarePropertyBuffer()
 
52
{
 
53
}
 
54
 
 
55
void KexiDataAwarePropertyBuffer::slotDataSet( KexiTableViewData *data )
 
56
{
 
57
        if (!m_currentTVData.isNull()) {
 
58
                m_currentTVData->disconnect( this );
 
59
                clear();
 
60
        }
 
61
        m_currentTVData = data;
 
62
        if (!m_currentTVData.isNull()) {
 
63
                connect(m_currentTVData, SIGNAL(rowDeleted()), this, SLOT(slotRowDeleted()));
 
64
                connect(m_currentTVData, SIGNAL(rowsDeleted( const QValueList<int> & )), 
 
65
                        this, SLOT(slotRowsDeleted( const QValueList<int> & )));
 
66
                connect(m_currentTVData, SIGNAL(rowInserted(KexiTableItem*,uint,bool)), 
 
67
                        this, SLOT(slotRowInserted(KexiTableItem*,uint,bool)));
 
68
                connect(m_currentTVData, SIGNAL(reloadRequested()), 
 
69
                        this, SLOT(slotReloadRequested()));
 
70
        }
 
71
}
 
72
 
 
73
void KexiDataAwarePropertyBuffer::removeCurrentPropertyBuffer()
 
74
{
 
75
        remove( m_dataObject->currentRow() );
 
76
}
 
77
 
 
78
void KexiDataAwarePropertyBuffer::remove(uint row)
 
79
{
 
80
        KexiPropertyBuffer *buf = m_buffers.at(row);
 
81
        if (!buf)
 
82
                return;
 
83
        buf->debug();
 
84
        m_buffers.remove(row);
 
85
        m_view->setDirty();
 
86
        m_view->propertyBufferSwitched();
 
87
}
 
88
 
 
89
uint KexiDataAwarePropertyBuffer::size() const
 
90
{
 
91
        return m_buffers.size();
 
92
}
 
93
 
 
94
void KexiDataAwarePropertyBuffer::clear(uint minimumSize)
 
95
{
 
96
        m_buffers.clear();
 
97
        m_buffers.resize(QMAX(minimumSize, MAX_FIELDS));
 
98
        m_view->setDirty(true);
 
99
        m_view->propertyBufferSwitched();
 
100
}
 
101
 
 
102
void KexiDataAwarePropertyBuffer::slotReloadRequested()
 
103
{
 
104
        clear();
 
105
}
 
106
 
 
107
void KexiDataAwarePropertyBuffer::insert(uint row, KexiPropertyBuffer* buf, bool newOne)
 
108
{
 
109
        if (!buf || row >= m_buffers.size()) {
 
110
                kexiwarn << "KexiDataAwarePropertyBuffer::insert() invalid args: rew="<< row<< " buf="<< buf<< endl;
 
111
                return;
 
112
        }
 
113
        if (buf->parent() && buf->parent()!=this) {
 
114
                kexiwarn << "KexiDataAwarePropertyBuffer::insert() buffer's parent must be NULL or this KexiDataAwarePropertyBuffer" << endl;
 
115
                return;
 
116
        }
 
117
 
 
118
//      m_buffers.remove(row);//sanity
 
119
 
 
120
/*      //let's move down all buffers that are below
 
121
        m_buffers.setAutoDelete(false);//to avoid auto deleting in insert()
 
122
        m_buffers.resize(m_buffers.size()+1);
 
123
        for (int i=int(m_buffers.size()-1); i>(int)row; i--) {
 
124
                KexiPropertyBuffer *b = m_buffers[i-1];
 
125
                m_buffers.insert( i , b );
 
126
        }*/
 
127
        m_buffers.insert(row, buf);
 
128
 
 
129
//      m_buffers.setAutoDelete(true);//revert the flag
 
130
 
 
131
        connect(buf,SIGNAL(propertyChanged()), m_view, SLOT(setDirty()));
 
132
 
 
133
        if (newOne) {
 
134
                //add a special property indicating that this is brand new buffer, 
 
135
                //not just changed
 
136
                KexiProperty* prop = new KexiProperty("newrow", QVariant());
 
137
                prop->setVisible(false);
 
138
                buf->add( prop );
 
139
                m_view->setDirty();
 
140
        }
 
141
}
 
142
 
 
143
KexiPropertyBuffer* KexiDataAwarePropertyBuffer::currentPropertyBuffer() const
 
144
{
 
145
        return (m_dataObject->currentRow() >= 0) ? m_buffers.at( m_dataObject->currentRow() ) : 0;
 
146
}
 
147
 
 
148
void KexiDataAwarePropertyBuffer::slotRowDeleted()
 
149
{
 
150
        m_view->setDirty();
 
151
        removeCurrentPropertyBuffer();
 
152
 
 
153
        //let's move up all buffers that are below that deleted
 
154
        m_buffers.setAutoDelete(false);//to avoid auto deleting in insert()
 
155
        const int r = m_dataObject->currentRow();
 
156
        for (int i=r;i<int(m_buffers.size()-1);i++) {
 
157
                KexiPropertyBuffer *b = m_buffers[i+1];
 
158
                m_buffers.insert( i , b );
 
159
        }
 
160
        m_buffers.insert( m_buffers.size()-1, 0 );
 
161
        m_buffers.setAutoDelete(true);//revert the flag
 
162
 
 
163
        m_view->propertyBufferSwitched();
 
164
        emit rowDeleted();
 
165
}
 
166
 
 
167
void KexiDataAwarePropertyBuffer::slotRowsDeleted( const QValueList<int> &rows )
 
168
{
 
169
        //let's move most buffers up & delete unwanted
 
170
        m_buffers.setAutoDelete(false);//to avoid auto deleting in insert()
 
171
        const int orig_size = size();
 
172
        int prev_r = -1;
 
173
        int num_removed = 0, cur_r = -1;
 
174
        for (QValueList<int>::ConstIterator r_it = rows.constBegin(); r_it!=rows.constEnd() && *r_it < orig_size; ++r_it) {
 
175
                cur_r = *r_it;// - num_removed;
 
176
                if (prev_r>=0) {
 
177
//                      kdDebug() << "move " << prev_r+num_removed-1 << ".." << cur_r-1 << " to " << prev_r+num_removed-1 << ".." << cur_r-2 << endl;
 
178
                        int i=prev_r;
 
179
                        KexiPropertyBuffer *b = m_buffers.take(i+num_removed);
 
180
                        kdDebug() << "buffer " << i+num_removed << " deleted" << endl;
 
181
                        delete b;
 
182
                        num_removed++;
 
183
                        for (; (i+num_removed)<cur_r; i++) {
 
184
                                m_buffers.insert( i, m_buffers[i+num_removed] );
 
185
                                kdDebug() << i << " <- " << i+num_removed << endl;
 
186
                        }
 
187
                }
 
188
                prev_r = cur_r - num_removed;
 
189
        }
 
190
        //move remaining buffers up
 
191
        if (cur_r>=0) {
 
192
                KexiPropertyBuffer *b = m_buffers.take(cur_r);
 
193
                kdDebug() << "buffer " << cur_r << " deleted" << endl;
 
194
                delete b;
 
195
                num_removed++;
 
196
                for (int i=prev_r; (i+num_removed)<orig_size; i++) {
 
197
                        m_buffers.insert( i, m_buffers[i+num_removed] );
 
198
                        kdDebug() << i << " <- " << i+num_removed << endl;
 
199
                }
 
200
        }
 
201
        //finally: clear last rows
 
202
        for (int i=orig_size-num_removed; i<orig_size; i++) {
 
203
                kdDebug() << i << " <- zero" << endl;
 
204
                m_buffers.insert( i, 0 );
 
205
        }
 
206
        m_buffers.setAutoDelete(true);//revert the flag
 
207
        
 
208
        if (num_removed>0)
 
209
                m_view->setDirty();
 
210
        m_view->propertyBufferSwitched();
 
211
}
 
212
 
 
213
//void KexiDataAwarePropertyBuffer::slotEmptyRowInserted(KexiTableItem*, uint /*index*/)
 
214
void KexiDataAwarePropertyBuffer::slotRowInserted(KexiTableItem*, uint row, bool /*repaint*/)
 
215
{
 
216
        m_view->setDirty();
 
217
 
 
218
        //let's move down all buffers that are below
 
219
        m_buffers.setAutoDelete(false);//to avoid auto deleting in insert()
 
220
//      const int r = m_dataObject->currentRow();
 
221
        m_buffers.resize(m_buffers.size()+1);
 
222
        for (int i=int(m_buffers.size()); i>(int)row; i--) {
 
223
                KexiPropertyBuffer *b = m_buffers[i-1];
 
224
                m_buffers.insert( i , b );
 
225
        }
 
226
        m_buffers.insert( row, 0 );
 
227
        m_buffers.setAutoDelete(true);//revert the flag
 
228
 
 
229
        m_view->propertyBufferSwitched();
 
230
 
 
231
        emit rowInserted();
 
232
}
 
233
 
 
234
void KexiDataAwarePropertyBuffer::slotCellSelected(int, int row)
 
235
{
 
236
        if(row == m_row)
 
237
                return;
 
238
        m_row = row;
 
239
        m_view->propertyBufferSwitched();
 
240
}
 
241
 
 
242
KexiPropertyBuffer* KexiDataAwarePropertyBuffer::bufferForItem(KexiTableItem& item)
 
243
{
 
244
        if (m_currentTVData.isNull())
 
245
                return 0;
 
246
        int idx = m_currentTVData->findRef(&item);
 
247
        if (idx<0)
 
248
                return 0;
 
249
        return m_buffers[idx];
 
250
}
 
251
 
 
252
#include "kexitableviewpropertybuffer.moc"
 
253