From c82dd728746f3df9ededdd3beb651dd97449c6d2 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 18 Jan 2016 12:41:54 +0100 Subject: Fix SSID decoding Allocate sufficient buffer size. Change-Id: Id2c885d132814553a93b9baa026fa044d667527b Task-number: QTEE-1038 Reviewed-by: Teemu Holappa --- src/wifi/qwifimanager.cpp | 4 +-- src/wifi/qwifinetworklistmodel.cpp | 2 +- src/wifi/qwifisupplicant.cpp | 70 ++++++++++++++++++++------------------ src/wifi/qwifisupplicant_p.h | 4 +-- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/wifi/qwifimanager.cpp b/src/wifi/qwifimanager.cpp index 6bace8f..6f733ba 100644 --- a/src/wifi/qwifimanager.cpp +++ b/src/wifi/qwifimanager.cpp @@ -68,7 +68,7 @@ void QWifiManagerPrivate::handleAuthenticating(QWifiEvent *event) QString ssid = data.mid(data.indexOf(QLatin1String("SSID")) + 6); ssid = ssid.left(ssid.lastIndexOf(QLatin1Char('\''))); - setCurrentSSID(QWifiSupplicant::decodeHexEncoded(ssid)); + setCurrentSSID(QWifiSupplicant::decodeSsid(ssid)); updateNetworkState(QWifiManager::Authenticating); } @@ -425,7 +425,7 @@ bool QWifiManager::connect(QWifiConfiguration *config) const QStringList configuredNetworks = d->call(QStringLiteral("LIST_NETWORKS")).split('\n'); for (int i = 1; i < configuredNetworks.length(); ++i) { const QStringList networkFields = configuredNetworks.at(i).split('\t'); - const QString ssid = QWifiSupplicant::decodeHexEncoded(networkFields.at(1)); + const QString ssid = QWifiSupplicant::decodeSsid(networkFields.at(1)); if (ssid == d->m_currentSSID) { id = networkFields.at(0); networkKnown = true; diff --git a/src/wifi/qwifinetworklistmodel.cpp b/src/wifi/qwifinetworklistmodel.cpp index a1f825f..fa3f7dc 100644 --- a/src/wifi/qwifinetworklistmodel.cpp +++ b/src/wifi/qwifinetworklistmodel.cpp @@ -124,7 +124,7 @@ void QWifiNetworkListModel::parseScanResults(const QString &results) continue; int pos = 0; - QString ssid = QWifiSupplicant::decodeHexEncoded(info.at(4)); + QString ssid = QWifiSupplicant::decodeSsid(info.at(4)); if (ssid.isEmpty()) continue; diff --git a/src/wifi/qwifisupplicant.cpp b/src/wifi/qwifisupplicant.cpp index 7b303ed..b2ec497 100644 --- a/src/wifi/qwifisupplicant.cpp +++ b/src/wifi/qwifisupplicant.cpp @@ -300,22 +300,32 @@ int QWifiSupplicant::receiveEvent(char *reply, size_t *reply_len) return -2; } -/*! \internal - * - Decode wpa_supplicant encoded string, see file hostapd/src/utils/common.c - in git://w1.fi/hostap.git repository. +static inline int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} - For Ascii encoded string, any octet < 32 or > 127 is encoded as a "\\x" - followed by the hex representation of the octet. Exception chars are ", - \\, \\e, \\n, \\r, \\t which are escaped by a backslash +static inline int hex2byte(const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} - */ -QString QWifiSupplicant::decodeHexEncoded(const QString &encoded) +static inline int printf_decode(char *buf, int maxlen, const char *str) { - int maxlen = encoded.size() + 1; - QByteArray buf; - buf.resize(maxlen); - const char *pos = encoded.toLocal8Bit().constData(); + const char *pos = str; int len = 0; int val; @@ -391,30 +401,24 @@ QString QWifiSupplicant::decodeHexEncoded(const QString &encoded) if (maxlen > len) buf[len] = '\0'; - return QString::fromUtf8(buf); + return len; } -int QWifiSupplicant::hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} +/*! \internal + * + Decode wpa_supplicant encoded string, see file hostapd/src/utils/common.c + in git://w1.fi/hostap.git repository. -int QWifiSupplicant::hex2byte(const char *hex) + For Ascii encoded string, any octet < 32 or > 127 is encoded as a "\\x" + followed by the hex representation of the octet. Exception chars are ", + \\, \\e, \\n, \\r, \\t which are escaped by a backslash + + */ +QString QWifiSupplicant::decodeSsid(const QString &encoded) { - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; + static char ssid[2048]; + printf_decode(ssid, sizeof(ssid), encoded.toLatin1().constData()); + return QString::fromUtf8(ssid); } QT_END_NAMESPACE diff --git a/src/wifi/qwifisupplicant_p.h b/src/wifi/qwifisupplicant_p.h index f904925..3b18380 100644 --- a/src/wifi/qwifisupplicant_p.h +++ b/src/wifi/qwifisupplicant_p.h @@ -43,12 +43,10 @@ public: void closeSupplicantConnection(); int waitForEvent(char *buf, size_t buflen); bool sendCommand(const QString &command, QByteArray *reply); - static QString decodeHexEncoded(const QString &encoded); + static QString decodeSsid(const QString &encoded); protected: int receiveEvent(char *reply, size_t *reply_len); - static int hex2num(char c); - static int hex2byte(const char *hex); private: wpa_ctrl *ctrl_conn; -- cgit v1.2.3