From 6a185285ae44ed182dbab9206b9092f78c7d3714 Mon Sep 17 00:00:00 2001 From: Jos van den Oever Date: Tue, 18 Dec 2018 13:55:56 +0100 Subject: Escape bytes that are larger than or equal to 127 in config files Summary: UserBase tells me that KDE configuration files are encoded in UTF-8. https://userbase.kde.org/KDE_System_Administration/Configuration_Files In practice some *rc files have bytes outside that encoding. In my home directory I found two files that are not valid UTF-8. I searched with find ~/.config/ -name '*rc' -exec file {} + which gives these exceptions: akonadiconsolerc: Non-ISO extended-ASCII text, with very long lines kmail2rc: Non-ISO extended-ASCII text, with very long lines In kmail2rc, the offending fields are [AttachmentView]/State [CollectionFolderView]/HeaderState Both are QByteArray values saved from QHeaderView::saveState(). In the instance I found, the offending bytes were 0x81 and 0x84. akonadiconsolerc had way more of these values. All seem related to saving widget state and hence probably QByteArrays. The written QByteArray values look very strange. The bytes in the non-printable ASCII range are written as \xXX but the values above 127 are written literally. The encoding is done by KConfigIniBackend::stringToPrintable. It does not currently escape bytes that are larger than or equal to 127. Reviewers: dfaure, arichardson, apol Reviewed By: apol Subscribers: apol, kde-frameworks-devel Tags: #frameworks Differential Revision: https://phabricator.kde.org/D17651 --- autotests/kconfigtest.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'autotests/kconfigtest.cpp') diff --git a/autotests/kconfigtest.cpp b/autotests/kconfigtest.cpp index 45fe8e53..a60ea57a 100644 --- a/autotests/kconfigtest.cpp +++ b/autotests/kconfigtest.cpp @@ -1719,6 +1719,35 @@ void KConfigTest::testAnonymousConfig() QCOMPARE(general.readEntry("Foo"), QString("Bar")); } +void KConfigTest::testQByteArrayUtf8() +{ + QTemporaryFile file; + QVERIFY(file.open()); + qWarning() << file.fileName(); + KConfig config(file.fileName(), KConfig::SimpleConfig); + KConfigGroup general(&config, "General"); + QByteArray bytes(256, '\0'); + for (int i = 0; i < 256; i++) { + bytes[i] = i; + } + general.writeEntry("Utf8", bytes); + config.sync(); + file.flush(); + file.close(); + QFile readFile(file.fileName()); + QVERIFY(readFile.open(QFile::ReadOnly)); +#ifndef Q_OS_WIN + QCOMPARE(readFile.readAll(), QByteArrayLiteral("[General]\nUtf8=\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff\n")); +#else + QCOMPARE(readFile.readAll(), QByteArrayLiteral("[General]\r\nUtf8=\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff\r\n")); +#endif + + // check that reading works + KConfig config2(file.fileName(), KConfig::SimpleConfig); + KConfigGroup general2(&config2, "General"); + QCOMPARE(bytes, general2.readEntry("Utf8", QByteArray())); +} + void KConfigTest::testNewlines() { // test that kconfig always uses the native line endings -- cgit v1.2.1