File indexing completed on 2024-11-24 04:44:41

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 #include "khealthcertificateparser.h"
0007 #include "divoc/divocparser_p.h"
0008 #include "eu-dgc/eudgcparser_p.h"
0009 #include "icao/icaovdsparser_p.h"
0010 #include "nl-coronacheck/nlcoronacheckparser_p.h"
0011 #include "shc/shcparser_p.h"
0012 
0013 #include <KZip>
0014 
0015 #include <QBuffer>
0016 #include <QByteArray>
0017 #include <QVariant>
0018 
0019 static bool initResources()
0020 {
0021     DivocParser::init();
0022     EuDgcParser::init();
0023     IcaoVdsParser::init();
0024     NLCoronaCheckParser::init();
0025     ShcParser::init();
0026 
0027     return true;
0028 }
0029 
0030 QVariant KHealthCertificateParser::parse(const QByteArray &data)
0031 {
0032     [[maybe_unused]] static bool s_init = initResources();
0033 
0034     EuDgcParser eudcg;
0035     auto result = eudcg.parse(data);
0036     if (!result.isNull()) {
0037         return result;
0038     }
0039     result = DivocParser::parse(data);
0040     if (!result.isNull()) {
0041         return result;
0042     }
0043     result = ShcParser::parse(data);
0044     if (!result.isNull()) {
0045         return result;
0046     }
0047     result = IcaoVdsParser::parse(data);
0048     if (!result.isNull()) {
0049         return result;
0050     }
0051     result = NLCoronaCheckParser::parse(data);
0052     if (!result.isNull()) {
0053         return result;
0054     }
0055 
0056     // ZIP unpacking (needed for Indian certificates)
0057     if (data.startsWith(QByteArray("\x50\x4B\x03\x04"))) {
0058         QBuffer buffer;
0059         buffer.setData(data);
0060         buffer.open(QIODevice::ReadOnly);
0061         KZip zip(&buffer);
0062         if (!zip.open(QIODevice::ReadOnly)) {
0063             return {};
0064         }
0065         const auto entries = zip.directory()->entries();
0066         for (const auto &entry : entries) {
0067             if (auto f = zip.directory()->file(entry)) {
0068                 result = parse(f->data());
0069                 if (!result.isNull()) {
0070                     auto vac = result.value<KVaccinationCertificate>();
0071                     vac.setRawData(data);
0072                     return vac;
0073                 }
0074             }
0075         }
0076 
0077     }
0078 
0079     return {};
0080 }