summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-07-13 12:04:40 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-14 03:20:25 +0200
commitcc741597021dd5e9c7ca2caffaf8a15181f68e89 (patch)
tree5269f5485422717baedfc651af5decbe5a8b5875 /src
parent3154e1ccaabfbdb42aa48cbb5805b23442cdc33e (diff)
Base64: Implement the "base64url" encoding and the stripping of '='
The "base64url" encoding is defined in RFC 4648, which is the newest version of Base64. There are also a few situations where the ending '=' is not desired. Change-Id: I9bb9fa55817b57d125189e4e795d6fde97caea6d Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp13
-rw-r--r--src/corelib/doc/src/external-resources.qdoc5
-rw-r--r--src/corelib/tools/qbytearray.cpp95
-rw-r--r--src/corelib/tools/qbytearray.h17
4 files changed, 116 insertions, 14 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index c2a375f498..003fce580b 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -352,6 +352,14 @@ QByteArray text("Qt is great!");
text.toBase64(); // returns "UXQgaXMgZ3JlYXQh"
//! [39]
+//! [39bis]
+QByteArray text("<p>Hello?</p>");
+text.toBase64(QByteArray::Base64 | QByteArray::OmitTrailingEquals); // returns "PHA+SGVsbG8/PC9wPg"
+text.toBase64(QByteArray::Base64); // returns "PHA+SGVsbG8/PC9wPg=="
+text.toBase64(QByteArray::Base64Url); // returns "PHA-SGVsbG8_PC9wPg=="
+text.toBase64(QByteArray::Base64Url | QByteArray::OmitTrailingEquals); // returns "PHA-SGVsbG8_PC9wPg"
+//! [39bis]
+
//! [40]
QByteArray ba;
@@ -394,6 +402,11 @@ QByteArray text = QByteArray::fromBase64("UXQgaXMgZ3JlYXQh");
text.data(); // returns "Qt is great!"
//! [44]
+//! [44bis]
+QByteArray::fromBase64("PHA+SGVsbG8/PC9wPg==", QByteArray::Base64Encoding); // returns "<p>Hello?</p>"
+QByteArray::fromBase64("PHA-SGVsbG8_PC9wPg==", QByteArray::Base64UrlEncoding); // returns "<p>Hello?</p>"
+//! [44bis]
+
//! [45]
QByteArray text = QByteArray::fromHex("517420697320677265617421");
diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc
index 86df385d9e..d1c7eb5d1b 100644
--- a/src/corelib/doc/src/external-resources.qdoc
+++ b/src/corelib/doc/src/external-resources.qdoc
@@ -67,6 +67,11 @@
*/
/*!
+ \externalpage http://www.ietf.org/rfc/rfc4648.txt
+ \title RFC 4648
+*/
+
+/*!
\externalpage http://www.iana.org/assignments/character-sets/character-sets.xml
\title IANA character-sets encoding file
*/
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 7ec7333054..975894a516 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -795,6 +795,27 @@ static inline char qToLower(char c)
\sa QString, QBitArray
*/
+/*!
+ \enum QByteArray::Base64Option
+ \since 5.2
+
+ This enum contains the options available for encoding and decoding Base64.
+ Base64 is defined by \l{RFC 4648}, with the following options:
+
+ \value Base64Encoding (default) The regular Base64 alphabet, called simply "base64"
+ \value Base64UrlEncoding An alternate alphabet, called "base64url", which replaces two
+ characters in the alphabet to be more friendly to URLs.
+ \value KeepTrailingEquals (default) Keeps the trailing padding equal signs at the end
+ of the encoded data, so the data is always a size multiple of
+ four.
+ \value OmitTrailingEquals Omits adding the padding equal signs at the end of the encoded
+ data.
+
+ QByteArray::fromBase64() ignores the KeepTrailingEquals and
+ OmitTrailingEquals options and will not flag errors in case they are
+ missing or if there are too many of them.
+*/
+
/*! \fn QByteArray::iterator QByteArray::begin()
\internal
@@ -3539,14 +3560,34 @@ float QByteArray::toFloat(bool *ok) const
\snippet code/src_corelib_tools_qbytearray.cpp 39
- The algorithm used to encode Base64-encoded data is defined in \l{RFC 2045}.
+ The algorithm used to encode Base64-encoded data is defined in \l{RFC 4648}.
\sa fromBase64()
*/
QByteArray QByteArray::toBase64() const
{
- const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
- "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
+ return toBase64(Base64Encoding);
+}
+
+/*!
+ \since 5.2
+ \overload
+
+ Returns a copy of the byte array, encoded using the options \a options.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 39bis
+
+ The algorithm used to encode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa fromBase64()
+*/
+QByteArray QByteArray::toBase64(Base64Options options) const
+{
+ const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+ "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
+ const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+ "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
+ const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
const char padchar = '=';
int padlen = 0;
@@ -3575,14 +3616,18 @@ QByteArray QByteArray::toBase64() const
*out++ = alphabet[j];
*out++ = alphabet[k];
- if (padlen > 1)
- *out++ = padchar;
- else
+ if (padlen > 1) {
+ if ((options & OmitTrailingEquals) == 0)
+ *out++ = padchar;
+ } else {
*out++ = alphabet[l];
- if (padlen > 0)
- *out++ = padchar;
- else
+ }
+ if (padlen > 0) {
+ if ((options & OmitTrailingEquals) == 0)
+ *out++ = padchar;
+ } else {
*out++ = alphabet[m];
+ }
}
tmp.truncate(out - tmp.data());
@@ -3941,12 +3986,34 @@ QByteArray &QByteArray::setRawData(const char *data, uint size)
\snippet code/src_corelib_tools_qbytearray.cpp 44
- The algorithm used to decode Base64-encoded data is defined in \l{RFC 2045}.
+ The algorithm used to decode Base64-encoded data is defined in \l{RFC 4648}.
\sa toBase64()
*/
QByteArray QByteArray::fromBase64(const QByteArray &base64)
{
+ return fromBase64(base64, Base64Encoding);
+}
+
+/*!
+ \since 5.2
+ \overload
+
+ Returns a decoded copy of the Base64 array \a base64, using the alphabet
+ defined by \a options. Input is not checked for validity; invalid
+ characters in the input are skipped, enabling the decoding process to
+ continue with subsequent characters.
+
+ For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 44bis
+
+ The algorithm used to decode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa toBase64()
+*/
+QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
+{
unsigned int buf = 0;
int nbits = 0;
QByteArray tmp((base64.size() * 3) / 4, Qt::Uninitialized);
@@ -3962,9 +4029,13 @@ QByteArray QByteArray::fromBase64(const QByteArray &base64)
d = ch - 'a' + 26;
else if (ch >= '0' && ch <= '9')
d = ch - '0' + 52;
- else if (ch == '+')
+ else if (ch == '+' && (options & Base64UrlEncoding) == 0)
d = 62;
- else if (ch == '/')
+ else if (ch == '-' && (options & Base64UrlEncoding) != 0)
+ d = 62;
+ else if (ch == '/' && (options & Base64UrlEncoding) == 0)
+ d = 63;
+ else if (ch == '_' && (options & Base64UrlEncoding) != 0)
d = 63;
else
d = -1;
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 85d1f0ab90..ae8166db81 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -173,6 +173,15 @@ private:
typedef QTypedArrayData<char> Data;
public:
+ enum Base64Option {
+ Base64Encoding = 0,
+ Base64UrlEncoding = 1,
+
+ KeepTrailingEquals = 0,
+ OmitTrailingEquals = 2
+ };
+ Q_DECLARE_FLAGS(Base64Options, Base64Option)
+
inline QByteArray();
QByteArray(const char *, int size = -1);
QByteArray(int size, char c);
@@ -317,7 +326,8 @@ public:
qulonglong toULongLong(bool *ok = 0, int base = 10) const;
float toFloat(bool *ok = 0) const;
double toDouble(bool *ok = 0) const;
- QByteArray toBase64() const;
+ QByteArray toBase64(Base64Options options) const;
+ QByteArray toBase64() const; // ### Qt6 merge with previous
QByteArray toHex() const;
QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
const QByteArray &include = QByteArray(),
@@ -339,7 +349,8 @@ public:
static QByteArray number(qulonglong, int base = 10);
static QByteArray number(double, char f = 'g', int prec = 6);
static QByteArray fromRawData(const char *, int size);
- static QByteArray fromBase64(const QByteArray &base64);
+ static QByteArray fromBase64(const QByteArray &base64, Base64Options options);
+ static QByteArray fromBase64(const QByteArray &base64); // ### Qt6 merge with previous
static QByteArray fromHex(const QByteArray &hexEncoded);
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
@@ -392,6 +403,8 @@ public:
inline DataPtr &data_ptr() { return d; }
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
+
inline QByteArray::QByteArray(): d(Data::sharedNull()) { }
inline QByteArray::~QByteArray() { if (!d->ref.deref()) Data::deallocate(d); }
inline int QByteArray::size() const