Commit 69603179 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix PVS-Studio warning: possible memory leaks in production code

Most of the leaks are hardly reproducible in normal circumstances. But
the one in PNG converter is huge. PNG converter also had an invalid null
pointer access, which didn't crash Krita only by a happy coincidence.

CCBUG:393431
parent 7be37e4a
...@@ -665,7 +665,7 @@ bool SvgParser::parseSymbol(const KoXmlElement &e) ...@@ -665,7 +665,7 @@ bool SvgParser::parseSymbol(const KoXmlElement &e)
if (id.isEmpty()) return false; if (id.isEmpty()) return false;
KoSvgSymbol *svgSymbol = new KoSvgSymbol(); QScopedPointer<KoSvgSymbol> svgSymbol(new KoSvgSymbol());
// ensure that the clip path is loaded in local coordinates system // ensure that the clip path is loaded in local coordinates system
m_context.pushGraphicsContext(e, false); m_context.pushGraphicsContext(e, false);
...@@ -674,24 +674,23 @@ bool SvgParser::parseSymbol(const KoXmlElement &e) ...@@ -674,24 +674,23 @@ bool SvgParser::parseSymbol(const KoXmlElement &e)
QString title = e.firstChildElement("title").toElement().text(); QString title = e.firstChildElement("title").toElement().text();
KoShape *symbolShape = parseGroup(e); QScopedPointer<KoShape> symbolShape(parseGroup(e));
m_context.popGraphicsContext(); m_context.popGraphicsContext();
if (!symbolShape) return false; if (!symbolShape) return false;
svgSymbol->shape = symbolShape; svgSymbol->shape = symbolShape.take();
svgSymbol->title = title; svgSymbol->title = title;
svgSymbol->id = id; svgSymbol->id = id;
if (title.isEmpty()) svgSymbol->title = id; if (title.isEmpty()) svgSymbol->title = id;
if (svgSymbol->shape->boundingRect() == QRectF(0.0, 0.0, 0.0, 0.0)) { if (svgSymbol->shape->boundingRect() == QRectF(0.0, 0.0, 0.0, 0.0)) {
debugFlake << "Symbol" << id << "seems to be empty, discarding"; debugFlake << "Symbol" << id << "seems to be empty, discarding";
delete svgSymbol;
return false; return false;
} }
m_symbols << svgSymbol; m_symbols << svgSymbol.take();
return true; return true;
} }
...@@ -1259,8 +1258,7 @@ KoShape* SvgParser::parseUse(const KoXmlElement &e, DeferredUseStore* deferredUs ...@@ -1259,8 +1258,7 @@ KoShape* SvgParser::parseUse(const KoXmlElement &e, DeferredUseStore* deferredUs
const bool gotDef = m_context.hasDefinition(key); const bool gotDef = m_context.hasDefinition(key);
if (gotDef) { if (gotDef) {
return resolveUse(e, key); return resolveUse(e, key);
} } else if (deferredUseStore) {
if (!gotDef && deferredUseStore) {
deferredUseStore->add(&e, key); deferredUseStore->add(&e, key);
return 0; return 0;
} }
......
...@@ -419,8 +419,8 @@ void KisInputManager::Private::addWheelShortcut(KisAbstractInputAction* action, ...@@ -419,8 +419,8 @@ void KisInputManager::Private::addWheelShortcut(KisAbstractInputAction* action,
const QList<Qt::Key> &modifiers, const QList<Qt::Key> &modifiers,
KisShortcutConfiguration::MouseWheelMovement wheelAction) KisShortcutConfiguration::MouseWheelMovement wheelAction)
{ {
KisSingleActionShortcut *keyShortcut = QScopedPointer<KisSingleActionShortcut> keyShortcut(
new KisSingleActionShortcut(action, index); new KisSingleActionShortcut(action, index));
KisSingleActionShortcut::WheelAction a; KisSingleActionShortcut::WheelAction a;
switch(wheelAction) { switch(wheelAction) {
...@@ -444,7 +444,7 @@ void KisInputManager::Private::addWheelShortcut(KisAbstractInputAction* action, ...@@ -444,7 +444,7 @@ void KisInputManager::Private::addWheelShortcut(KisAbstractInputAction* action,
} }
keyShortcut->setWheel(QSet<Qt::Key>::fromList(modifiers), a); keyShortcut->setWheel(QSet<Qt::Key>::fromList(modifiers), a);
matcher.addShortcut(keyShortcut); matcher.addShortcut(keyShortcut.take());
} }
void KisInputManager::Private::addTouchShortcut(KisAbstractInputAction* action, int index, KisShortcutConfiguration::GestureAction gesture) void KisInputManager::Private::addTouchShortcut(KisAbstractInputAction* action, int index, KisShortcutConfiguration::GestureAction gesture)
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include "dialogs/kis_dlg_png_import.h" #include "dialogs/kis_dlg_png_import.h"
#include "kis_clipboard.h" #include "kis_clipboard.h"
#include <kis_cursor_override_hijacker.h> #include <kis_cursor_override_hijacker.h>
#include "kis_undo_stores.h"
namespace namespace
{ {
...@@ -622,8 +623,8 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod) ...@@ -622,8 +623,8 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod)
// Creating the KisImageSP // Creating the KisImageSP
if (m_image == 0) { if (m_image == 0) {
m_image = new KisImage(m_doc->createUndoStore(), width, height, cs, "built image"); KisUndoStore *store = m_doc ? m_doc->createUndoStore() : new KisSurrogateUndoStore();
Q_CHECK_PTR(m_image); m_image = new KisImage(store, width, height, cs, "built image");
} }
// Read resolution // Read resolution
...@@ -667,14 +668,13 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod) ...@@ -667,14 +668,13 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod)
} }
} }
} }
// Read image data // Read image data
KisPNGReaderAbstract* reader = 0; QScopedPointer<KisPNGReaderAbstract> reader;
try { try {
if (interlace_type == PNG_INTERLACE_ADAM7) { if (interlace_type == PNG_INTERLACE_ADAM7) {
reader = new KisPNGReaderFullImage(png_ptr, info_ptr, width, height); reader.reset(new KisPNGReaderFullImage(png_ptr, info_ptr, width, height));
} else { } else {
reader = new KisPNGReaderLineByLine(png_ptr, info_ptr, width, height); reader.reset(new KisPNGReaderLineByLine(png_ptr, info_ptr, width, height));
} }
} catch (std::bad_alloc& e) { } catch (std::bad_alloc& e) {
// new png_byte[] may raise such an exception if the image // new png_byte[] may raise such an exception if the image
...@@ -796,8 +796,6 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod) ...@@ -796,8 +796,6 @@ KisImageBuilder_Result KisPNGConverter::buildImage(QIODevice* iod)
// Freeing memory // Freeing memory
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
delete reader;
return KisImageBuilder_RESULT_OK; return KisImageBuilder_RESULT_OK;
} }
...@@ -970,10 +968,10 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -970,10 +968,10 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
Q_ASSERT(color_type > -1); Q_ASSERT(color_type > -1);
// Try to compute a table of color if the colorspace is RGB8f // Try to compute a table of color if the colorspace is RGB8f
png_colorp palette = 0; QScopedArrayPointer<png_color> palette;
int num_palette = 0; int num_palette = 0;
if (!options.alpha && options.tryToSaveAsIndexed && KoID(device->colorSpace()->id()) == KoID("RGBA")) { // png doesn't handle indexed images and alpha, and only have indexed for RGB8 if (!options.alpha && options.tryToSaveAsIndexed && KoID(device->colorSpace()->id()) == KoID("RGBA")) { // png doesn't handle indexed images and alpha, and only have indexed for RGB8
palette = new png_color[255]; palette.reset(new png_color[255]);
KisSequentialIterator it(device, imageRect); KisSequentialIterator it(device, imageRect);
...@@ -1014,7 +1012,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1014,7 +1012,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
color_nb_bits = 8; color_nb_bits = 8;
} }
} else { } else {
delete [] palette; palette.reset();
} }
} }
...@@ -1038,9 +1036,14 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1038,9 +1036,14 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
/*if (!options.saveSRGBProfile && sRGB) { /*if (!options.saveSRGBProfile && sRGB) {
png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
}*/ }*/
// we should ensure we don't access non-existing palette object
KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(palette || color_type != PNG_COLOR_TYPE_PALETTE, KisImageBuilder_RESULT_FAILURE);
// set the palette // set the palette
if (color_type == PNG_COLOR_TYPE_PALETTE) { if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_PLTE(png_ptr, info_ptr, palette, num_palette); png_set_PLTE(png_ptr, info_ptr, palette.data(), num_palette);
} }
// Save annotation // Save annotation
vKisAnnotationSP_it it = annotationsStart; vKisAnnotationSP_it it = annotationsStart;
...@@ -1188,26 +1191,48 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1188,26 +1191,48 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
// Write the PNG // Write the PNG
// png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0); // png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0);
struct RowPointersStruct {
RowPointersStruct(const QSize &size, int pixelSize)
: numRows(size.height())
{
rows = new png_byte*[numRows];
for (int i = 0; i < numRows; i++) {
rows[i] = new png_byte[size.width() * pixelSize];
}
}
~RowPointersStruct() {
for (int i = 0; i < numRows; i++) {
delete[] rows[i];
}
delete[] rows;
}
const int numRows = 0;
png_byte** rows = 0;
};
// Fill the data structure // Fill the data structure
png_byte** row_pointers = new png_byte*[imageRect.height()]; RowPointersStruct rowPointers(imageRect.size(), device->pixelSize());
int row = 0; int row = 0;
for (int y = imageRect.y(); y < imageRect.y() + imageRect.height(); y++, row++) { for (int y = imageRect.y(); y < imageRect.y() + imageRect.height(); y++, row++) {
KisHLineConstIteratorSP it = device->createHLineConstIteratorNG(imageRect.x(), y, imageRect.width()); KisHLineConstIteratorSP it = device->createHLineConstIteratorNG(imageRect.x(), y, imageRect.width());
row_pointers[row] = new png_byte[imageRect.width() * device->pixelSize()];
switch (color_type) { switch (color_type) {
case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_GRAY_ALPHA: case PNG_COLOR_TYPE_GRAY_ALPHA:
if (color_nb_bits == 16) { if (color_nb_bits == 16) {
quint16 *dst = reinterpret_cast<quint16 *>(row_pointers[row]); quint16 *dst = reinterpret_cast<quint16 *>(rowPointers.rows[row]);
do { do {
const quint16 *d = reinterpret_cast<const quint16 *>(it->oldRawData()); const quint16 *d = reinterpret_cast<const quint16 *>(it->oldRawData());
*(dst++) = d[0]; *(dst++) = d[0];
if (options.alpha) *(dst++) = d[1]; if (options.alpha) *(dst++) = d[1];
} while (it->nextPixel()); } while (it->nextPixel());
} else { } else {
quint8 *dst = row_pointers[row]; quint8 *dst = rowPointers.rows[row];
do { do {
const quint8 *d = it->oldRawData(); const quint8 *d = it->oldRawData();
*(dst++) = d[0]; *(dst++) = d[0];
...@@ -1218,7 +1243,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1218,7 +1243,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA: case PNG_COLOR_TYPE_RGB_ALPHA:
if (color_nb_bits == 16) { if (color_nb_bits == 16) {
quint16 *dst = reinterpret_cast<quint16 *>(row_pointers[row]); quint16 *dst = reinterpret_cast<quint16 *>(rowPointers.rows[row]);
do { do {
const quint16 *d = reinterpret_cast<const quint16 *>(it->oldRawData()); const quint16 *d = reinterpret_cast<const quint16 *>(it->oldRawData());
*(dst++) = d[2]; *(dst++) = d[2];
...@@ -1227,7 +1252,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1227,7 +1252,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
if (options.alpha) *(dst++) = d[3]; if (options.alpha) *(dst++) = d[3];
} while (it->nextPixel()); } while (it->nextPixel());
} else { } else {
quint8 *dst = row_pointers[row]; quint8 *dst = rowPointers.rows[row];
do { do {
const quint8 *d = it->oldRawData(); const quint8 *d = it->oldRawData();
*(dst++) = d[2]; *(dst++) = d[2];
...@@ -1238,7 +1263,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1238,7 +1263,7 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
} }
break; break;
case PNG_COLOR_TYPE_PALETTE: { case PNG_COLOR_TYPE_PALETTE: {
quint8 *dst = row_pointers[row]; quint8 *dst = rowPointers.rows[row];
KisPNGWriteStream writestream(dst, color_nb_bits); KisPNGWriteStream writestream(dst, color_nb_bits);
do { do {
const quint8 *d = it->oldRawData(); const quint8 *d = it->oldRawData();
...@@ -1255,26 +1280,17 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe ...@@ -1255,26 +1280,17 @@ KisImageBuilder_Result KisPNGConverter::buildFile(QIODevice* iodevice, const QRe
} }
break; break;
default: default:
delete[] row_pointers;
return KisImageBuilder_RESULT_UNSUPPORTED; return KisImageBuilder_RESULT_UNSUPPORTED;
} }
} }
png_write_image(png_ptr, row_pointers); png_write_image(png_ptr, rowPointers.rows);
// Writing is over // Writing is over
png_write_end(png_ptr, info_ptr); png_write_end(png_ptr, info_ptr);
// Free memory // Free memory
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
for (int y = 0; y < imageRect.height(); y++) {
delete[] row_pointers[y];
}
delete[] row_pointers;
if (color_type == PNG_COLOR_TYPE_PALETTE) {
delete [] palette;
}
return KisImageBuilder_RESULT_OK; return KisImageBuilder_RESULT_OK;
} }
......
...@@ -515,6 +515,10 @@ TextTool::TextTool(MockCanvas *canvas) // constructor for our unit tests; ...@@ -515,6 +515,10 @@ TextTool::TextTool(MockCanvas *canvas) // constructor for our unit tests;
TextTool::~TextTool() TextTool::~TextTool()
{ {
delete m_toolSelection; delete m_toolSelection;
KIS_SAFE_ASSERT_RECOVER (!m_currentCommand) {
delete m_currentCommand;
}
} }
void TextTool::showEditTip() void TextTool::showEditTip()
...@@ -2825,12 +2829,12 @@ void TextTool::createStyleFromCurrentBlockFormat(const QString &name) ...@@ -2825,12 +2829,12 @@ void TextTool::createStyleFromCurrentBlockFormat(const QString &name)
void TextTool::createStyleFromCurrentCharFormat(const QString &name) void TextTool::createStyleFromCurrentCharFormat(const QString &name)
{ {
KoCharacterStyle blankStyle;
KoTextDocument document(m_textShapeData->document()); KoTextDocument document(m_textShapeData->document());
KoStyleManager *styleManager = document.styleManager(); KoStyleManager *styleManager = document.styleManager();
KoCharacterStyle *originalCharStyle = styleManager->characterStyle(m_textEditor.data()->charFormat().intProperty(KoCharacterStyle::StyleId)); KoCharacterStyle *originalCharStyle = styleManager->characterStyle(m_textEditor.data()->charFormat().intProperty(KoCharacterStyle::StyleId));
KoCharacterStyle *autoStyle; KoCharacterStyle *autoStyle;
if (!originalCharStyle) { if (!originalCharStyle) {
KoCharacterStyle blankStyle;
originalCharStyle = &blankStyle; originalCharStyle = &blankStyle;
autoStyle = originalCharStyle->autoStyle(m_textEditor.data()->charFormat(), m_textEditor.data()->blockCharFormat()); autoStyle = originalCharStyle->autoStyle(m_textEditor.data()->charFormat(), m_textEditor.data()->blockCharFormat());
autoStyle->setParentStyle(0); autoStyle->setParentStyle(0);
......
...@@ -87,7 +87,8 @@ void BibliographyGenerator::generate() ...@@ -87,7 +87,8 @@ void BibliographyGenerator::generate()
cursor.setPosition(m_bibDocument->rootFrame()->firstPosition(), QTextCursor::KeepAnchor); cursor.setPosition(m_bibDocument->rootFrame()->firstPosition(), QTextCursor::KeepAnchor);
cursor.beginEditBlock(); cursor.beginEditBlock();
KoStyleManager *styleManager = KoTextDocument(m_block.document()).styleManager(); KoTextDocument koDocument(m_block.document());
KoStyleManager *styleManager = koDocument.styleManager();
if (!m_bibInfo->m_indexTitleTemplate.text.isNull()) { if (!m_bibInfo->m_indexTitleTemplate.text.isNull()) {
KoParagraphStyle *titleStyle = styleManager->paragraphStyle(m_bibInfo->m_indexTitleTemplate.styleId); KoParagraphStyle *titleStyle = styleManager->paragraphStyle(m_bibInfo->m_indexTitleTemplate.styleId);
...@@ -106,13 +107,13 @@ void BibliographyGenerator::generate() ...@@ -106,13 +107,13 @@ void BibliographyGenerator::generate()
QTextCharFormat savedCharFormat = cursor.charFormat(); QTextCharFormat savedCharFormat = cursor.charFormat();
QList<KoInlineCite*> citeList; QList<KoInlineCite*> citeList;
if ( KoTextDocument(m_block.document()).styleManager()->bibliographyConfiguration()->sortByPosition() ) { if (styleManager->bibliographyConfiguration()->sortByPosition()) {
citeList = KoTextDocument(m_block.document()) citeList = koDocument.inlineTextObjectManager()->
.inlineTextObjectManager()->citationsSortedByPosition(false, m_block.document()->firstBlock()); citationsSortedByPosition(false, m_block.document()->firstBlock());
} else { } else {
KoTextDocument *doc = new KoTextDocument(m_block.document()); citeList = sort(koDocument.inlineTextObjectManager()->
citeList = sort(doc->inlineTextObjectManager()->citationsSortedByPosition(false, m_block.document()->firstBlock()), citationsSortedByPosition(false, m_block.document()->firstBlock()),
KoTextDocument(m_block.document()).styleManager()->bibliographyConfiguration()->sortKeys()); koDocument.styleManager()->bibliographyConfiguration()->sortKeys());
} }
foreach (KoInlineCite *cite, citeList) foreach (KoInlineCite *cite, citeList)
......
...@@ -50,6 +50,7 @@ KoAnchorTextRange::KoAnchorTextRange(KoShapeAnchor *parent, const QTextCursor &c ...@@ -50,6 +50,7 @@ KoAnchorTextRange::KoAnchorTextRange(KoShapeAnchor *parent, const QTextCursor &c
KoAnchorTextRange::~KoAnchorTextRange() KoAnchorTextRange::~KoAnchorTextRange()
{ {
delete d_ptr;
} }
KoShapeAnchor *KoAnchorTextRange::anchor() const KoShapeAnchor *KoAnchorTextRange::anchor() const
......
...@@ -67,6 +67,7 @@ OdfTextTrackStyles::OdfTextTrackStyles(KoStyleManager *manager) ...@@ -67,6 +67,7 @@ OdfTextTrackStyles::OdfTextTrackStyles(KoStyleManager *manager)
OdfTextTrackStyles::~OdfTextTrackStyles() OdfTextTrackStyles::~OdfTextTrackStyles()
{ {
delete m_changeCommand;
} }
void OdfTextTrackStyles::beginEdit() void OdfTextTrackStyles::beginEdit()
......
...@@ -145,15 +145,13 @@ void KoTextWriter::write(const QTextDocument *document, int from, int to) ...@@ -145,15 +145,13 @@ void KoTextWriter::write(const QTextDocument *document, int from, int to)
} }
// save the whole list if all list-items are selected // save the whole list if all list-items are selected
if (currentList) { int fromindex = currentList->itemNumber(fromblock);
int fromindex = currentList->itemNumber(fromblock); int toindex = currentList->itemNumber(toblock);
int toindex = currentList->itemNumber(toblock); if ((fromcursor.isNull() || fromcursor.currentList() != currentList) &&
if ((fromcursor.isNull() || fromcursor.currentList() != currentList) && (toCursor.isNull() || toCursor.currentList() != currentList) &&
(toCursor.isNull() || toCursor.currentList() != currentList) && fromindex <= 0 && (toindex < 0 || toindex == currentList->count()-1)
fromindex <= 0 && (toindex < 0 || toindex == currentList->count()-1)
) { ) {
currentList = 0; currentList = 0;
}
} }
} }
} }
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <KoTableRowStyle.h> #include <KoTableRowStyle.h>
#include <KoInlineTextObjectManager.h> #include <KoInlineTextObjectManager.h>
#include <KoVariable.h> #include <KoVariable.h>
#include "kis_assert.h"
#include "TextDebug.h" #include "TextDebug.h"
...@@ -77,15 +78,22 @@ KoTextWriter::Private::Private(KoShapeSavingContext &context) ...@@ -77,15 +78,22 @@ KoTextWriter::Private::Private(KoShapeSavingContext &context)
, writer(0) , writer(0)
, context(context) , context(context)
{ {
currentPairedInlineObjectsStack = new QStack<KoInlineObject*>(); currentPairedInlineObjectsStack.reset(new QStack<KoInlineObject*>());
writer = &context.xmlWriter(); writer = &context.xmlWriter();
} }
void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int to, QHash<QTextList *, QString> &listStyles, QTextTable *currentTable, QTextList *currentList) KoTextWriter::Private::~Private()
{ {
pairedInlineObjectsStackStack.push(currentPairedInlineObjectsStack); KIS_SAFE_ASSERT_RECOVER (pairedInlineObjectsStackStack.isEmpty()) {
currentPairedInlineObjectsStack = new QStack<KoInlineObject*>(); qDeleteAll(pairedInlineObjectsStackStack);
QTextBlock block = document->findBlock(from); }
}
void KoTextWriter::Private::writeBlocks(QTextDocument *doc, int from, int to, QHash<QTextList *, QString> &listStyles, QTextTable *currentTable, QTextList *currentList)
{
pairedInlineObjectsStackStack.push(currentPairedInlineObjectsStack.take());
currentPairedInlineObjectsStack.reset(new QStack<KoInlineObject*>());
QTextBlock block = doc->findBlock(from);
// Here we are going to detect all sections that // Here we are going to detect all sections that
// are positioned entirely inside selection. // are positioned entirely inside selection.
...@@ -95,7 +103,7 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t ...@@ -95,7 +103,7 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t
// the selection and finding open/close pairs. // the selection and finding open/close pairs.
QSet<QString> entireWithinSectionNames; QSet<QString> entireWithinSectionNames;
QStack<QString> sectionNamesStack; QStack<QString> sectionNamesStack;
QTextCursor cur(document); QTextCursor cur(doc);
cur.setPosition(from); cur.setPosition(from);
while (to == -1 || cur.position() <= to) { while (to == -1 || cur.position() <= to) {
if (cur.block().position() >= from) { // Begin of the block is inside selection. if (cur.block().position() >= from) { // Begin of the block is inside selection.
...@@ -143,12 +151,12 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t ...@@ -143,12 +151,12 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t
continue; continue;
} }
if (format.hasProperty(KoParagraphStyle::TableOfContentsData)) { if (format.hasProperty(KoParagraphStyle::TableOfContentsData)) {
saveTableOfContents(document, listStyles, block); saveTableOfContents(doc, listStyles, block);
block = block.next(); block = block.next();
continue; continue;
} }
if (format.hasProperty(KoParagraphStyle::BibliographyData)) { if (format.hasProperty(KoParagraphStyle::BibliographyData)) {
saveBibliography(document, listStyles, block); saveBibliography(doc, listStyles, block);
block = block.next(); block = block.next();
continue; continue;
} }
...@@ -183,8 +191,7 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t ...@@ -183,8 +191,7 @@ void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int t
} // while } // while
Q_ASSERT(!pairedInlineObjectsStackStack.isEmpty()); Q_ASSERT(!pairedInlineObjectsStackStack.isEmpty());
delete currentPairedInlineObjectsStack; currentPairedInlineObjectsStack.reset(pairedInlineObjectsStackStack.pop());
currentPairedInlineObjectsStack = pairedInlineObjectsStackStack.pop();
} }
...@@ -1080,7 +1087,7 @@ void KoTextWriter::Private::writeAttributes(QTextStream &, KoXmlElement &) ...@@ -1080,7 +1087,7 @@ void KoTextWriter::Private::writeAttributes(QTextStream &, KoXmlElement &)
} }
void KoTextWriter::Private::writeNode(QTextStream &outputXmlStream, KoXmlNode &node, bool writeOnlyChildren) void KoTextWriter::Private::writeNode(QTextStream &outputXmlStream, const KoXmlNode &node, bool writeOnlyChildren)
{ {
if (node.isText()) { if (node.isText()) {
outputXmlStream << node.toText().data(); outputXmlStream << node.toText().data();
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <QStack> #include <QStack>
#include <QPair> #include <QPair>
#include <QString> #include <QString>
#include <QScopedPointer>
#include <KoTextWriter.h> #include <KoTextWriter.h>
#include <KoXmlReaderForward.h> #include <KoXmlReaderForward.h>
...@@ -101,7 +102,7 @@ public: ...@@ -101,7 +102,7 @@ public:
explicit Private(KoShapeSavingContext &context); explicit Private(KoShapeSavingContext &context);
~Private() {} ~Private();
void writeBlocks(QTextDocument *document, int from, int to, void writeBlocks(QTextDocument *document, int from, int to,
QHash<QTextList *, QString> &listStyles, QHash<QTextList *, QString> &listStyles,
...@@ -145,7 +146,7 @@ private: ...@@ -145,7 +146,7 @@ private:
// Common methods // Common methods
void writeAttributes(QTextStream &outputXmlStream, KoXmlElement &element); void writeAttributes(QTextStream &outputXmlStream, KoXmlElement &element);
void writeNode(QTextStream &outputXmlStream, KoXmlNode &node, bool writeOnlyChildren = false); void writeNode(QTextStream &outputXmlStream, const KoXmlNode &node, bool writeOnlyChildren = false);
QString createXmlId(); QString createXmlId();
...@@ -170,7 +171,7 @@ private: ...@@ -170,7 +171,7 @@ private:
// when their end markeris not included in the selection. However, when recursing into // when their end markeris not included in the selection. However, when recursing into
// e.g. the QTextDocument of a table, we need have a clean slate. Hence, a stack of stacks. // e.g. the QTextDocument of a table, we need have a clean slate. Hence, a stack of stacks.
QStack< QStack<KoInlineObject*> *> pairedInlineObjectsStackStack; QStack< QStack<KoInlineObject*> *> pairedInlineObjectsStackStack;
QStack<KoInlineObject*> *currentPairedInlineObjectsStack; QScopedPointer<QStack<KoInlineObject*>> currentPairedInlineObjectsStack;
QMap<KoList *, QString> listXmlIds; QMap<KoList *, QString> listXmlIds;
......
...@@ -236,11 +236,11 @@ KisImportExportFilter::ConversionStatus KisPPMImport::convert(KisDocument *docum ...@@ -236,11 +236,11 @@ KisImportExportFilter::ConversionStatus KisPPMImport::convert(KisDocument *docum
KisImageSP image = new KisImage(document->createUndoStore(), width, height, colorSpace, "built image"); KisImageSP image = new KisImage(document->createUndoStore(), width, height, colorSpace, "built image");
KisPaintLayerSP layer = new KisPaintLayer(image, image->nextLayerName(), 255); KisPaintLayerSP layer = new KisPaintLayer(image, image->nextLayerName(), 255);
KisPpmFlow* ppmFlow = 0; QScopedPointer<KisPpmFlow> ppmFlow;
if (isAscii) { if (isAscii) {
ppmFlow = new KisAsciiPpmFlow(io); ppmFlow.reset(new KisAsciiPpmFlow(io));
} else { } else {
ppmFlow = new KisBinaryPpmFlow(io, pixelsize * width); ppmFlow.reset(new KisBinaryPpmFlow(io,