Merge branch 'staging'

This commit is contained in:
Felix Geyer 2013-11-30 12:15:16 +01:00
commit ea628af580
24 changed files with 369 additions and 152 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
CMakeLists.txt.* CMakeLists.txt.*
build/

View File

@ -13,6 +13,12 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo Debug Debugfull Profile MinSizeRel."
FORCE)
endif()
project(KeePassX) project(KeePassX)
cmake_minimum_required(VERSION 2.6.4) cmake_minimum_required(VERSION 2.6.4)
@ -58,7 +64,7 @@ endmacro(add_gcc_compiler_flags)
add_definitions(-DQT_NO_KEYWORDS -DQT_NO_EXCEPTIONS -DQT_NO_STL -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII) add_definitions(-DQT_NO_KEYWORDS -DQT_NO_EXCEPTIONS -DQT_NO_STL -DQT_STRICT_ITERATORS -DQT_NO_CAST_TO_ASCII)
add_gcc_compiler_flags("-fno-common -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2") add_gcc_compiler_flags("-fno-common -fstack-protector --param=ssp-buffer-size=4")
add_gcc_compiler_flags("-Wall -Wextra -Wundef -Wpointer-arith -Wno-long-long") add_gcc_compiler_flags("-Wall -Wextra -Wundef -Wpointer-arith -Wno-long-long")
add_gcc_compiler_flags("-Wformat=2 -Wmissing-format-attribute") add_gcc_compiler_flags("-Wformat=2 -Wmissing-format-attribute")
add_gcc_compiler_flags("-fvisibility=hidden") add_gcc_compiler_flags("-fvisibility=hidden")
@ -68,6 +74,11 @@ add_gcc_compiler_cxxflags("-fno-exceptions -fno-rtti")
add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual") add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual")
add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings") add_gcc_compiler_cflags("-Wchar-subscripts -Wwrite-strings")
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
add_gcc_compiler_flags("-D_FORTIFY_SOURCE=2")
endif()
check_c_compiler_flag("-Werror=format-security -Werror=implicit-function-declaration" WERROR_C_AVAILABLE) check_c_compiler_flag("-Werror=format-security -Werror=implicit-function-declaration" WERROR_C_AVAILABLE)
check_cxx_compiler_flag("-Werror=format-security" WERROR_CXX_AVAILABLE) check_cxx_compiler_flag("-Werror=format-security" WERROR_CXX_AVAILABLE)
if(WERROR_C_AVAILABLE AND WERROR_CXX_AVAILABLE) if(WERROR_C_AVAILABLE AND WERROR_CXX_AVAILABLE)

View File

@ -32,13 +32,14 @@ QHash<Uuid, Database*> Database::m_uuidMap;
Database::Database() Database::Database()
: m_metadata(new Metadata(this)) : m_metadata(new Metadata(this))
, m_timer(new QTimer(this)) , m_timer(new QTimer(this))
, m_cipher(KeePass2::CIPHER_AES)
, m_compressionAlgo(CompressionGZip)
, m_transformRounds(50000)
, m_hasKey(false)
, m_emitModified(false) , m_emitModified(false)
, m_uuid(Uuid::random()) , m_uuid(Uuid::random())
{ {
m_data.cipher = KeePass2::CIPHER_AES;
m_data.compressionAlgo = CompressionGZip;
m_data.transformRounds = 50000;
m_data.hasKey = false;
setRootGroup(new Group()); setRootGroup(new Group());
rootGroup()->setUuid(Uuid::random()); rootGroup()->setUuid(Uuid::random());
m_timer->setSingleShot(true); m_timer->setSingleShot(true);
@ -150,60 +151,60 @@ void Database::addDeletedObject(const Uuid& uuid)
Uuid Database::cipher() const Uuid Database::cipher() const
{ {
return m_cipher; return m_data.cipher;
} }
Database::CompressionAlgorithm Database::compressionAlgo() const Database::CompressionAlgorithm Database::compressionAlgo() const
{ {
return m_compressionAlgo; return m_data.compressionAlgo;
} }
QByteArray Database::transformSeed() const QByteArray Database::transformSeed() const
{ {
return m_transformSeed; return m_data.transformSeed;
} }
quint64 Database::transformRounds() const quint64 Database::transformRounds() const
{ {
return m_transformRounds; return m_data.transformRounds;
} }
QByteArray Database::transformedMasterKey() const QByteArray Database::transformedMasterKey() const
{ {
return m_transformedMasterKey; return m_data.transformedMasterKey;
} }
void Database::setCipher(const Uuid& cipher) void Database::setCipher(const Uuid& cipher)
{ {
Q_ASSERT(!cipher.isNull()); Q_ASSERT(!cipher.isNull());
m_cipher = cipher; m_data.cipher = cipher;
} }
void Database::setCompressionAlgo(Database::CompressionAlgorithm algo) void Database::setCompressionAlgo(Database::CompressionAlgorithm algo)
{ {
Q_ASSERT(static_cast<quint32>(algo) <= CompressionAlgorithmMax); Q_ASSERT(static_cast<quint32>(algo) <= CompressionAlgorithmMax);
m_compressionAlgo = algo; m_data.compressionAlgo = algo;
} }
void Database::setTransformRounds(quint64 rounds) void Database::setTransformRounds(quint64 rounds)
{ {
if (m_transformRounds != rounds) { if (m_data.transformRounds != rounds) {
m_transformRounds = rounds; m_data.transformRounds = rounds;
if (m_hasKey) { if (m_data.hasKey) {
setKey(m_key); setKey(m_data.key);
} }
} }
} }
void Database::setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime) void Database::setKey(const CompositeKey& key, const QByteArray& transformSeed, bool updateChangedTime)
{ {
m_key = key; m_data.key = key;
m_transformSeed = transformSeed; m_data.transformSeed = transformSeed;
m_transformedMasterKey = key.transform(transformSeed, transformRounds()); m_data.transformedMasterKey = key.transform(transformSeed, transformRounds());
m_hasKey = true; m_data.hasKey = true;
if (updateChangedTime) { if (updateChangedTime) {
m_metadata->setMasterKeyChanged(Tools::currentDateTimeUtc()); m_metadata->setMasterKeyChanged(Tools::currentDateTimeUtc());
} }
@ -217,14 +218,14 @@ void Database::setKey(const CompositeKey& key)
bool Database::hasKey() const bool Database::hasKey() const
{ {
return m_hasKey; return m_data.hasKey;
} }
bool Database::verifyKey(const CompositeKey& key) const bool Database::verifyKey(const CompositeKey& key) const
{ {
Q_ASSERT(hasKey()); Q_ASSERT(hasKey());
return (m_key.rawKey() == key.rawKey()); return (m_data.key.rawKey() == key.rawKey());
} }
void Database::createRecycleBin() void Database::createRecycleBin()
@ -269,6 +270,12 @@ void Database::setEmitModified(bool value)
m_emitModified = value; m_emitModified = value;
} }
void Database::copyAttributesFrom(const Database* other)
{
m_data = other->m_data;
m_metadata->copyAttributesFrom(other->m_metadata);
}
Uuid Database::uuid() Uuid Database::uuid()
{ {
return m_uuid; return m_uuid;

View File

@ -49,6 +49,17 @@ public:
}; };
static const quint32 CompressionAlgorithmMax = CompressionGZip; static const quint32 CompressionAlgorithmMax = CompressionGZip;
struct DatabaseData
{
Uuid cipher;
CompressionAlgorithm compressionAlgo;
QByteArray transformSeed;
quint64 transformRounds;
QByteArray transformedMasterKey;
CompositeKey key;
bool hasKey;
};
Database(); Database();
~Database(); ~Database();
Group* rootGroup(); Group* rootGroup();
@ -91,6 +102,7 @@ public:
void recycleEntry(Entry* entry); void recycleEntry(Entry* entry);
void recycleGroup(Group* group); void recycleGroup(Group* group);
void setEmitModified(bool value); void setEmitModified(bool value);
void copyAttributesFrom(const Database* other);
/** /**
* Returns a unique id that is only valid as long as the Database exists. * Returns a unique id that is only valid as long as the Database exists.
@ -124,15 +136,7 @@ private:
Group* m_rootGroup; Group* m_rootGroup;
QList<DeletedObject> m_deletedObjects; QList<DeletedObject> m_deletedObjects;
QTimer* m_timer; QTimer* m_timer;
DatabaseData m_data;
Uuid m_cipher;
CompressionAlgorithm m_compressionAlgo;
QByteArray m_transformSeed;
quint64 m_transformRounds;
QByteArray m_transformedMasterKey;
CompositeKey m_key;
bool m_hasKey;
bool m_emitModified; bool m_emitModified;
Uuid m_uuid; Uuid m_uuid;

View File

@ -94,8 +94,14 @@ QImage Entry::icon() const
return databaseIcons()->icon(m_data.iconNumber); return databaseIcons()->icon(m_data.iconNumber);
} }
else { else {
// TODO: check if database() is 0 Q_ASSERT(database());
return database()->metadata()->customIcon(m_data.customIcon);
if (database()) {
return database()->metadata()->customIcon(m_data.customIcon);
}
else {
return QImage();
}
} }
} }
@ -105,9 +111,10 @@ QPixmap Entry::iconPixmap() const
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} }
else { else {
Q_ASSERT(database());
QPixmap pixmap; QPixmap pixmap;
if (!QPixmapCache::find(m_pixmapCacheKey, &pixmap)) { if (database() && !QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
// TODO: check if database() is 0
pixmap = QPixmap::fromImage(database()->metadata()->customIcon(m_data.customIcon)); pixmap = QPixmap::fromImage(database()->metadata()->customIcon(m_data.customIcon));
m_pixmapCacheKey = QPixmapCache::insert(pixmap); m_pixmapCacheKey = QPixmapCache::insert(pixmap);
} }
@ -432,22 +439,40 @@ void Entry::truncateHistory()
} }
} }
Entry* Entry::clone() const Entry* Entry::clone(CloneFlags flags) const
{ {
Entry* entry = new Entry(); Entry* entry = new Entry();
entry->setUpdateTimeinfo(false); entry->setUpdateTimeinfo(false);
entry->m_uuid = Uuid::random(); if (flags & CloneNewUuid) {
entry->m_uuid = Uuid::random();
}
else {
entry->m_uuid = m_uuid;
}
entry->m_data = m_data; entry->m_data = m_data;
entry->m_attributes->copyDataFrom(m_attributes); entry->m_attributes->copyDataFrom(m_attributes);
entry->m_attachments->copyDataFrom(m_attachments); entry->m_attachments->copyDataFrom(m_attachments);
entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations); entry->m_autoTypeAssociations->copyDataFrom(this->m_autoTypeAssociations);
if (flags & CloneIncludeHistory) {
Q_FOREACH (Entry* historyItem, m_history) {
Entry* historyItemClone = historyItem->clone(flags & ~CloneIncludeHistory & ~CloneNewUuid);
historyItemClone->setUpdateTimeinfo(false);
historyItemClone->setUuid(entry->uuid());
historyItemClone->setUpdateTimeinfo(true);
entry->addHistoryItem(historyItemClone);
}
}
entry->setUpdateTimeinfo(true); entry->setUpdateTimeinfo(true);
QDateTime now = Tools::currentDateTimeUtc(); if (flags & CloneResetTimeInfo) {
entry->m_data.timeInfo.setCreationTime(now); QDateTime now = Tools::currentDateTimeUtc();
entry->m_data.timeInfo.setLastModificationTime(now); entry->m_data.timeInfo.setCreationTime(now);
entry->m_data.timeInfo.setLastAccessTime(now); entry->m_data.timeInfo.setLastModificationTime(now);
entry->m_data.timeInfo.setLocationChanged(now); entry->m_data.timeInfo.setLastAccessTime(now);
entry->m_data.timeInfo.setLocationChanged(now);
}
return entry; return entry;
} }

View File

@ -110,7 +110,22 @@ public:
void addHistoryItem(Entry* entry); void addHistoryItem(Entry* entry);
void removeHistoryItems(const QList<Entry*>& historyEntries); void removeHistoryItems(const QList<Entry*>& historyEntries);
void truncateHistory(); void truncateHistory();
Entry* clone() const;
enum CloneFlag {
CloneNoFlags = 0,
CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeHistory = 4 // clone the history items
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
/**
* Creates a duplicate of this entry except that the returned entry isn't
* part of any group.
* Note that you need to copy the custom icons manually when inserting the
* new entry into another database.
*/
Entry* clone(CloneFlags flags) const;
void copyDataFrom(const Entry* other); void copyDataFrom(const Entry* other);
QString resolvePlaceholders(const QString& str) const; QString resolvePlaceholders(const QString& str) const;
@ -160,4 +175,6 @@ private:
bool m_updateTimeinfo; bool m_updateTimeinfo;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(Entry::CloneFlags)
#endif // KEEPASSX_ENTRY_H #endif // KEEPASSX_ENTRY_H

View File

@ -115,8 +115,14 @@ QImage Group::icon() const
return databaseIcons()->icon(m_data.iconNumber); return databaseIcons()->icon(m_data.iconNumber);
} }
else { else {
// TODO: check if m_db is 0 Q_ASSERT(m_db);
return m_db->metadata()->customIcon(m_data.customIcon);
if (m_db) {
return m_db->metadata()->customIcon(m_data.customIcon);
}
else {
return QImage();
}
} }
} }
@ -126,9 +132,10 @@ QPixmap Group::iconPixmap() const
return databaseIcons()->iconPixmap(m_data.iconNumber); return databaseIcons()->iconPixmap(m_data.iconNumber);
} }
else { else {
Q_ASSERT(m_db);
QPixmap pixmap; QPixmap pixmap;
if (!QPixmapCache::find(m_pixmapCacheKey, &pixmap)) { if (m_db && !QPixmapCache::find(m_pixmapCacheKey, &pixmap)) {
// TODO: check if m_db is 0
pixmap = QPixmap::fromImage(m_db->metadata()->customIcon(m_data.customIcon)); pixmap = QPixmap::fromImage(m_db->metadata()->customIcon(m_data.customIcon));
m_pixmapCacheKey = QPixmapCache::insert(pixmap); m_pixmapCacheKey = QPixmapCache::insert(pixmap);
} }
@ -457,11 +464,8 @@ QSet<Uuid> Group::customIconsRecursive() const
return result; return result;
} }
Group* Group::clone() const Group* Group::clone(Entry::CloneFlags entryFlags) const
{ {
// TODO: what to do about custom icons?
// they won't be available when changing the database later
Group* clonedGroup = new Group(); Group* clonedGroup = new Group();
clonedGroup->setUpdateTimeinfo(false); clonedGroup->setUpdateTimeinfo(false);
@ -470,7 +474,7 @@ Group* Group::clone() const
clonedGroup->m_data = m_data; clonedGroup->m_data = m_data;
Q_FOREACH (Entry* entry, entries()) { Q_FOREACH (Entry* entry, entries()) {
Entry* clonedEntry = entry->clone(); Entry* clonedEntry = entry->clone(entryFlags);
clonedEntry->setGroup(clonedGroup); clonedEntry->setGroup(clonedGroup);
} }
@ -496,6 +500,22 @@ void Group::copyDataFrom(const Group* other)
m_lastTopVisibleEntry = other->m_lastTopVisibleEntry; m_lastTopVisibleEntry = other->m_lastTopVisibleEntry;
} }
Database* Group::exportToDb()
{
Q_ASSERT(database());
Database* db = new Database();
Group* clonedGroup = clone(Entry::CloneNewUuid | Entry::CloneIncludeHistory);
clonedGroup->setParent(db->rootGroup());
QSet<Uuid> customIcons = customIconsRecursive();
db->metadata()->copyCustomIcons(customIcons, database()->metadata());
db->copyAttributesFrom(database());
return db;
}
void Group::addEntry(Entry* entry) void Group::addEntry(Entry* entry)
{ {
Q_ASSERT(entry); Q_ASSERT(entry);

View File

@ -100,8 +100,16 @@ public:
QList<Entry*> entriesRecursive(bool includeHistoryItems = false) const; QList<Entry*> entriesRecursive(bool includeHistoryItems = false) const;
QList<const Group*> groupsRecursive(bool includeSelf) const; QList<const Group*> groupsRecursive(bool includeSelf) const;
QSet<Uuid> customIconsRecursive() const; QSet<Uuid> customIconsRecursive() const;
Group* clone() const; /**
* Creates a duplicate of this group including all child entries and groups.
* The exceptions are that the returned group doesn't have a parent group
* and all TimeInfo attributes are set to the current time.
* Note that you need to copy the custom icons manually when inserting the
* new group into another database.
*/
Group* clone(Entry::CloneFlags entryFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo) const;
void copyDataFrom(const Group* other); void copyDataFrom(const Group* other);
Database* exportToDb();
QList<Entry*> search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity, QList<Entry*> search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity,
bool resolveInherit = true); bool resolveInherit = true);

View File

@ -26,25 +26,26 @@ const int Metadata::DefaultHistoryMaxSize = 6 * 1024 * 1024;
Metadata::Metadata(QObject* parent) Metadata::Metadata(QObject* parent)
: QObject(parent) : QObject(parent)
, m_generator("KeePassX")
, m_maintenanceHistoryDays(365)
, m_protectTitle(false)
, m_protectUsername(false)
, m_protectPassword(true)
, m_protectUrl(false)
, m_protectNotes(false)
// , m_autoEnableVisualHiding(false)
, m_recycleBinEnabled(true)
, m_masterKeyChangeRec(-1)
, m_masterKeyChangeForce(-1)
, m_historyMaxItems(DefaultHistoryMaxItems)
, m_historyMaxSize(DefaultHistoryMaxSize)
, m_updateDatetime(true) , m_updateDatetime(true)
{ {
m_data.generator = "KeePassX";
m_data.maintenanceHistoryDays = 365;
m_data.masterKeyChangeRec = -1;
m_data.masterKeyChangeForce = -1;
m_data.historyMaxItems = DefaultHistoryMaxItems;
m_data.historyMaxSize = DefaultHistoryMaxSize;
m_data.recycleBinEnabled = true;
m_data.protectTitle = false;
m_data.protectUsername = false;
m_data.protectPassword = true;
m_data.protectUrl = false;
m_data.protectNotes = false;
// m_data.autoEnableVisualHiding = false;
QDateTime now = Tools::currentDateTimeUtc(); QDateTime now = Tools::currentDateTimeUtc();
m_nameChanged = now; m_data.nameChanged = now;
m_descriptionChanged = now; m_data.descriptionChanged = now;
m_defaultUserNameChanged = now; m_data.defaultUserNameChanged = now;
m_recycleBinChanged = now; m_recycleBinChanged = now;
m_entryTemplatesGroupChanged = now; m_entryTemplatesGroupChanged = now;
m_masterKeyChanged = now; m_masterKeyChanged = now;
@ -81,74 +82,79 @@ void Metadata::setUpdateDatetime(bool value)
m_updateDatetime = value; m_updateDatetime = value;
} }
void Metadata::copyAttributesFrom(const Metadata* other)
{
m_data = other->m_data;
}
QString Metadata::generator() const QString Metadata::generator() const
{ {
return m_generator; return m_data.generator;
} }
QString Metadata::name() const QString Metadata::name() const
{ {
return m_name; return m_data.name;
} }
QDateTime Metadata::nameChanged() const QDateTime Metadata::nameChanged() const
{ {
return m_nameChanged; return m_data.nameChanged;
} }
QString Metadata::description() const QString Metadata::description() const
{ {
return m_description; return m_data.description;
} }
QDateTime Metadata::descriptionChanged() const QDateTime Metadata::descriptionChanged() const
{ {
return m_descriptionChanged; return m_data.descriptionChanged;
} }
QString Metadata::defaultUserName() const QString Metadata::defaultUserName() const
{ {
return m_defaultUserName; return m_data.defaultUserName;
} }
QDateTime Metadata::defaultUserNameChanged() const QDateTime Metadata::defaultUserNameChanged() const
{ {
return m_defaultUserNameChanged; return m_data.defaultUserNameChanged;
} }
int Metadata::maintenanceHistoryDays() const int Metadata::maintenanceHistoryDays() const
{ {
return m_maintenanceHistoryDays; return m_data.maintenanceHistoryDays;
} }
QColor Metadata::color() const QColor Metadata::color() const
{ {
return m_color; return m_data.color;
} }
bool Metadata::protectTitle() const bool Metadata::protectTitle() const
{ {
return m_protectTitle; return m_data.protectTitle;
} }
bool Metadata::protectUsername() const bool Metadata::protectUsername() const
{ {
return m_protectUsername; return m_data.protectUsername;
} }
bool Metadata::protectPassword() const bool Metadata::protectPassword() const
{ {
return m_protectPassword; return m_data.protectPassword;
} }
bool Metadata::protectUrl() const bool Metadata::protectUrl() const
{ {
return m_protectUrl; return m_data.protectUrl;
} }
bool Metadata::protectNotes() const bool Metadata::protectNotes() const
{ {
return m_protectNotes; return m_data.protectNotes;
} }
/*bool Metadata::autoEnableVisualHiding() const /*bool Metadata::autoEnableVisualHiding() const
@ -178,7 +184,7 @@ QList<Uuid> Metadata::customIconsOrder() const
bool Metadata::recycleBinEnabled() const bool Metadata::recycleBinEnabled() const
{ {
return m_recycleBinEnabled; return m_data.recycleBinEnabled;
} }
Group* Metadata::recycleBin() Group* Metadata::recycleBin()
@ -223,22 +229,22 @@ QDateTime Metadata::masterKeyChanged() const
int Metadata::masterKeyChangeRec() const int Metadata::masterKeyChangeRec() const
{ {
return m_masterKeyChangeRec; return m_data.masterKeyChangeRec;
} }
int Metadata::masterKeyChangeForce() const int Metadata::masterKeyChangeForce() const
{ {
return m_masterKeyChangeForce; return m_data.masterKeyChangeForce;
} }
int Metadata::historyMaxItems() const int Metadata::historyMaxItems() const
{ {
return m_historyMaxItems; return m_data.historyMaxItems;
} }
int Metadata::historyMaxSize() const int Metadata::historyMaxSize() const
{ {
return m_historyMaxSize; return m_data.historyMaxSize;
} }
QHash<QString, QString> Metadata::customFields() const QHash<QString, QString> Metadata::customFields() const
@ -248,12 +254,12 @@ QHash<QString, QString> Metadata::customFields() const
void Metadata::setGenerator(const QString& value) void Metadata::setGenerator(const QString& value)
{ {
set(m_generator, value); set(m_data.generator, value);
} }
void Metadata::setName(const QString& value) void Metadata::setName(const QString& value)
{ {
if (set(m_name, value, m_nameChanged)) { if (set(m_data.name, value, m_data.nameChanged)) {
Q_EMIT nameTextChanged(); Q_EMIT nameTextChanged();
} }
} }
@ -261,64 +267,64 @@ void Metadata::setName(const QString& value)
void Metadata::setNameChanged(const QDateTime& value) void Metadata::setNameChanged(const QDateTime& value)
{ {
Q_ASSERT(value.timeSpec() == Qt::UTC); Q_ASSERT(value.timeSpec() == Qt::UTC);
m_nameChanged = value; m_data.nameChanged = value;
} }
void Metadata::setDescription(const QString& value) void Metadata::setDescription(const QString& value)
{ {
set(m_description, value, m_descriptionChanged); set(m_data.description, value, m_data.descriptionChanged);
} }
void Metadata::setDescriptionChanged(const QDateTime& value) void Metadata::setDescriptionChanged(const QDateTime& value)
{ {
Q_ASSERT(value.timeSpec() == Qt::UTC); Q_ASSERT(value.timeSpec() == Qt::UTC);
m_descriptionChanged = value; m_data.descriptionChanged = value;
} }
void Metadata::setDefaultUserName(const QString& value) void Metadata::setDefaultUserName(const QString& value)
{ {
set(m_defaultUserName, value, m_defaultUserNameChanged); set(m_data.defaultUserName, value, m_data.defaultUserNameChanged);
} }
void Metadata::setDefaultUserNameChanged(const QDateTime& value) void Metadata::setDefaultUserNameChanged(const QDateTime& value)
{ {
Q_ASSERT(value.timeSpec() == Qt::UTC); Q_ASSERT(value.timeSpec() == Qt::UTC);
m_defaultUserNameChanged = value; m_data.defaultUserNameChanged = value;
} }
void Metadata::setMaintenanceHistoryDays(int value) void Metadata::setMaintenanceHistoryDays(int value)
{ {
set(m_maintenanceHistoryDays, value); set(m_data.maintenanceHistoryDays, value);
} }
void Metadata::setColor(const QColor& value) void Metadata::setColor(const QColor& value)
{ {
set(m_color, value); set(m_data.color, value);
} }
void Metadata::setProtectTitle(bool value) void Metadata::setProtectTitle(bool value)
{ {
set(m_protectTitle, value); set(m_data.protectTitle, value);
} }
void Metadata::setProtectUsername(bool value) void Metadata::setProtectUsername(bool value)
{ {
set(m_protectUsername, value); set(m_data.protectUsername, value);
} }
void Metadata::setProtectPassword(bool value) void Metadata::setProtectPassword(bool value)
{ {
set(m_protectPassword, value); set(m_data.protectPassword, value);
} }
void Metadata::setProtectUrl(bool value) void Metadata::setProtectUrl(bool value)
{ {
set(m_protectUrl, value); set(m_data.protectUrl, value);
} }
void Metadata::setProtectNotes(bool value) void Metadata::setProtectNotes(bool value)
{ {
set(m_protectNotes, value); set(m_data.protectNotes, value);
} }
/*void Metadata::setAutoEnableVisualHiding(bool value) /*void Metadata::setAutoEnableVisualHiding(bool value)
@ -361,7 +367,7 @@ void Metadata::copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* other
void Metadata::setRecycleBinEnabled(bool value) void Metadata::setRecycleBinEnabled(bool value)
{ {
set(m_recycleBinEnabled, value); set(m_data.recycleBinEnabled, value);
} }
void Metadata::setRecycleBin(Group* group) void Metadata::setRecycleBin(Group* group)
@ -404,22 +410,22 @@ void Metadata::setMasterKeyChanged(const QDateTime& value)
void Metadata::setMasterKeyChangeRec(int value) void Metadata::setMasterKeyChangeRec(int value)
{ {
set(m_masterKeyChangeRec, value); set(m_data.masterKeyChangeRec, value);
} }
void Metadata::setMasterKeyChangeForce(int value) void Metadata::setMasterKeyChangeForce(int value)
{ {
set(m_masterKeyChangeForce, value); set(m_data.masterKeyChangeForce, value);
} }
void Metadata::setHistoryMaxItems(int value) void Metadata::setHistoryMaxItems(int value)
{ {
set(m_historyMaxItems, value); set(m_data.historyMaxItems, value);
} }
void Metadata::setHistoryMaxSize(int value) void Metadata::setHistoryMaxSize(int value)
{ {
set(m_historyMaxSize, value); set(m_data.historyMaxSize, value);
} }
void Metadata::addCustomField(const QString& key, const QString& value) void Metadata::addCustomField(const QString& key, const QString& value)

View File

@ -37,6 +37,31 @@ class Metadata : public QObject
public: public:
explicit Metadata(QObject* parent = Q_NULLPTR); explicit Metadata(QObject* parent = Q_NULLPTR);
struct MetadataData
{
QString generator;
QString name;
QDateTime nameChanged;
QString description;
QDateTime descriptionChanged;
QString defaultUserName;
QDateTime defaultUserNameChanged;
int maintenanceHistoryDays;
QColor color;
bool recycleBinEnabled;
int historyMaxItems;
int historyMaxSize;
int masterKeyChangeRec;
int masterKeyChangeForce;
bool protectTitle;
bool protectUsername;
bool protectPassword;
bool protectUrl;
bool protectNotes;
// bool autoEnableVisualHiding;
};
QString generator() const; QString generator() const;
QString name() const; QString name() const;
QDateTime nameChanged() const; QDateTime nameChanged() const;
@ -107,6 +132,14 @@ public:
void addCustomField(const QString& key, const QString& value); void addCustomField(const QString& key, const QString& value);
void removeCustomField(const QString& key); void removeCustomField(const QString& key);
void setUpdateDatetime(bool value); void setUpdateDatetime(bool value);
/*
* Copy all attributes from other except:
* - Group pointers/uuids
* - Master key changed date
* - Custom icons
* - Custom fields
*/
void copyAttributesFrom(const Metadata* other);
Q_SIGNALS: Q_SIGNALS:
void nameTextChanged(); void nameTextChanged();
@ -116,27 +149,11 @@ private:
template <class P, class V> bool set(P& property, const V& value); template <class P, class V> bool set(P& property, const V& value);
template <class P, class V> bool set(P& property, const V& value, QDateTime& dateTime); template <class P, class V> bool set(P& property, const V& value, QDateTime& dateTime);
QString m_generator; MetadataData m_data;
QString m_name;
QDateTime m_nameChanged;
QString m_description;
QDateTime m_descriptionChanged;
QString m_defaultUserName;
QDateTime m_defaultUserNameChanged;
int m_maintenanceHistoryDays;
QColor m_color;
bool m_protectTitle;
bool m_protectUsername;
bool m_protectPassword;
bool m_protectUrl;
bool m_protectNotes;
// bool m_autoEnableVisualHiding;
QHash<Uuid, QImage> m_customIcons; QHash<Uuid, QImage> m_customIcons;
QList<Uuid> m_customIconsOrder; QList<Uuid> m_customIconsOrder;
bool m_recycleBinEnabled;
QPointer<Group> m_recycleBin; QPointer<Group> m_recycleBin;
QDateTime m_recycleBinChanged; QDateTime m_recycleBinChanged;
QPointer<Group> m_entryTemplatesGroup; QPointer<Group> m_entryTemplatesGroup;
@ -145,10 +162,6 @@ private:
QPointer<Group> m_lastTopVisibleGroup; QPointer<Group> m_lastTopVisibleGroup;
QDateTime m_masterKeyChanged; QDateTime m_masterKeyChanged;
int m_masterKeyChangeRec;
int m_masterKeyChangeForce;
int m_historyMaxItems;
int m_historyMaxSize;
QHash<QString, QString> m_customFields; QHash<QString, QString> m_customFields;

View File

@ -141,7 +141,7 @@ QString imageReaderFilter()
} }
} }
formatsStringList.append("*." + QString::fromAscii(format).toLower()); formatsStringList.append("*." + QString::fromLatin1(format).toLower());
} }
return formatsStringList.join(" "); return formatsStringList.join(" ");

View File

@ -42,12 +42,12 @@ Uuid Uuid::random()
QString Uuid::toBase64() const QString Uuid::toBase64() const
{ {
return QString::fromAscii(m_data.toBase64()); return QString::fromLatin1(m_data.toBase64());
} }
QString Uuid::toHex() const QString Uuid::toHex() const
{ {
return QString::fromAscii(m_data.toHex()); return QString::fromLatin1(m_data.toHex());
} }
QByteArray Uuid::toByteArray() const QByteArray Uuid::toByteArray() const
@ -85,7 +85,7 @@ bool Uuid::operator!=(const Uuid& other) const
Uuid Uuid::fromBase64(const QString& str) Uuid Uuid::fromBase64(const QString& str)
{ {
QByteArray data = QByteArray::fromBase64(str.toAscii()); QByteArray data = QByteArray::fromBase64(str.toLatin1());
return Uuid(data); return Uuid(data);
} }

View File

@ -779,7 +779,7 @@ void KeePass2XmlReader::parseEntryString(Entry* entry)
if (isProtected && !value.isEmpty()) { if (isProtected && !value.isEmpty()) {
if (m_randomStream) { if (m_randomStream) {
value = QString::fromUtf8(m_randomStream->process(QByteArray::fromBase64(value.toAscii()))); value = QString::fromUtf8(m_randomStream->process(QByteArray::fromBase64(value.toLatin1())));
} }
else { else {
raiseError("Unable to decrypt entry string"); raiseError("Unable to decrypt entry string");
@ -1053,7 +1053,7 @@ Uuid KeePass2XmlReader::readUuid()
QByteArray KeePass2XmlReader::readBinary() QByteArray KeePass2XmlReader::readBinary()
{ {
return QByteArray::fromBase64(readString().toAscii()); return QByteArray::fromBase64(readString().toLatin1());
} }
QByteArray KeePass2XmlReader::readCompressedBinary() QByteArray KeePass2XmlReader::readCompressedBinary()

View File

@ -192,7 +192,7 @@ void KeePass2XmlWriter::writeBinaries()
} }
if (!data.isEmpty()) { if (!data.isEmpty()) {
m_xml.writeCharacters(QString::fromAscii(data.toBase64())); m_xml.writeCharacters(QString::fromLatin1(data.toBase64()));
} }
m_xml.writeEndElement(); m_xml.writeEndElement();
} }
@ -341,7 +341,7 @@ void KeePass2XmlWriter::writeEntry(const Entry* entry)
if (m_randomStream) { if (m_randomStream) {
m_xml.writeAttribute("Protected", "True"); m_xml.writeAttribute("Protected", "True");
QByteArray rawData = m_randomStream->process(entry->attributes()->value(key).toUtf8()); QByteArray rawData = m_randomStream->process(entry->attributes()->value(key).toUtf8());
value = QString::fromAscii(rawData.toBase64()); value = QString::fromLatin1(rawData.toBase64());
} }
else { else {
m_xml.writeAttribute("ProtectInMemory", "True"); m_xml.writeAttribute("ProtectInMemory", "True");
@ -485,7 +485,7 @@ void KeePass2XmlWriter::writeUuid(const QString& qualifiedName, const Entry* ent
void KeePass2XmlWriter::writeBinary(const QString& qualifiedName, const QByteArray& ba) void KeePass2XmlWriter::writeBinary(const QString& qualifiedName, const QByteArray& ba)
{ {
writeString(qualifiedName, QString::fromAscii(ba.toBase64())); writeString(qualifiedName, QString::fromLatin1(ba.toBase64()));
} }
void KeePass2XmlWriter::writeColor(const QString& qualifiedName, const QColor& color) void KeePass2XmlWriter::writeColor(const QString& qualifiedName, const QColor& color)

View File

@ -224,7 +224,7 @@ void DatabaseWidget::cloneEntry()
return; return;
} }
Entry* entry = currentEntry->clone(); Entry* entry = currentEntry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
entry->setGroup(currentEntry->group()); entry->setGroup(currentEntry->group());
m_entryView->setFocus(); m_entryView->setFocus();
m_entryView->setCurrentEntry(entry); m_entryView->setCurrentEntry(entry);

View File

@ -26,6 +26,7 @@
#include <QMenu> #include <QMenu>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include "core/Config.h"
#include "core/Database.h" #include "core/Database.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Metadata.h" #include "core/Metadata.h"
@ -605,9 +606,11 @@ void EditEntryWidget::insertAttachment()
{ {
Q_ASSERT(!m_history); Q_ASSERT(!m_history);
// TODO: save last used dir QString defaultDir = config()->get("LastAttachmentDir").toString();
QString filename = fileDialog()->getOpenFileName(this, tr("Select file"), if (defaultDir.isEmpty() || !QDir(defaultDir).exists()) {
QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)); defaultDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
}
QString filename = fileDialog()->getOpenFileName(this, tr("Select file"), defaultDir);
if (filename.isEmpty() || !QFile::exists(filename)) { if (filename.isEmpty() || !QFile::exists(filename)) {
return; return;
} }
@ -637,8 +640,11 @@ void EditEntryWidget::saveCurrentAttachment()
} }
QString filename = m_attachmentsModel->keyByIndex(index); QString filename = m_attachmentsModel->keyByIndex(index);
// TODO: save last used dir QString defaultDirName = config()->get("LastAttachmentDir").toString();
QDir dir(QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)); if (defaultDirName.isEmpty() || !QDir(defaultDirName).exists()) {
defaultDirName = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
}
QDir dir(defaultDirName);
QString savePath = fileDialog()->getSaveFileName(this, tr("Save attachment"), QString savePath = fileDialog()->getSaveFileName(this, tr("Save attachment"),
dir.filePath(filename)); dir.filePath(filename));
if (!savePath.isEmpty()) { if (!savePath.isEmpty()) {

View File

@ -298,7 +298,7 @@ bool GroupModel::dropMimeData(const QMimeData* data, Qt::DropAction action,
entry = dragEntry; entry = dragEntry;
} }
else { else {
entry = dragEntry->clone(); entry = dragEntry->clone(Entry::CloneNewUuid | Entry::CloneResetTimeInfo);
} }
Database* sourceDb = dragEntry->group()->database(); Database* sourceDb = dragEntry->group()->database();

View File

@ -122,7 +122,7 @@ void FileKey::create(QIODevice* device)
xmlWriter.writeStartElement("Key"); xmlWriter.writeStartElement("Key");
QByteArray data = randomGen()->randomArray(32); QByteArray data = randomGen()->randomArray(32);
xmlWriter.writeTextElement("Data", QString::fromAscii(data.toBase64())); xmlWriter.writeTextElement("Data", QString::fromLatin1(data.toBase64()));
xmlWriter.writeEndElement(); xmlWriter.writeEndElement();
@ -211,7 +211,7 @@ QByteArray FileKey::loadXmlKey(QXmlStreamReader& xmlReader)
while (!xmlReader.error() && xmlReader.readNextStartElement()) { while (!xmlReader.error() && xmlReader.readNextStartElement()) {
if (xmlReader.name() == "Data") { if (xmlReader.name() == "Data") {
// TODO: do we need to enforce a specific data.size()? // TODO: do we need to enforce a specific data.size()?
data = QByteArray::fromBase64(xmlReader.readElementText().toAscii()); data = QByteArray::fromBase64(xmlReader.readElementText().toLatin1());
} }
} }

View File

@ -37,13 +37,13 @@ void TestCryptoHash::test()
QCOMPARE(cryptoHash1.result(), QCOMPARE(cryptoHash1.result(),
QByteArray::fromHex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")); QByteArray::fromHex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
QByteArray source2 = QString("KeePassX").toAscii(); QByteArray source2 = QString("KeePassX").toLatin1();
QByteArray result2 = CryptoHash::hash(source2, CryptoHash::Sha256); QByteArray result2 = CryptoHash::hash(source2, CryptoHash::Sha256);
QCOMPARE(result2, QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4")); QCOMPARE(result2, QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4"));
CryptoHash cryptoHash3(CryptoHash::Sha256); CryptoHash cryptoHash3(CryptoHash::Sha256);
cryptoHash3.addData(QString("KeePa").toAscii()); cryptoHash3.addData(QString("KeePa").toLatin1());
cryptoHash3.addData(QString("ssX").toAscii()); cryptoHash3.addData(QString("ssX").toLatin1());
QCOMPARE(cryptoHash3.result(), QCOMPARE(cryptoHash3.result(),
QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4")); QByteArray::fromHex("0b56e5f65263e747af4a833bd7dd7ad26a64d7a4de7c68e52364893dca0766b4"));
} }

View File

@ -21,6 +21,12 @@
#include "tests.h" #include "tests.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "crypto/Crypto.h"
void TestEntry::initTestCase()
{
Crypto::init();
}
void TestEntry::testHistoryItemDeletion() void TestEntry::testHistoryItemDeletion()
{ {
@ -74,4 +80,46 @@ void TestEntry::testCopyDataFrom()
QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("3")); QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("3"));
} }
void TestEntry::testClone()
{
Entry* entryOrg = new Entry();
entryOrg->setUuid(Uuid::random());
entryOrg->setTitle("Original Title");
entryOrg->beginUpdate();
entryOrg->setTitle("New Title");
entryOrg->endUpdate();
TimeInfo entryOrgTime = entryOrg->timeInfo();
QDateTime dateTime;
dateTime.setTimeSpec(Qt::UTC);
dateTime.setMSecsSinceEpoch(60);
entryOrgTime.setCreationTime(dateTime);
entryOrg->setTimeInfo(entryOrgTime);
Entry* entryCloneNone = entryOrg->clone(Entry::CloneNoFlags);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneNone->title(), QString("New Title"));
QCOMPARE(entryCloneNone->historyItems().size(), 0);
QCOMPARE(entryCloneNone->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
Entry* entryCloneNewUuid = entryOrg->clone(Entry::CloneNewUuid);
QVERIFY(entryCloneNewUuid->uuid() != entryOrg->uuid());
QVERIFY(!entryCloneNewUuid->uuid().isNull());
QCOMPARE(entryCloneNewUuid->title(), QString("New Title"));
QCOMPARE(entryCloneNewUuid->historyItems().size(), 0);
QCOMPARE(entryCloneNewUuid->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
Entry* entryCloneResetTime = entryOrg->clone(Entry::CloneResetTimeInfo);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneResetTime->title(), QString("New Title"));
QCOMPARE(entryCloneResetTime->historyItems().size(), 0);
QVERIFY(entryCloneResetTime->timeInfo().creationTime() != entryOrg->timeInfo().creationTime());
Entry* entryCloneHistory = entryOrg->clone(Entry::CloneIncludeHistory);
QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
QCOMPARE(entryCloneHistory->title(), QString("New Title"));
QCOMPARE(entryCloneHistory->historyItems().size(), 1);
QCOMPARE(entryCloneHistory->historyItems().first()->title(), QString("Original Title"));
QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
}
QTEST_GUILESS_MAIN(TestEntry) QTEST_GUILESS_MAIN(TestEntry)

View File

@ -27,8 +27,10 @@ class TestEntry : public QObject
Q_OBJECT Q_OBJECT
private Q_SLOTS: private Q_SLOTS:
void initTestCase();
void testHistoryItemDeletion(); void testHistoryItemDeletion();
void testCopyDataFrom(); void testCopyDataFrom();
void testClone();
}; };
#endif // KEEPASSX_TESTENTRY_H #endif // KEEPASSX_TESTENTRY_H

View File

@ -441,8 +441,11 @@ void TestGroup::testClone()
Entry* originalGroupEntry = new Entry(); Entry* originalGroupEntry = new Entry();
originalGroupEntry->setGroup(originalGroup); originalGroupEntry->setGroup(originalGroup);
originalGroupEntry->setTitle("GroupEntry"); originalGroupEntry->setTitle("GroupEntryOld");
originalGroupEntry->setIcon(43); originalGroupEntry->setIcon(43);
originalGroupEntry->beginUpdate();
originalGroupEntry->setTitle("GroupEntry");
originalGroupEntry->endUpdate();
Group* subGroup = new Group(); Group* subGroup = new Group();
subGroup->setParent(originalGroup); subGroup->setParent(originalGroup);
@ -465,6 +468,7 @@ void TestGroup::testClone()
QVERIFY(clonedGroupEntry->uuid() != originalGroupEntry->uuid()); QVERIFY(clonedGroupEntry->uuid() != originalGroupEntry->uuid());
QCOMPARE(clonedGroupEntry->title(), QString("GroupEntry")); QCOMPARE(clonedGroupEntry->title(), QString("GroupEntry"));
QCOMPARE(clonedGroupEntry->iconNumber(), 43); QCOMPARE(clonedGroupEntry->iconNumber(), 43);
QCOMPARE(clonedGroupEntry->historyItems().size(), 0);
Group* clonedSubGroup = clonedGroup->children().at(0); Group* clonedSubGroup = clonedGroup->children().at(0);
QVERIFY(clonedSubGroup->uuid() != subGroup->uuid()); QVERIFY(clonedSubGroup->uuid() != subGroup->uuid());
@ -533,4 +537,48 @@ void TestGroup::testCopyCustomIcons()
QCOMPARE(metaTarget->customIcon(group2Icon).pixel(0, 0), qRgb(4, 5, 6)); QCOMPARE(metaTarget->customIcon(group2Icon).pixel(0, 0), qRgb(4, 5, 6));
} }
void TestGroup::testExportToDb()
{
QImage iconImage(1, 1, QImage::Format_RGB32);
iconImage.setPixel(0, 0, qRgb(1, 2, 3));
Uuid iconUuid = Uuid::random();
QImage iconUnusedImage(1, 1, QImage::Format_RGB32);
iconUnusedImage.setPixel(0, 0, qRgb(1, 2, 3));
Uuid iconUnusedUuid = Uuid::random();
Database* dbOrg = new Database();
Group* groupOrg = new Group();
groupOrg->setParent(dbOrg->rootGroup());
groupOrg->setName("GTEST");
Entry* entryOrg = new Entry();
entryOrg->setGroup(groupOrg);
entryOrg->setTitle("ETEST");
dbOrg->metadata()->addCustomIcon(iconUuid, iconImage);
dbOrg->metadata()->addCustomIcon(iconUnusedUuid, iconUnusedImage);
entryOrg->setIcon(iconUuid);
entryOrg->beginUpdate();
entryOrg->setIcon(Entry::DefaultIconNumber);
entryOrg->endUpdate();
Database* dbExp = groupOrg->exportToDb();
QCOMPARE(dbExp->rootGroup()->children().size(), 1);
Group* groupExp = dbExp->rootGroup()->children().first();
QVERIFY(groupExp != groupOrg);
QCOMPARE(groupExp->name(), groupOrg->name());
QCOMPARE(groupExp->entries().size(), 1);
Entry* entryExp = groupExp->entries().first();
QCOMPARE(entryExp->title(), entryOrg->title());
QCOMPARE(dbExp->metadata()->customIcons().size(), 1);
QVERIFY(dbExp->metadata()->containsCustomIcon(iconUuid));
QCOMPARE(entryExp->iconNumber(), entryOrg->iconNumber());
QCOMPARE(entryExp->historyItems().size(), 1);
QCOMPARE(entryExp->historyItems().first()->iconUuid(), iconUuid);
delete dbOrg;
delete dbExp;
}
QTEST_GUILESS_MAIN(TestGroup) QTEST_GUILESS_MAIN(TestGroup)

View File

@ -35,6 +35,7 @@ private Q_SLOTS:
void testAndConcatenationInSearch(); void testAndConcatenationInSearch();
void testClone(); void testClone();
void testCopyCustomIcons(); void testCopyCustomIcons();
void testExportToDb();
}; };
#endif // KEEPASSX_TESTGROUP_H #endif // KEEPASSX_TESTGROUP_H

View File

@ -33,7 +33,7 @@ namespace QTest {
char* toString(const Uuid& uuid) char* toString(const Uuid& uuid)
{ {
QByteArray ba = "Uuid("; QByteArray ba = "Uuid(";
ba += uuid.toBase64().toAscii().constData(); ba += uuid.toBase64().toLatin1().constData();
ba += ")"; ba += ")";
return qstrdup(ba.constData()); return qstrdup(ba.constData());
} }
@ -296,7 +296,7 @@ void TestKeePass2XmlReader::testEntry2()
QVERIFY(attrs.isEmpty()); QVERIFY(attrs.isEmpty());
QCOMPARE(entry->attachments()->keys().size(), 1); QCOMPARE(entry->attachments()->keys().size(), 1);
QCOMPARE(QString::fromAscii(entry->attachments()->value("myattach.txt")), QString("abcdefghijk")); QCOMPARE(QString::fromLatin1(entry->attachments()->value("myattach.txt")), QString("abcdefghijk"));
QCOMPARE(entry->autoTypeEnabled(), true); QCOMPARE(entry->autoTypeEnabled(), true);
QCOMPARE(entry->autoTypeObfuscation(), 1); QCOMPARE(entry->autoTypeObfuscation(), 1);