Bug 414699 - Cloned layers create corrupted files after moving to a new document
Summary: Cloned layers create corrupted files after moving to a new document
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: File formats (show other bugs)
Version: 4.2.8
Platform: Microsoft Windows Microsoft Windows
: NOR major
Target Milestone: ---
Assignee: Dmitry Kazakov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-30 18:32 UTC by Yaroslav
Modified: 2021-08-03 10:09 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
A corrupted file example (29.87 KB, application/x-krita)
2019-11-30 18:32 UTC, Yaroslav
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Yaroslav 2019-11-30 18:32:43 UTC
Created attachment 124219 [details]
A corrupted file example

SUMMARY
Copying cloned layers to other documents generates corrupted .kra files, doesn't matter if the cloned layer's source is copied together with it.


STEPS TO REPRODUCE
1. Create a clone layer;
2. Copy the cloned layer via the context menu;
3. Create a new document and "Paste Layer" there;
4. Save, close, and reopen the document.


OBSERVED RESULT
The file opens


EXPECTED RESULT
Krita crashes


SOFTWARE/OS VERSIONS
Windows: 10


ADDITIONAL INFORMATION
I compared two `maindoc.xml` files and it seems the `clonefromuuid` attribute remains the same and doesn't point to the source layer since its `uuid` is changed. I was able to recover my files by fixing that attribute manually.
Comment 1 Tiar 2019-11-30 18:43:50 UTC
Crash here is quite straight-forward, it's just an assert in the visitor reading the clone layer from the kra file:

Thread 1 (Thread 0x7fffeb49a800 (LWP 15305)):
#0  0x00007ffff4266077 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff4247535 in __GI_abort () at abort.c:79
#2  0x00007ffff46358d7 in  () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
---Type <return> to continue, or q <return> to quit---
#3  0x00007ffff4634d59 in qt_assert_x(char const*, char const*, char const*, int) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#4  0x00007fffcc5ccc48 in KisKraLoadVisitor::visit(KisCloneLayer*) (this=0x7fffffffc1e0, layer=0x555572b828f0) at /home/tymon/devsec/krita/plugins/impex/libkra/kis_kra_load_visitor.cpp:308
#5  0x00007ffff5d523b5 in KisNodeVisitor::visitAll(KisNode*, bool) (this=0x7fffffffc1e0, node=0x5555727bfb50, breakOnFail=false) at /home/tymon/devsec/krita/libs/global/kis_shared_ptr.h:179
#6  0x00007fffcc5e3a7d in KisKraLoader::loadBinaryData(KoStore*, KisSharedPtr<KisImage>, QString const&, bool) (this=0x55555b44a3c0, store=0x55555708ee60, image=..., uri=..., external=<optimized out>)
    at /home/tymon/devsec/krita/libs/global/kis_shared_ptr.h:179
#7  0x00007fffcc62ffd0 in KraConverter::completeLoading(KoStore*) (this=0x7fffffffc6f0, store=0x55555708ee60) at /usr/include/c++/8/bits/atomic_base.h:295
#8  0x00007fffcc631282 in KraConverter::buildImage(QIODevice*) (this=0x7fffffffc6f0, io=<optimized out>) at /home/tymon/devsec/krita/plugins/impex/kra/kra_converter.cpp:96
#9  0x00007fffcc62babc in KraImport::convert(KisDocument*, QIODevice*, KisPinnedSharedPtr<KisPropertiesConfiguration>) (this=<optimized out>, document=0x55557280ced0, io=0x7fffffffc7a0)
    at /home/tymon/devsec/krita/plugins/impex/kra/kra_import.cpp:43
#10 0x00007ffff702863a in KisImportExportManager::doImport(QString const&, QSharedPointer<KisImportExportFilter>) (this=0x555572c256e0, location=..., filter=...) at /home/tymon/devsec/krita/libs/global/kis_shared_ptr.h:75
#11 0x00007ffff7029d43 in KisImportExportManager::convert(KisImportExportManager::Direction, QString const&, QString const&, QString const&, bool, KisPinnedSharedPtr<KisPropertiesConfiguration>, bool) (this=0x555572c256e0, direction=KisImportExportManager::Import, location=..., realLocation=..., mimeType=..., showWarnings=<optimized out>, exportConfiguration=..., isAsync=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qsharedpointer_impl.h:330
#12 0x00007ffff702a8fd in KisImportExportManager::importDocument(QString const&, QString const&) (this=<optimized out>, location=..., mimeType=...) at /home/tymon/devsec/krita/libs/global/kis_shared_ptr.h:218
#13 0x00007ffff7019be0 in KisDocument::openFile() (this=0x55557280ced0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qrefcount.h:60
#14 0x00007ffff701a45b in KisDocument::openUrlInternal(QUrl const&) (this=0x55557280ced0, url=...) at /home/tymon/devsec/krita/libs/ui/KisDocument.cpp:1987
#15 0x00007ffff701a9c5 in KisDocument::openUrl(QUrl const&, QFlags<KisDocument::OpenFlag>) (this=0x55557280ced0, _url=..., flags=...) at /home/tymon/devsec/krita/libs/ui/KisDocument.cpp:1418
#16 0x00007ffff7032f85 in KisMainWindow::openDocumentInternal(QUrl const&, QFlags<KisMainWindow::OpenFlag>) (this=0x5555706d8fb0, url=..., flags=...) at /home/tymon/devsec/krita/libs/ui/KisMainWindow.cpp:997
#17 0x00007ffff703975e in KisMainWindow::openDocument(QUrl const&, QFlags<KisMainWindow::OpenFlag>) (this=0x5555706d8fb0, url=..., flags=...) at /home/tymon/devsec/krita/libs/ui/KisMainWindow.cpp:968
#18 0x00007ffff7039c00 in KisMainWindow::slotFileOpen(bool) (this=0x5555706d8fb0, isImporting=false) at /home/tymon/devsec/krita/libs/ui/KisMainWindow.cpp:1573
#19 0x00007ffff48486db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#20 0x00007ffff52c47a2 in QAbstractButton::clicked(bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007ffff52c49ba in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007ffff52c5d7f in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007ffff52c5f55 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff521c7d8 in QWidget::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff51de4a1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007ffff51e5d28 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff70054e7 in KisApplication::notify(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555706f1580, event=0x7fffffffd5c0) at /home/tymon/devsec/krita/libs/ui/KisApplication.cpp:653
#28 0x00007ffff481f499 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#29 0x00007ffff51e5029 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007ffff5237304 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007ffff5239e8e in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#32 0x00007ffff51de4a1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#33 0x00007ffff51e5ae0 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#34 0x00007ffff70054e7 in KisApplication::notify(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555707c5c10, event=0x7fffffffda40) at /home/tymon/devsec/krita/libs/ui/KisApplication.cpp:653
#35 0x00007ffff481f499 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#36 0x00007ffff4c2453b in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#37 0x00007ffff4c26435 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#38 0x00007ffff4c00b6b in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#39 0x00007fffeabb3e5b in  () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#40 0x00007ffff481e16b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#41 0x00007ffff48262e2 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#42 0x0000555555e4e4ed in main (argc=<optimized out>, argv=0x7fffffffdfe8) at /home/tymon/devsec/krita/krita/main.cc:586
#43 0x00007ffff424909b in __libc_start_main (main=0x555555e4d0e0 <main>, argc=1, argv=0x7fffffffdfe8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdfd8) at ../csu/libc-start.c:308
#44 0x0000555555e4f84a in _start () at /home/tymon/devsec/krita/krita/main.cc:461


NOTE: I believe both copying clone layers and the assert should be fixed (Krita shouldn't "crash"/close just because the file it's reading is broken).
Comment 2 Tiar 2019-12-09 19:36:48 UTC
Git commit cf3682662b4d6c7796b2c248b20d3fe9077a5658 by Agata Cacko.
Committed on 09/12/2019 at 19:36.
Pushed by tymond into branch 'master'.

Fix crash opening .kra with incorrect clone source

Before this commit, files created using copying and pasting
clone layers from one file to another would be corrupted
and crash Krita when the user tried to open them.
This commit fixes crashing on opening those files.
After this commit, all clone layers are replaced by
empty paint layers. (Empty, because all data is lost).

M  +4    -0    libs/image/kis_async_merger.cpp
M  +32   -2    plugins/impex/kra/kra_converter.cpp
M  +8    -3    plugins/impex/libkra/kis_kra_load_visitor.cpp

https://invent.kde.org/kde/krita/commit/cf3682662b4d6c7796b2c248b20d3fe9077a5658
Comment 3 Tiar 2019-12-09 19:38:40 UTC
It shouldn't crash any more, but it's still a dataloss... I tried to fix it by making sure clones are converted into paint layers, but it's trickier than it looks like.
Comment 4 Tiar 2019-12-11 12:51:34 UTC
Git commit c7a001e171ed2923c2e88cc5397921bb3b4aa30b by Agata Cacko.
Committed on 11/12/2019 at 12:49.
Pushed by tymond into branch 'krita/4.2'.

Fix crash opening .kra with incorrect clone source

Before this commit, files created using copying and pasting
clone layers from one file to another would be corrupted
and crash Krita when the user tried to open them.
This commit fixes crashing on opening those files.
After this commit, all clone layers are replaced by
empty paint layers. (Empty, because all data is lost).

M  +4    -0    libs/image/kis_async_merger.cpp
M  +32   -2    plugins/impex/kra/kra_converter.cpp
M  +8    -3    plugins/impex/libkra/kis_kra_load_visitor.cpp

https://invent.kde.org/kde/krita/commit/c7a001e171ed2923c2e88cc5397921bb3b4aa30b
Comment 5 Dmitry Kazakov 2021-07-29 12:33:30 UTC
Git commit efe590e146eff93a2bb06ef8304fb9bd9622c192 by Dmitry Kazakov.
Committed on 29/07/2021 at 12:32.
Pushed by dkazakov into branch 'master'.

Reincarnate clone layers when they are D&D'ed into a different image

M  +13   -3    libs/ui/kis_mimedata.cpp

https://invent.kde.org/graphics/krita/commit/efe590e146eff93a2bb06ef8304fb9bd9622c192
Comment 6 Dmitry Kazakov 2021-08-03 10:09:23 UTC
Git commit 56419305696d810f9c3299ac8f3814a7a81402e0 by Dmitry Kazakov.
Committed on 03/08/2021 at 08:36.
Pushed by dkazakov into branch 'krita/4.3'.

Reincarnate clone layers when they are D&D'ed into a different image

M  +13   -3    libs/ui/kis_mimedata.cpp

https://invent.kde.org/graphics/krita/commit/56419305696d810f9c3299ac8f3814a7a81402e0