File indexing completed on 2024-05-12 16:06:01
0001 /* 0002 SPDX-FileCopyrightText: 2023 g10 Code GmbH 0003 SPDX-FileContributor: Sune Stolborg Vuorela <sune@vuorela.dk> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 0007 Copied from poppler (pdf library) 0008 */ 0009 #include "../part/DistinguishedNameParser.h" 0010 0011 #include <QTest> 0012 0013 class TestDistinguishedNameParser : public QObject 0014 { 0015 Q_OBJECT 0016 public: 0017 explicit TestDistinguishedNameParser(QObject *parent = nullptr) 0018 : QObject(parent) 0019 { 0020 } 0021 private Q_SLOTS: 0022 // The big set of input/output. Several of the helper functions can be tested independently 0023 void testParser(); 0024 void testParser_data(); 0025 0026 void testRemoveLeadingSpaces(); 0027 void testRemoveLeadingSpaces_data(); 0028 0029 void testRemoveTrailingSpaces(); 0030 void testRemoveTrailingSpaces_data(); 0031 0032 void testParseHexString(); 0033 void testParseHexString_data(); 0034 }; 0035 0036 Q_DECLARE_METATYPE(DN::Result); 0037 Q_DECLARE_METATYPE(std::string); 0038 Q_DECLARE_METATYPE(std::optional<std::string>); 0039 0040 void TestDistinguishedNameParser::testParser() 0041 { 0042 QFETCH(std::string, inputData); 0043 QFETCH(DN::Result, expectedResult); 0044 0045 auto result = DN::parseString(inputData); 0046 QCOMPARE(result, expectedResult); 0047 } 0048 0049 void TestDistinguishedNameParser::testParser_data() 0050 { 0051 QTest::addColumn<std::string>("inputData"); 0052 QTest::addColumn<DN::Result>("expectedResult"); 0053 0054 QTest::newRow("empty") << std::string {} << DN::Result {}; 0055 QTest::newRow("CN=Simple") << std::string {"CN=Simple"} << DN::Result {{"CN", "Simple"}}; 0056 QTest::newRow("CN=Name with spaces") << std::string {"CN=Name with spaces"} << DN::Result {{"CN", "Name with spaces"}}; 0057 QTest::newRow("CN=Simple,O=Silly") << std::string {"CN=Simple,O=Silly"} << DN::Result {{"CN", "Simple"}, {"O", "Silly"}}; 0058 QTest::newRow("CN=Steve Kille,O=Isode Limited,C=GB") << std::string {"CN=Steve Kille,O=Isode Limited,C=GB"} << DN::Result {{"CN", "Steve Kille"}, {"O", "Isode Limited"}, {"C", "GB"}}; 0059 QTest::newRow("CN=some.user@example.com, O=MyCompany, L=San Diego,ST=California, C=US") 0060 << std::string {"CN=some.user@example.com, O=MyCompany, L=San Diego,ST=California, C=US"} << DN::Result {{"CN", "some.user@example.com"}, {"O", "MyCompany"}, {"L", "San Diego"}, {"ST", "California"}, {"C", "US"}}; 0061 QTest::newRow("Multi valued") << std::string {"OU=Sales+CN=J. Smith,O=Widget Inc.,C=US"} 0062 << DN::Result {{"OU", "Sales"}, {"CN", "J. Smith"}, {"O", "Widget Inc."}, {"C", "US"}}; // This is technically wrong, but probably good enough for now 0063 QTest::newRow("Escaping comma") << std::string {"CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB"} << DN::Result {{"CN", "L. Eagle"}, {"O", "Sue, Grabbit and Runn"}, {"C", "GB"}}; 0064 QTest::newRow("Escaped trailing space") << std::string {"CN=Trailing space\\ "} << DN::Result {{"CN", "Trailing space "}}; 0065 QTest::newRow("Escaped quote") << std::string {"CN=Quotation \\\" Mark"} << DN::Result {{"CN", "Quotation \" Mark"}}; 0066 0067 QTest::newRow("CN=Simple with escaping") << std::string {"CN=S\\69mpl\\65\\7A"} << DN::Result {{"CN", "Simplez"}}; 0068 QTest::newRow("SN=Lu\\C4\\8Di\\C4\\87") << std::string {"SN=Lu\\C4\\8Di\\C4\\87"} << DN::Result {{"SN", "Lučić"}}; 0069 QTest::newRow("CN=\"Quoted name\"") << std::string {"CN=\"Quoted name\""} << DN::Result {{"CN", "Quoted name"}}; 0070 QTest::newRow("CN=\" Leading and trailing spacees \"") << std::string {"CN=\" Leading and trailing spaces \""} << DN::Result {{"CN", " Leading and trailing spaces "}}; 0071 QTest::newRow("Comma in quotes") << std::string {"CN=\"Comma, inside\""} << DN::Result {{"CN", "Comma, inside"}}; 0072 QTest::newRow("forbidden chars in quotes") << std::string {"CN=\"Forbidden !@#$%&*()<>[]{},.?/\\| chars\""} << DN::Result {{"CN", "Forbidden !@#$%&*()<>[]{},.?/\\| chars"}}; 0073 QTest::newRow("Quoted quotation") << std::string {"CN=\"Quotation \\\" Mark\""} << DN::Result {{"CN", "Quotation \" Mark"}}; 0074 QTest::newRow("Quoted quotation") << std::string {"CN=\"Quotation \\\" Mark\\\" Multiples\""} << DN::Result {{"CN", "Quotation \" Mark\" Multiples"}}; 0075 0076 QTest::newRow("frompdf1") << std::string {"2.5.4.97=#5553742D49644E722E20444520313233343735323233,CN=TeleSec PKS eIDAS QES CA 5,O=Deutsche Telekom AG,C=DE"} 0077 << DN::Result {{"2.5.4.97", "USt-IdNr. DE 123475223"}, {"CN", "TeleSec PKS eIDAS QES CA 5"}, {"O", "Deutsche Telekom AG"}, {"C", "DE"}}; 0078 QTest::newRow("frompdf2") << std::string {"2.5.4.5=#34,CN=Koch\\, Werner,2.5.4.42=#5765726E6572,2.5.4.4=#4B6F6368,C=DE"} << DN::Result {{"SerialNumber", "4"}, {"CN", "Koch, Werner"}, {"GN", "Werner"}, {"SN", "Koch"}, {"C", "DE"}}; 0079 QTest::newRow("frompdf2a") << std::string {"2.5.4.5=#34,CN=Koch\\, Werner,oid.2.5.4.42=#5765726E6572,OID.2.5.4.4=#4B6F6368,C=DE"} 0080 << DN::Result {{"SerialNumber", "4"}, {"CN", "Koch, Werner"}, {"GN", "Werner"}, {"SN", "Koch"}, {"C", "DE"}}; 0081 0082 // weird spacing 0083 QTest::newRow("CN =Simple") << std::string {"CN =Simple"} << DN::Result {{"CN", "Simple"}}; 0084 QTest::newRow("CN= Simple") << std::string {"CN= Simple"} << DN::Result {{"CN", "Simple"}}; 0085 QTest::newRow("CN=Simple ") << std::string {"CN=Simple "} << DN::Result {{"CN", "Simple"}}; 0086 QTest::newRow("CN=Simple,") << std::string {"CN=Simple,"} << DN::Result {{"CN", "Simple"}}; 0087 QTest::newRow("CN=Simple, O=Silly") << std::string {"CN=Simple, O=Silly"} << DN::Result {{"CN", "Simple"}, {"O", "Silly"}}; 0088 0089 // various malformed 0090 QTest::newRow("CN=Simple\\") << std::string {"CN=Simple\\"} << DN::Result {}; 0091 QTest::newRow("CN=") << std::string {"CN="} << DN::Result {}; 0092 QTest::newRow("CN=Simple\\X") << std::string {"CN=Simple\\X"} << DN::Result {}; 0093 QTest::newRow("CN=Simple, O") << std::string {"CN=Simple, O"} << DN::Result {}; 0094 QTest::newRow("CN=Sim\"ple") << std::string {"CN=Sim\"ple, O"} << DN::Result {}; 0095 QTest::newRow("CN=Simple\\a") << std::string {"CN=Simple\\a"} << DN::Result {}; 0096 QTest::newRow("=Simple") << std::string {"=Simple"} << DN::Result {}; 0097 QTest::newRow("CN=\"Simple") << std::string {"CN=\"Simple"} << DN::Result {}; 0098 QTest::newRow("CN=\"Simple") << std::string {"CN=\"Simple\\"} << DN::Result {}; 0099 QTest::newRow("unquoted quotation in quotation") << std::string {"CN=\"Quotation \" Mark\""} << DN::Result {}; 0100 } 0101 0102 void TestDistinguishedNameParser::testRemoveLeadingSpaces() 0103 { 0104 QFETCH(std::string, input); 0105 QFETCH(std::string, expectedOutput); 0106 0107 auto result = DN::detail::removeLeadingSpaces(input); 0108 QCOMPARE(result, expectedOutput); 0109 } 0110 void TestDistinguishedNameParser::testRemoveLeadingSpaces_data() 0111 { 0112 QTest::addColumn<std::string>("input"); 0113 QTest::addColumn<std::string>("expectedOutput"); 0114 0115 QTest::newRow("Empty") << std::string {} << std::string {}; 0116 QTest::newRow("No leading spaces") << std::string {"horse"} << std::string {"horse"}; 0117 QTest::newRow("Some spaces") << std::string {" horse"} << std::string {"horse"}; 0118 QTest::newRow("Some leading and trailing") << std::string {" horse "} << std::string {"horse "}; 0119 } 0120 0121 void TestDistinguishedNameParser::testRemoveTrailingSpaces() 0122 { 0123 QFETCH(std::string, input); 0124 QFETCH(std::string, expectedOutput); 0125 0126 auto result = DN::detail::removeTrailingSpaces(input); 0127 QCOMPARE(result, expectedOutput); 0128 } 0129 void TestDistinguishedNameParser::testRemoveTrailingSpaces_data() 0130 { 0131 QTest::addColumn<std::string>("input"); 0132 QTest::addColumn<std::string>("expectedOutput"); 0133 0134 QTest::newRow("Empty") << std::string {} << std::string {}; 0135 QTest::newRow("No leading spaces") << std::string {"horse"} << std::string {"horse"}; 0136 QTest::newRow("Some spaces") << std::string {"horse "} << std::string {"horse"}; 0137 QTest::newRow("Some leading and trailing") << std::string {" horse "} << std::string {" horse"}; 0138 } 0139 0140 void TestDistinguishedNameParser::testParseHexString() 0141 { 0142 QFETCH(std::string, input); 0143 QFETCH(std::optional<std::string>, expectedOutput); 0144 0145 auto result = DN::detail::parseHexString(input); 0146 QCOMPARE(result, expectedOutput); 0147 } 0148 0149 void TestDistinguishedNameParser::testParseHexString_data() 0150 { 0151 QTest::addColumn<std::string>("input"); 0152 QTest::addColumn<std::optional<std::string>>("expectedOutput"); 0153 0154 QTest::newRow("4") << std::string {"34"} << std::optional<std::string>("4"); 0155 QTest::newRow("Koch") << std::string {"4B6F6368"} << std::optional<std::string>("Koch"); 0156 QTest::newRow("USt-IdNr. DE 123475223") << std::string {"5553742D49644E722E20444520313233343735323233"} << std::optional<std::string>("USt-IdNr. DE 123475223"); 0157 0158 // various baddies 0159 QTest::newRow("empty") << std::string {} << std::optional<std::string> {}; 0160 QTest::newRow("FFF") << std::string {"FFF"} << std::optional<std::string> {}; 0161 QTest::newRow("F") << std::string {"F"} << std::optional<std::string> {}; 0162 QTest::newRow("XX") << std::string {"XX"} << std::optional<std::string> {}; 0163 } 0164 0165 QTEST_GUILESS_MAIN(TestDistinguishedNameParser); 0166 #include "check_distinguished_name_parser.moc"