Merge remote-tracking branch 'origin/master' into refactor
Change-Id: I53c78056abde99198ffe1c67f7f9e90b4b08051dbb10
commit
a81093b915
|
|
@ -540,6 +540,7 @@ namespace QT_NAMESPACE {}
|
|||
# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
|
||||
# define Q_COMPILER_CLASS_ENUM
|
||||
# define Q_COMPILER_INITIALIZER_LISTS
|
||||
# define Q_COMPILER_ATOMICS
|
||||
# endif
|
||||
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
|
||||
/* C++0x features supported in GCC 4.5: */
|
||||
|
|
@ -547,7 +548,10 @@ namespace QT_NAMESPACE {}
|
|||
# endif
|
||||
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
/* C++0x features supported in GCC 4.6: */
|
||||
# define Q_COMPILER_NULLPTR
|
||||
# define Q_COMPILER_CONSTEXPR
|
||||
# define Q_COMPILER_UNRESTRICTED_UNIONS
|
||||
# define Q_COMPILER_RANGE_FOR
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
|
@ -799,11 +803,10 @@ namespace QT_NAMESPACE {}
|
|||
# define Q_NO_TEMPLATE_FRIENDS
|
||||
# endif
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
|
||||
# if __INTEL_COMPILER >= 1100
|
||||
# if __INTEL_COMPILER >= 1200
|
||||
# define Q_COMPILER_RVALUE_REFS
|
||||
# define Q_COMPILER_EXTERN_TEMPLATES
|
||||
# define Q_COMPILER_DECLTYPE
|
||||
# elif __INTEL_COMPILER >= 1200
|
||||
# define Q_COMPILER_VARIADIC_TEMPLATES
|
||||
# define Q_COMPILER_AUTO_TYPE
|
||||
# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
|
||||
|
|
@ -1114,6 +1117,12 @@ redefine to built-in booleans to make autotests work properly */
|
|||
# define QT_FASTCALL
|
||||
#endif
|
||||
|
||||
#ifdef Q_COMPILER_NULLPTR
|
||||
# define Q_NULLPTR nullptr
|
||||
#else
|
||||
# define Q_NULLPTR 0
|
||||
#endif
|
||||
|
||||
#ifdef Q_COMPILER_CONSTEXPR
|
||||
# define Q_DECL_CONSTEXPR constexpr
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define IS_RAW_DATA(d) ((d)->data != (d)->array)
|
||||
#define IS_RAW_DATA(d) ((d)->offset != 0)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -546,7 +546,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
qWarning("qUncompress: Input data is corrupted");
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc));
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc + 1));
|
||||
if (!p) {
|
||||
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
|
||||
qWarning("qUncompress: could not allocate enough memory to uncompress data");
|
||||
|
|
@ -554,8 +554,9 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
}
|
||||
d.take(); // realloc was successful
|
||||
d.reset(p);
|
||||
d->offset = 0;
|
||||
|
||||
int res = ::uncompress((uchar*)d->array, &len,
|
||||
int res = ::uncompress((uchar*)d->data(), &len,
|
||||
(uchar*)data+4, nbytes-4);
|
||||
|
||||
switch (res) {
|
||||
|
|
@ -566,7 +567,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
qWarning("qUncompress: Input data is corrupted");
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len));
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len + 1));
|
||||
if (!p) {
|
||||
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
|
||||
qWarning("qUncompress: could not allocate enough memory to uncompress data");
|
||||
|
|
@ -576,9 +577,11 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
d.reset(p);
|
||||
}
|
||||
d->ref = 1;
|
||||
d->alloc = d->size = len;
|
||||
d->data = d->array;
|
||||
d->array[len] = 0;
|
||||
d->size = len;
|
||||
d->alloc = len;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[len] = 0;
|
||||
|
||||
return QByteArray(d.take(), 0, 0);
|
||||
|
||||
|
|
@ -611,10 +614,10 @@ static inline char qToLower(char c)
|
|||
return c;
|
||||
}
|
||||
|
||||
QByteArray::Data QByteArray::shared_null = {Q_BASIC_ATOMIC_INITIALIZER(1),
|
||||
0, 0, shared_null.array, {0} };
|
||||
QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
|
||||
0, 0, shared_empty.array, {0} };
|
||||
QConstByteArrayData<1> QByteArray::shared_null = { { Q_REFCOUNT_INITIALIZER(-1),
|
||||
0, 0, 0, { 0 } }, { 0 } };
|
||||
QConstByteArrayData<1> QByteArray::shared_empty = { { Q_REFCOUNT_INITIALIZER(-1),
|
||||
0, 0, 0, { 0 } }, { 0 } };
|
||||
|
||||
/*!
|
||||
\class QByteArray
|
||||
|
|
@ -896,15 +899,15 @@ QByteArray &QByteArray::operator=(const char *str)
|
|||
{
|
||||
Data *x;
|
||||
if (!str) {
|
||||
x = &shared_null;
|
||||
x = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!*str) {
|
||||
x = &shared_empty;
|
||||
x = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
int len = qstrlen(str);
|
||||
if (d->ref != 1 || len > d->alloc || (len < d->size && len < d->alloc >> 1))
|
||||
realloc(len);
|
||||
x = d;
|
||||
memcpy(x->data, str, len + 1); // include null terminator
|
||||
memcpy(x->data(), str, len + 1); // include null terminator
|
||||
x->size = len;
|
||||
}
|
||||
x->ref.ref();
|
||||
|
|
@ -1294,19 +1297,20 @@ void QByteArray::chop(int n)
|
|||
QByteArray::QByteArray(const char *str)
|
||||
{
|
||||
if (!str) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!*str) {
|
||||
d = &shared_empty;
|
||||
d = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
int len = qstrlen(str);
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+len));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + len + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;;
|
||||
d->alloc = d->size = len;
|
||||
d->data = d->array;
|
||||
memcpy(d->array, str, len+1); // include null terminator
|
||||
d->ref = 1;
|
||||
d->size = len;
|
||||
d->alloc = len;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), str, len+1); // include null terminator
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1323,19 +1327,20 @@ QByteArray::QByteArray(const char *str)
|
|||
QByteArray::QByteArray(const char *data, int size)
|
||||
{
|
||||
if (!data) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (size <= 0) {
|
||||
d = &shared_empty;
|
||||
d = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
memcpy(d->array, data, size);
|
||||
d->array[size] = '\0';
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), data, size);
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1348,17 +1353,18 @@ QByteArray::QByteArray(const char *data, int size)
|
|||
QByteArray::QByteArray(int size, char ch)
|
||||
{
|
||||
if (size <= 0) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else {
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
d->array[size] = '\0';
|
||||
memset(d->array, ch, size);
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memset(d->data(), ch, size);
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1369,12 +1375,14 @@ QByteArray::QByteArray(int size, char ch)
|
|||
|
||||
QByteArray::QByteArray(int size, Qt::Initialization)
|
||||
{
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 1;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
d->array[size] = '\0';
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1392,13 +1400,20 @@ QByteArray::QByteArray(int size, Qt::Initialization)
|
|||
|
||||
void QByteArray::resize(int size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
Data *x = &shared_empty;
|
||||
x->ref.ref();
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
|
||||
if (d->offset && d->ref == 1 && size < d->size) {
|
||||
d->size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 0 && !d->capacityReserved) {
|
||||
Data *x = const_cast<Data *>(&shared_empty.ba);
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = x;
|
||||
} else if (d == &shared_null) {
|
||||
} else if (d == &shared_null.ba || d == &shared_empty.ba) {
|
||||
//
|
||||
// Optimize the idiom:
|
||||
// QByteArray a;
|
||||
|
|
@ -1407,22 +1422,21 @@ void QByteArray::resize(int size)
|
|||
// which is used in place of the Qt 3 idiom:
|
||||
// QByteArray a(sz);
|
||||
//
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->ref = 1;
|
||||
x->alloc = x->size = size;
|
||||
x->data = x->array;
|
||||
x->array[size] = '\0';
|
||||
(void) d->ref.deref(); // cannot be 0, x points to shared_null
|
||||
x->size = size;
|
||||
x->alloc = size;
|
||||
x->capacityReserved = false;
|
||||
x->offset = 0;
|
||||
x->data()[size] = '\0';
|
||||
d = x;
|
||||
} else {
|
||||
if (d->ref != 1 || size > d->alloc || (size < d->size && size < d->alloc >> 1))
|
||||
if (d->ref != 1 || size > d->alloc || (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
|
||||
realloc(qAllocMore(size, sizeof(Data)));
|
||||
if (d->alloc >= size) {
|
||||
d->size = size;
|
||||
if (d->data == d->array) {
|
||||
d->array[size] = '\0';
|
||||
}
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1442,29 +1456,30 @@ QByteArray &QByteArray::fill(char ch, int size)
|
|||
{
|
||||
resize(size < 0 ? d->size : size);
|
||||
if (d->size)
|
||||
memset(d->data, ch, d->size);
|
||||
memset(d->data(), ch, d->size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void QByteArray::realloc(int alloc)
|
||||
{
|
||||
if (d->ref != 1 || d->data != d->array) {
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc));
|
||||
if (d->ref != 1 || d->offset) {
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->size = qMin(alloc, d->size);
|
||||
::memcpy(x->array, d->data, x->size);
|
||||
x->array[x->size] = '\0';
|
||||
x->ref = 1;
|
||||
x->size = qMin(alloc, d->size);
|
||||
x->alloc = alloc;
|
||||
x->data = x->array;
|
||||
x->capacityReserved = d->capacityReserved;
|
||||
x->offset = 0;
|
||||
::memcpy(x->data(), d->data(), x->size);
|
||||
x->data()[x->size] = '\0';
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = x;
|
||||
} else {
|
||||
Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc));
|
||||
Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->alloc = alloc;
|
||||
x->data = x->array;
|
||||
x->offset = 0;
|
||||
d = x;
|
||||
}
|
||||
}
|
||||
|
|
@ -1486,7 +1501,7 @@ void QByteArray::expand(int i)
|
|||
QByteArray QByteArray::nulTerminated() const
|
||||
{
|
||||
// is this fromRawData?
|
||||
if (d->data == d->array)
|
||||
if (!d->offset)
|
||||
return *this; // no, then we're sure we're zero terminated
|
||||
|
||||
QByteArray copy(*this);
|
||||
|
|
@ -1517,9 +1532,9 @@ QByteArray QByteArray::nulTerminated() const
|
|||
|
||||
QByteArray &QByteArray::prepend(const QByteArray &ba)
|
||||
{
|
||||
if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
|
||||
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d != &shared_null) {
|
||||
} else if (ba.d != &shared_null.ba) {
|
||||
QByteArray tmp = *this;
|
||||
*this = ba;
|
||||
append(tmp);
|
||||
|
|
@ -1550,10 +1565,10 @@ QByteArray &QByteArray::prepend(const char *str, int len)
|
|||
if (str) {
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memmove(d->data+len, d->data, d->size);
|
||||
memcpy(d->data, str, len);
|
||||
memmove(d->data()+len, d->data(), d->size);
|
||||
memcpy(d->data(), str, len);
|
||||
d->size += len;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1568,10 +1583,10 @@ QByteArray &QByteArray::prepend(char ch)
|
|||
{
|
||||
if (d->ref != 1 || d->size + 1 > d->alloc)
|
||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||
memmove(d->data+1, d->data, d->size);
|
||||
d->data[0] = ch;
|
||||
memmove(d->data()+1, d->data(), d->size);
|
||||
d->data()[0] = ch;
|
||||
++d->size;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1601,14 +1616,14 @@ QByteArray &QByteArray::prepend(char ch)
|
|||
|
||||
QByteArray &QByteArray::append(const QByteArray &ba)
|
||||
{
|
||||
if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
|
||||
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d != &shared_null) {
|
||||
} else if (ba.d != &shared_null.ba) {
|
||||
if (d->ref != 1 || d->size + ba.d->size > d->alloc)
|
||||
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
|
||||
memcpy(d->data + d->size, ba.d->data, ba.d->size);
|
||||
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
|
||||
d->size += ba.d->size;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1640,7 +1655,7 @@ QByteArray& QByteArray::append(const char *str)
|
|||
int len = qstrlen(str);
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memcpy(d->data + d->size, str, len + 1); // include null terminator
|
||||
memcpy(d->data() + d->size, str, len + 1); // include null terminator
|
||||
d->size += len;
|
||||
}
|
||||
return *this;
|
||||
|
|
@ -1665,9 +1680,9 @@ QByteArray &QByteArray::append(const char *str, int len)
|
|||
if (str && len) {
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memcpy(d->data + d->size, str, len); // include null terminator
|
||||
memcpy(d->data() + d->size, str, len); // include null terminator
|
||||
d->size += len;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1682,8 +1697,8 @@ QByteArray& QByteArray::append(char ch)
|
|||
{
|
||||
if (d->ref != 1 || d->size + 1 > d->alloc)
|
||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||
d->data[d->size++] = ch;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size++] = ch;
|
||||
d->data()[d->size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1724,7 +1739,7 @@ static inline QByteArray &qbytearray_insert(QByteArray *ba,
|
|||
QByteArray &QByteArray::insert(int i, const QByteArray &ba)
|
||||
{
|
||||
QByteArray copy(ba);
|
||||
return qbytearray_insert(this, i, copy.d->data, copy.d->size);
|
||||
return qbytearray_insert(this, i, copy.d->data(), copy.d->size);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1812,7 +1827,7 @@ QByteArray &QByteArray::remove(int pos, int len)
|
|||
if (pos + len >= d->size) {
|
||||
resize(pos);
|
||||
} else {
|
||||
memmove(d->data + pos, d->data + pos + len, d->size - pos - len);
|
||||
memmove(d->data() + pos, d->data() + pos + len, d->size - pos - len);
|
||||
resize(d->size - len);
|
||||
}
|
||||
return *this;
|
||||
|
|
@ -1832,7 +1847,7 @@ QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
|
|||
{
|
||||
if (len == after.d->size && (pos + len <= d->size)) {
|
||||
detach();
|
||||
memmove(d->data + pos, after.d->data, len*sizeof(char));
|
||||
memmove(d->data() + pos, after.d->data(), len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
QByteArray copy(after);
|
||||
|
|
@ -1869,7 +1884,7 @@ QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
|
|||
{
|
||||
if (len == alen && (pos + len <= d->size)) {
|
||||
detach();
|
||||
memcpy(d->data + pos, after, len*sizeof(char));
|
||||
memcpy(d->data() + pos, after, len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
remove(pos, len);
|
||||
|
|
@ -1936,13 +1951,13 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
|||
// protect against before or after being part of this
|
||||
const char *a = after;
|
||||
const char *b = before;
|
||||
if (after >= d->data && after < d->data + d->size) {
|
||||
if (after >= d->data() && after < d->data() + d->size) {
|
||||
char *copy = (char *)malloc(asize);
|
||||
Q_CHECK_PTR(copy);
|
||||
memcpy(copy, after, asize);
|
||||
a = copy;
|
||||
}
|
||||
if (before >= d->data && before < d->data + d->size) {
|
||||
if (before >= d->data() && before < d->data() + d->size) {
|
||||
char *copy = (char *)malloc(bsize);
|
||||
Q_CHECK_PTR(copy);
|
||||
memcpy(copy, before, bsize);
|
||||
|
|
@ -2019,7 +2034,7 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
|||
resize(newlen);
|
||||
len = newlen;
|
||||
}
|
||||
d = this->d->data;
|
||||
d = this->d->data();
|
||||
|
||||
while(pos) {
|
||||
pos--;
|
||||
|
|
@ -2192,19 +2207,19 @@ QByteArray QByteArray::repeated(int times) const
|
|||
if (result.d->alloc != resultSize)
|
||||
return QByteArray(); // not enough memory
|
||||
|
||||
memcpy(result.d->data, d->data, d->size);
|
||||
memcpy(result.d->data(), d->data(), d->size);
|
||||
|
||||
int sizeSoFar = d->size;
|
||||
char *end = result.d->data + sizeSoFar;
|
||||
char *end = result.d->data() + sizeSoFar;
|
||||
|
||||
const int halfResultSize = resultSize >> 1;
|
||||
while (sizeSoFar <= halfResultSize) {
|
||||
memcpy(end, result.d->data, sizeSoFar);
|
||||
memcpy(end, result.d->data(), sizeSoFar);
|
||||
end += sizeSoFar;
|
||||
sizeSoFar <<= 1;
|
||||
}
|
||||
memcpy(end, result.d->data, resultSize - sizeSoFar);
|
||||
result.d->data[resultSize] = '\0';
|
||||
memcpy(end, result.d->data(), resultSize - sizeSoFar);
|
||||
result.d->data()[resultSize] = '\0';
|
||||
result.d->size = resultSize;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2231,13 +2246,13 @@ int QByteArray::indexOf(const QByteArray &ba, int from) const
|
|||
if (ol == 0)
|
||||
return from;
|
||||
if (ol == 1)
|
||||
return indexOf(*ba.d->data, from);
|
||||
return indexOf(*ba.d->data(), from);
|
||||
|
||||
const int l = d->size;
|
||||
if (from > d->size || ol + from > l)
|
||||
return -1;
|
||||
|
||||
return qFindByteArray(d->data, d->size, from, ba.d->data, ol);
|
||||
return qFindByteArray(d->data(), d->size, from, ba.d->data(), ol);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::indexOf(const QString &str, int from) const
|
||||
|
|
@ -2279,7 +2294,7 @@ int QByteArray::indexOf(const char *c, int from) const
|
|||
if (ol == 0)
|
||||
return from;
|
||||
|
||||
return qFindByteArray(d->data, d->size, from, c, ol);
|
||||
return qFindByteArray(d->data(), d->size, from, c, ol);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2300,11 +2315,11 @@ int QByteArray::indexOf(char ch, int from) const
|
|||
if (from < 0)
|
||||
from = qMax(from + d->size, 0);
|
||||
if (from < d->size) {
|
||||
const char *n = d->data + from - 1;
|
||||
const char *e = d->data + d->size;
|
||||
const char *n = d->data() + from - 1;
|
||||
const char *e = d->data() + d->size;
|
||||
while (++n != e)
|
||||
if (*n == ch)
|
||||
return n - d->data;
|
||||
return n - d->data();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -2361,9 +2376,9 @@ int QByteArray::lastIndexOf(const QByteArray &ba, int from) const
|
|||
{
|
||||
const int ol = ba.d->size;
|
||||
if (ol == 1)
|
||||
return lastIndexOf(*ba.d->data, from);
|
||||
return lastIndexOf(*ba.d->data(), from);
|
||||
|
||||
return lastIndexOfHelper(d->data, d->size, ba.d->data, ol, from);
|
||||
return lastIndexOfHelper(d->data(), d->size, ba.d->data(), ol, from);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::lastIndexOf(const QString &str, int from) const
|
||||
|
|
@ -2400,7 +2415,7 @@ int QByteArray::lastIndexOf(const char *str, int from) const
|
|||
if (ol == 1)
|
||||
return lastIndexOf(*str, from);
|
||||
|
||||
return lastIndexOfHelper(d->data, d->size, str, ol, from);
|
||||
return lastIndexOfHelper(d->data(), d->size, str, ol, from);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2424,8 +2439,8 @@ int QByteArray::lastIndexOf(char ch, int from) const
|
|||
else if (from > d->size)
|
||||
from = d->size-1;
|
||||
if (from >= 0) {
|
||||
const char *b = d->data;
|
||||
const char *n = d->data + from + 1;
|
||||
const char *b = d->data();
|
||||
const char *n = d->data() + from + 1;
|
||||
while (n-- != b)
|
||||
if (*n == ch)
|
||||
return n - b;
|
||||
|
|
@ -2479,8 +2494,8 @@ int QByteArray::count(const char *str) const
|
|||
int QByteArray::count(char ch) const
|
||||
{
|
||||
int num = 0;
|
||||
const char *i = d->data + d->size;
|
||||
const char *b = d->data;
|
||||
const char *i = d->data() + d->size;
|
||||
const char *b = d->data();
|
||||
while (i != b)
|
||||
if (*--i == ch)
|
||||
++num;
|
||||
|
|
@ -2509,7 +2524,7 @@ bool QByteArray::startsWith(const QByteArray &ba) const
|
|||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
return false;
|
||||
return memcmp(d->data, ba.d->data, ba.d->size) == 0;
|
||||
return memcmp(d->data(), ba.d->data(), ba.d->size) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2524,7 +2539,7 @@ bool QByteArray::startsWith(const char *str) const
|
|||
int len = qstrlen(str);
|
||||
if (d->size < len)
|
||||
return false;
|
||||
return qstrncmp(d->data, str, len) == 0;
|
||||
return qstrncmp(d->data(), str, len) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2536,7 +2551,7 @@ bool QByteArray::startsWith(char ch) const
|
|||
{
|
||||
if (d->size == 0)
|
||||
return false;
|
||||
return d->data[0] == ch;
|
||||
return d->data()[0] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2554,7 +2569,7 @@ bool QByteArray::endsWith(const QByteArray &ba) const
|
|||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
return false;
|
||||
return memcmp(d->data + d->size - ba.d->size, ba.d->data, ba.d->size) == 0;
|
||||
return memcmp(d->data() + d->size - ba.d->size, ba.d->data(), ba.d->size) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2569,7 +2584,7 @@ bool QByteArray::endsWith(const char *str) const
|
|||
int len = qstrlen(str);
|
||||
if (d->size < len)
|
||||
return false;
|
||||
return qstrncmp(d->data + d->size - len, str, len) == 0;
|
||||
return qstrncmp(d->data() + d->size - len, str, len) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2581,7 +2596,7 @@ bool QByteArray::endsWith(char ch) const
|
|||
{
|
||||
if (d->size == 0)
|
||||
return false;
|
||||
return d->data[d->size - 1] == ch;
|
||||
return d->data()[d->size - 1] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2603,7 +2618,7 @@ QByteArray QByteArray::left(int len) const
|
|||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data, len);
|
||||
return QByteArray(d->data(), len);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2625,7 +2640,7 @@ QByteArray QByteArray::right(int len) const
|
|||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data + d->size - len, len);
|
||||
return QByteArray(d->data() + d->size - len, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2644,7 +2659,7 @@ QByteArray QByteArray::right(int len) const
|
|||
|
||||
QByteArray QByteArray::mid(int pos, int len) const
|
||||
{
|
||||
if (d == &shared_null || d == &shared_empty || pos >= d->size)
|
||||
if (d == &shared_null.ba || d == &shared_empty.ba || pos >= d->size)
|
||||
return QByteArray();
|
||||
if (len < 0)
|
||||
len = d->size - pos;
|
||||
|
|
@ -2656,7 +2671,7 @@ QByteArray QByteArray::mid(int pos, int len) const
|
|||
len = d->size - pos;
|
||||
if (pos == 0 && len == d->size)
|
||||
return *this;
|
||||
return QByteArray(d->data + pos, len);
|
||||
return QByteArray(d->data() + pos, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2715,7 +2730,7 @@ void QByteArray::clear()
|
|||
{
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
|
|
@ -3106,10 +3121,10 @@ QByteArray QByteArray::simplified() const
|
|||
if (d->size == 0)
|
||||
return *this;
|
||||
QByteArray result(d->size, Qt::Uninitialized);
|
||||
const char *from = d->data;
|
||||
const char *from = d->data();
|
||||
const char *fromend = from + d->size;
|
||||
int outc=0;
|
||||
char *to = result.d->data;
|
||||
char *to = result.d->data();
|
||||
for (;;) {
|
||||
while (from!=fromend && isspace(uchar(*from)))
|
||||
from++;
|
||||
|
|
@ -3145,7 +3160,7 @@ QByteArray QByteArray::trimmed() const
|
|||
{
|
||||
if (d->size == 0)
|
||||
return *this;
|
||||
const char *s = d->data;
|
||||
const char *s = d->data();
|
||||
if (!isspace(uchar(*s)) && !isspace(uchar(s[d->size-1])))
|
||||
return *this;
|
||||
int start = 0;
|
||||
|
|
@ -3158,8 +3173,7 @@ QByteArray QByteArray::trimmed() const
|
|||
}
|
||||
int l = end - start + 1;
|
||||
if (l <= 0) {
|
||||
shared_empty.ref.ref();
|
||||
return QByteArray(&shared_empty, 0, 0);
|
||||
return QByteArray(const_cast<Data *>(&shared_empty.ba), 0, 0);
|
||||
}
|
||||
return QByteArray(s+start, l);
|
||||
}
|
||||
|
|
@ -3190,8 +3204,8 @@ QByteArray QByteArray::leftJustified(int width, char fill, bool truncate) const
|
|||
if (padlen > 0) {
|
||||
result.resize(len+padlen);
|
||||
if (len)
|
||||
memcpy(result.d->data, d->data, len);
|
||||
memset(result.d->data+len, fill, padlen);
|
||||
memcpy(result.d->data(), d->data(), len);
|
||||
memset(result.d->data()+len, fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
|
|
@ -3227,8 +3241,8 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
|||
if (padlen > 0) {
|
||||
result.resize(len+padlen);
|
||||
if (len)
|
||||
memcpy(result.d->data+padlen, data(), len);
|
||||
memset(result.d->data, fill, padlen);
|
||||
memcpy(result.d->data()+padlen, data(), len);
|
||||
memset(result.d->data(), fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
|
|
@ -3238,7 +3252,7 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
|||
return result;
|
||||
}
|
||||
|
||||
bool QByteArray::isNull() const { return d == &shared_null; }
|
||||
bool QByteArray::isNull() const { return d == &shared_null.ba; }
|
||||
|
||||
|
||||
/*!
|
||||
|
|
@ -3562,13 +3576,13 @@ QByteArray QByteArray::toBase64() const
|
|||
char *out = tmp.data();
|
||||
while (i < d->size) {
|
||||
int chunk = 0;
|
||||
chunk |= int(uchar(d->data[i++])) << 16;
|
||||
chunk |= int(uchar(d->data()[i++])) << 16;
|
||||
if (i == d->size) {
|
||||
padlen = 2;
|
||||
} else {
|
||||
chunk |= int(uchar(d->data[i++])) << 8;
|
||||
chunk |= int(uchar(d->data()[i++])) << 8;
|
||||
if (i == d->size) padlen = 1;
|
||||
else chunk |= int(uchar(d->data[i++]));
|
||||
else chunk |= int(uchar(d->data()[i++]));
|
||||
}
|
||||
|
||||
int j = (chunk & 0x00fc0000) >> 18;
|
||||
|
|
@ -3864,17 +3878,20 @@ QByteArray QByteArray::number(double n, char f, int prec)
|
|||
|
||||
QByteArray QByteArray::fromRawData(const char *data, int size)
|
||||
{
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
|
||||
Q_CHECK_PTR(x);
|
||||
if (data) {
|
||||
x->data = const_cast<char *>(data);
|
||||
Data *x;
|
||||
if (!data) {
|
||||
x = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!size) {
|
||||
x = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
x->data = x->array;
|
||||
size = 0;
|
||||
x = static_cast<Data *>(qMalloc(sizeof(Data) + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->ref = 1;
|
||||
x->size = size;
|
||||
x->alloc = 0;
|
||||
x->capacityReserved = false;
|
||||
x->offset = data - (x->d + sizeof(qptrdiff));
|
||||
}
|
||||
x->ref = 1;
|
||||
x->alloc = x->size = size;
|
||||
*x->array = '\0';
|
||||
return QByteArray(x, 0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -3898,13 +3915,13 @@ QByteArray &QByteArray::setRawData(const char *data, uint size)
|
|||
*this = fromRawData(data, size);
|
||||
} else {
|
||||
if (data) {
|
||||
d->data = const_cast<char *>(data);
|
||||
d->size = size;
|
||||
d->offset = data - (d->d + sizeof(qptrdiff));
|
||||
} else {
|
||||
d->data = d->array;
|
||||
size = 0;
|
||||
d->offset = 0;
|
||||
d->size = 0;
|
||||
*d->data() = 0;
|
||||
}
|
||||
d->alloc = d->size = size;
|
||||
*d->array = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -4013,7 +4030,7 @@ QByteArray QByteArray::toHex() const
|
|||
{
|
||||
QByteArray hex(d->size * 2, Qt::Uninitialized);
|
||||
char *hexData = hex.data();
|
||||
const uchar *data = (const uchar *)d->data;
|
||||
const uchar *data = (const uchar *)d->data();
|
||||
for (int i = 0; i < d->size; ++i) {
|
||||
int j = (data[i] >> 4) & 0xf;
|
||||
if (j <= 9)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#ifndef QBYTEARRAY_H
|
||||
#define QBYTEARRAY_H
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qrefcount.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -119,18 +119,65 @@ class QString;
|
|||
class QDataStream;
|
||||
template <typename T> class QList;
|
||||
|
||||
struct QByteArrayData
|
||||
{
|
||||
QtPrivate::RefCount ref;
|
||||
int size;
|
||||
uint alloc : 31;
|
||||
uint capacityReserved : 1;
|
||||
union {
|
||||
qptrdiff offset; // will always work as we add/subtract from a ushort ptr
|
||||
char d[sizeof(qptrdiff)];
|
||||
};
|
||||
inline char *data() { return d + sizeof(qptrdiff) + offset; }
|
||||
inline const char *data() const { return d + sizeof(qptrdiff) + offset; }
|
||||
};
|
||||
|
||||
template<int n> struct QConstByteArrayData
|
||||
{
|
||||
const QByteArrayData ba;
|
||||
const char data[n];
|
||||
};
|
||||
|
||||
template<int N> struct QConstByteArrayDataPtr
|
||||
{
|
||||
const QConstByteArrayData<N> *ptr;
|
||||
};
|
||||
|
||||
|
||||
#if defined(Q_COMPILER_LAMBDA)
|
||||
# define QByteArrayLiteral(str) ([]() { \
|
||||
enum { Size = sizeof(str) }; \
|
||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
|
||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||
return holder; }())
|
||||
|
||||
#elif defined(Q_CC_GNU)
|
||||
// We need to create a QByteArrayData in the .rodata section of memory
|
||||
// and the only way to do that is to create a "static const" variable.
|
||||
// To do that, we need the __extension__ {( )} trick which only GCC supports
|
||||
|
||||
# define QByteArrayLiteral(str) \
|
||||
__extension__ ({ \
|
||||
enum { Size = sizeof(str) }; \
|
||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
|
||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||
holder; })
|
||||
#endif
|
||||
|
||||
#ifndef QByteArrayLiteral
|
||||
// no lambdas, not GCC, use const char * instead
|
||||
|
||||
# define QByteArrayLiteral(str) (str)
|
||||
#endif
|
||||
|
||||
|
||||
class Q_CORE_EXPORT QByteArray
|
||||
{
|
||||
private:
|
||||
struct Data {
|
||||
QBasicAtomicInt ref;
|
||||
int alloc, size;
|
||||
// ### Qt 5.0: We need to add the missing capacity bit
|
||||
// (like other tool classes have), to maintain the
|
||||
// reserved memory on resize.
|
||||
char *data;
|
||||
char array[1];
|
||||
};
|
||||
typedef QByteArrayData Data;
|
||||
|
||||
public:
|
||||
inline QByteArray();
|
||||
|
|
@ -330,10 +377,17 @@ public:
|
|||
int length() const { return d->size; }
|
||||
bool isNull() const;
|
||||
|
||||
template <int n>
|
||||
inline QByteArray(const QConstByteArrayData<n> &dd)
|
||||
: d(const_cast<QByteArrayData *>(&dd.str)) {}
|
||||
template <int N>
|
||||
Q_DECL_CONSTEXPR inline QByteArray(QConstByteArrayDataPtr<N> dd)
|
||||
: d(const_cast<QByteArrayData *>(&dd.ptr->ba)) {}
|
||||
|
||||
private:
|
||||
operator QNoImplicitBoolCast() const;
|
||||
static Data shared_null;
|
||||
static Data shared_empty;
|
||||
static QConstByteArrayData<1> shared_null;
|
||||
static QConstByteArrayData<1> shared_empty;
|
||||
Data *d;
|
||||
QByteArray(Data *dd, int /*dummy*/, int /*dummy*/) : d(dd) {}
|
||||
void realloc(int alloc);
|
||||
|
|
@ -348,34 +402,34 @@ public:
|
|||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
inline QByteArray::QByteArray(): d(&shared_null) { d->ref.ref(); }
|
||||
inline QByteArray::QByteArray(): d(const_cast<Data *>(&shared_null.ba)) { d->ref.ref(); }
|
||||
inline QByteArray::~QByteArray() { if (!d->ref.deref()) qFree(d); }
|
||||
inline int QByteArray::size() const
|
||||
{ return d->size; }
|
||||
|
||||
inline char QByteArray::at(int i) const
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data()[i]; }
|
||||
inline char QByteArray::operator[](int i) const
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data()[i]; }
|
||||
inline char QByteArray::operator[](uint i) const
|
||||
{ Q_ASSERT(i < uint(size())); return d->data[i]; }
|
||||
{ Q_ASSERT(i < uint(size())); return d->data()[i]; }
|
||||
|
||||
inline bool QByteArray::isEmpty() const
|
||||
{ return d->size == 0; }
|
||||
#ifndef QT_NO_CAST_FROM_BYTEARRAY
|
||||
inline QByteArray::operator const char *() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::operator const void *() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
#endif
|
||||
inline char *QByteArray::data()
|
||||
{ detach(); return d->data; }
|
||||
{ detach(); return d->data(); }
|
||||
inline const char *QByteArray::data() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline const char *QByteArray::constData() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline void QByteArray::detach()
|
||||
{ if (d->ref != 1 || d->data != d->array) realloc(d->size); }
|
||||
{ if (d->ref != 1 || d->offset) realloc(d->size); }
|
||||
inline bool QByteArray::isDetached() const
|
||||
{ return d->ref == 1; }
|
||||
inline QByteArray::QByteArray(const QByteArray &a) : d(a.d)
|
||||
|
|
@ -385,10 +439,10 @@ inline int QByteArray::capacity() const
|
|||
{ return d->alloc; }
|
||||
|
||||
inline void QByteArray::reserve(int asize)
|
||||
{ if (d->ref != 1 || asize > d->alloc) realloc(asize); }
|
||||
{ if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true; }
|
||||
|
||||
inline void QByteArray::squeeze()
|
||||
{ if (d->size < d->alloc) realloc(d->size); }
|
||||
{ if (d->size < d->alloc) realloc(d->size); d->capacityReserved = false; }
|
||||
|
||||
class Q_CORE_EXPORT QByteRef {
|
||||
QByteArray &a;
|
||||
|
|
@ -398,25 +452,25 @@ class Q_CORE_EXPORT QByteRef {
|
|||
friend class QByteArray;
|
||||
public:
|
||||
inline operator char() const
|
||||
{ return i < a.d->size ? a.d->data[i] : char(0); }
|
||||
{ return i < a.d->size ? a.d->data()[i] : char(0); }
|
||||
inline QByteRef &operator=(char c)
|
||||
{ if (i >= a.d->size) a.expand(i); else a.detach();
|
||||
a.d->data[i] = c; return *this; }
|
||||
a.d->data()[i] = c; return *this; }
|
||||
inline QByteRef &operator=(const QByteRef &c)
|
||||
{ if (i >= a.d->size) a.expand(i); else a.detach();
|
||||
a.d->data[i] = c.a.d->data[c.i]; return *this; }
|
||||
a.d->data()[i] = c.a.d->data()[c.i]; return *this; }
|
||||
inline bool operator==(char c) const
|
||||
{ return a.d->data[i] == c; }
|
||||
{ return a.d->data()[i] == c; }
|
||||
inline bool operator!=(char c) const
|
||||
{ return a.d->data[i] != c; }
|
||||
{ return a.d->data()[i] != c; }
|
||||
inline bool operator>(char c) const
|
||||
{ return a.d->data[i] > c; }
|
||||
{ return a.d->data()[i] > c; }
|
||||
inline bool operator>=(char c) const
|
||||
{ return a.d->data[i] >= c; }
|
||||
{ return a.d->data()[i] >= c; }
|
||||
inline bool operator<(char c) const
|
||||
{ return a.d->data[i] < c; }
|
||||
{ return a.d->data()[i] < c; }
|
||||
inline bool operator<=(char c) const
|
||||
{ return a.d->data[i] <= c; }
|
||||
{ return a.d->data()[i] <= c; }
|
||||
};
|
||||
|
||||
inline QByteRef QByteArray::operator[](int i)
|
||||
|
|
@ -424,17 +478,17 @@ inline QByteRef QByteArray::operator[](int i)
|
|||
inline QByteRef QByteArray::operator[](uint i)
|
||||
{ return QByteRef(*this, i); }
|
||||
inline QByteArray::iterator QByteArray::begin()
|
||||
{ detach(); return d->data; }
|
||||
{ detach(); return d->data(); }
|
||||
inline QByteArray::const_iterator QByteArray::begin() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::const_iterator QByteArray::constBegin() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::iterator QByteArray::end()
|
||||
{ detach(); return d->data + d->size; }
|
||||
{ detach(); return d->data() + d->size; }
|
||||
inline QByteArray::const_iterator QByteArray::end() const
|
||||
{ return d->data + d->size; }
|
||||
{ return d->data() + d->size; }
|
||||
inline QByteArray::const_iterator QByteArray::constEnd() const
|
||||
{ return d->data + d->size; }
|
||||
{ return d->data() + d->size; }
|
||||
inline QByteArray &QByteArray::operator+=(char c)
|
||||
{ return append(c); }
|
||||
inline QByteArray &QByteArray::operator+=(const char *s)
|
||||
|
|
|
|||
|
|
@ -76,17 +76,16 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDateTimePrivate
|
||||
class QDateTimePrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
enum Spec { LocalUnknown = -1, LocalStandard = 0, LocalDST = 1, UTC = 2, OffsetFromUTC = 3};
|
||||
|
||||
QDateTimePrivate() : spec(LocalUnknown), utcOffset(0) {}
|
||||
QDateTimePrivate(const QDateTimePrivate &other)
|
||||
: date(other.date), time(other.time), spec(other.spec), utcOffset(other.utcOffset)
|
||||
: QSharedData(other), date(other.date), time(other.time), spec(other.spec), utcOffset(other.utcOffset)
|
||||
{}
|
||||
|
||||
QAtomicInt ref;
|
||||
QDate date;
|
||||
QTime time;
|
||||
Spec spec;
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,11 @@ QString::QString(const QChar *unicode, int size)
|
|||
} else {
|
||||
d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = (uint) size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), unicode, size * sizeof(QChar));
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
|
|
@ -1079,7 +1083,11 @@ QString::QString(const QChar *unicode)
|
|||
} else {
|
||||
d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = (uint) size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), unicode, size * sizeof(QChar));
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
|
|
@ -1100,7 +1108,11 @@ QString::QString(int size, QChar ch)
|
|||
} else {
|
||||
d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = (uint) size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[size] = '\0';
|
||||
ushort *i = d->data() + size;
|
||||
ushort *b = d->data();
|
||||
|
|
@ -1120,7 +1132,11 @@ QString::QString(int size, Qt::Initialization)
|
|||
{
|
||||
d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = (uint) size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
|
||||
|
|
@ -1138,7 +1154,11 @@ QString::QString(QChar ch)
|
|||
{
|
||||
d = (Data *) qMalloc(sizeof(Data) + 2*sizeof(QChar));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data) { Q_REFCOUNT_INITIALIZER(1), 1, 1, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = 1;
|
||||
d->alloc = 1;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[0] = ch.unicode();
|
||||
d->data()[1] = '\0';
|
||||
}
|
||||
|
|
@ -1313,7 +1333,11 @@ void QString::realloc(int alloc)
|
|||
if (d->ref != 1 || d->offset) {
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
|
||||
Q_CHECK_PTR(x);
|
||||
*x = (Data){ Q_REFCOUNT_INITIALIZER(1), qMin(alloc, d->size), alloc, d->capacityReserved, { 0 } };
|
||||
x->ref = 1;
|
||||
x->size = qMin(alloc, d->size);
|
||||
x->alloc = (uint) alloc;
|
||||
x->capacityReserved = d->capacityReserved;
|
||||
x->offset =0;
|
||||
::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
|
||||
x->data()[x->size] = 0;
|
||||
if (!d->ref.deref())
|
||||
|
|
@ -3747,7 +3771,11 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
|
|||
size = qstrlen(str);
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + (size+1) * sizeof(QChar)));
|
||||
Q_CHECK_PTR(d);
|
||||
*d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = (uint) size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[size] = '\0';
|
||||
ushort *dst = d->data();
|
||||
/* SIMD:
|
||||
|
|
@ -7071,13 +7099,19 @@ bool QString::isRightToLeft() const
|
|||
*/
|
||||
QString QString::fromRawData(const QChar *unicode, int size)
|
||||
{
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
|
||||
*x = (Data){ Q_REFCOUNT_INITIALIZER(1), size, 0, false, { 0 } };
|
||||
Q_CHECK_PTR(x);
|
||||
if (unicode) {
|
||||
x->offset = (const ushort *)unicode - (x->d + sizeof(qptrdiff)/sizeof(ushort));
|
||||
Data *x;
|
||||
if (!unicode) {
|
||||
x = const_cast<Data *>(&shared_null.str);
|
||||
} else if (!size) {
|
||||
x = const_cast<Data *>(&shared_empty.str);
|
||||
} else {
|
||||
size = 0;
|
||||
x = static_cast<Data *>(qMalloc(sizeof(Data) + sizeof(ushort)));
|
||||
Q_CHECK_PTR(x);
|
||||
x->ref = 1;
|
||||
x->size = size;
|
||||
x->alloc = 0;
|
||||
x->capacityReserved = false;
|
||||
x->offset = (const ushort *)unicode - (x->d + sizeof(qptrdiff)/sizeof(ushort));
|
||||
}
|
||||
return QString(x, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ public:
|
|||
|
||||
int capacity() const;
|
||||
inline void reserve(int size);
|
||||
inline void squeeze() { if (d->size < d->alloc || d->ref != 1) realloc(); d->capacityReserved = false;}
|
||||
inline void squeeze() { if (d->size < (int)d->alloc || d->ref != 1) realloc(); d->capacityReserved = false;}
|
||||
|
||||
inline const QChar *unicode() const;
|
||||
inline QChar *data();
|
||||
|
|
@ -337,7 +337,7 @@ public:
|
|||
inline QString &prepend(const QLatin1String &s) { return insert(0, s); }
|
||||
|
||||
inline QString &operator+=(QChar c) {
|
||||
if (d->ref != 1 || d->size + 1 > d->alloc)
|
||||
if (d->ref != 1 || d->size + 1 > (int)d->alloc)
|
||||
realloc(grow(d->size + 1));
|
||||
d->data()[d->size++] = c.unicode();
|
||||
d->data()[d->size] = '\0';
|
||||
|
|
@ -633,7 +633,7 @@ public:
|
|||
class Q_CORE_EXPORT QLatin1String
|
||||
{
|
||||
public:
|
||||
inline explicit QLatin1String(const char *s) : m_size(s ? strlen(s) : 0), m_data(s) {}
|
||||
inline explicit QLatin1String(const char *s) : m_size(s ? (int)strlen(s) : 0), m_data(s) {}
|
||||
|
||||
inline const char *latin1() const { return m_data; }
|
||||
inline int size() const { return m_size; }
|
||||
|
|
@ -842,7 +842,7 @@ inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
|
|||
|
||||
inline QString::QString() : d(const_cast<Data *>(&shared_null.str)) {}
|
||||
inline QString::~QString() { if (!d->ref.deref()) free(d); }
|
||||
inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true;}
|
||||
inline void QString::reserve(int asize) { if (d->ref != 1 || asize > (int)d->alloc) realloc(asize); d->capacityReserved = true;}
|
||||
inline QString &QString::setUtf16(const ushort *autf16, int asize)
|
||||
{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
|
||||
inline QCharRef QString::operator[](int i)
|
||||
|
|
|
|||
|
|
@ -1644,7 +1644,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
|
|||
overall.y = qMin(overall.y, y);
|
||||
xmax = qMax(xmax, x + g->width);
|
||||
ymax = qMax(ymax, y + g->height);
|
||||
overall.xoff += qRound(g->advance);
|
||||
overall.xoff += g->advance;
|
||||
} else {
|
||||
int left = FLOOR(face->glyph->metrics.horiBearingX);
|
||||
int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
|
||||
|
|
@ -1657,7 +1657,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
|
|||
overall.y = qMin(overall.y, y);
|
||||
xmax = qMax(xmax, x + TRUNC(right - left));
|
||||
ymax = qMax(ymax, y + TRUNC(top - bottom));
|
||||
overall.xoff += qRound(TRUNC(ROUND(face->glyph->advance.x)));
|
||||
overall.xoff += int(TRUNC(ROUND(face->glyph->advance.x)));
|
||||
}
|
||||
}
|
||||
overall.height = qMax(overall.height, ymax - overall.y);
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
|
|||
value = request.headerField("accept-encoding");
|
||||
if (value.isEmpty()) {
|
||||
#ifndef QT_NO_COMPRESS
|
||||
request.setHeaderField("Accept-Encoding", "gzip");
|
||||
request.setHeaderField("Accept-Encoding", "gzip, deflate");
|
||||
request.d->autoDecompress = true;
|
||||
#else
|
||||
// if zlib is not available set this to false always
|
||||
|
|
|
|||
|
|
@ -202,9 +202,6 @@ public:
|
|||
QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket,
|
||||
const QString &extraDetail = QString());
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete);
|
||||
#endif
|
||||
void removeReply(QHttpNetworkReply *reply);
|
||||
|
||||
QString hostName;
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
|
|||
bytes += headerBytes;
|
||||
// If headers were parsed successfully now it is the ReadingDataState
|
||||
if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
|
||||
if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) {
|
||||
if (replyPrivate->isCompressed() && replyPrivate->autoDecompress) {
|
||||
// remove the Content-Length from header
|
||||
replyPrivate->removeAutoDecompressHeader();
|
||||
} else {
|
||||
|
|
@ -448,12 +448,17 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
|
|||
// the buffer in that size.
|
||||
// note that this call will read only from the still buffered data
|
||||
qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
|
||||
bytes += haveRead;
|
||||
replyPrivate->totalProgress += haveRead;
|
||||
|
||||
// the user will get notified of it via progress signal
|
||||
if (haveRead > 0)
|
||||
if (haveRead > 0) {
|
||||
bytes += haveRead;
|
||||
replyPrivate->totalProgress += haveRead;
|
||||
// the user will get notified of it via progress signal
|
||||
emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
|
||||
} else if (haveRead == 0) {
|
||||
// Happens since this called in a loop. Currently no bytes available.
|
||||
} else if (haveRead < 0) {
|
||||
connection->d_func()->emitReplyError(socket, reply, QNetworkReply::RemoteHostClosedError);
|
||||
break;
|
||||
}
|
||||
} else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
|
||||
&& replyPrivate->bodyLength > 0) {
|
||||
// bulk files like images should fulfill these properties and
|
||||
|
|
@ -470,30 +475,18 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
|
|||
{
|
||||
// use the traditional slower reading (for compressed encoding, chunked encoding,
|
||||
// no content-length etc)
|
||||
QByteDataBuffer byteDatas;
|
||||
qint64 haveRead = replyPrivate->readBody(socket, &byteDatas);
|
||||
if (haveRead) {
|
||||
qint64 haveRead = replyPrivate->readBody(socket, &replyPrivate->responseData);
|
||||
if (haveRead > 0) {
|
||||
bytes += haveRead;
|
||||
if (replyPrivate->autoDecompress)
|
||||
replyPrivate->appendCompressedReplyData(byteDatas);
|
||||
else
|
||||
replyPrivate->appendUncompressedReplyData(byteDatas);
|
||||
|
||||
if (!replyPrivate->autoDecompress) {
|
||||
replyPrivate->totalProgress += bytes;
|
||||
if (replyPrivate->shouldEmitSignals()) {
|
||||
// important: At the point of this readyRead(), the byteDatas list must be empty,
|
||||
// else implicit sharing will trigger memcpy when the user is reading data!
|
||||
emit reply->readyRead();
|
||||
emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
|
||||
}
|
||||
replyPrivate->totalProgress += haveRead;
|
||||
if (replyPrivate->shouldEmitSignals()) {
|
||||
emit reply->readyRead();
|
||||
emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
|
||||
}
|
||||
#ifndef QT_NO_COMPRESS
|
||||
else if (!expand(false)) { // expand a chunk if possible
|
||||
// If expand() failed we can just return, it had already called connection->emitReplyError()
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
} else if (haveRead == -1) {
|
||||
// Some error occured
|
||||
connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolFailure);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// still in ReadingDataState? This function will be called again by the socket's readyRead
|
||||
|
|
@ -633,57 +626,9 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
bool QHttpNetworkConnectionChannel::expand(bool dataComplete)
|
||||
{
|
||||
Q_ASSERT(socket);
|
||||
Q_ASSERT(reply);
|
||||
|
||||
qint64 total = reply->d_func()->compressedData.size();
|
||||
if (total >= CHUNK || dataComplete) {
|
||||
// uncompress the data
|
||||
QByteArray content, inflated;
|
||||
content = reply->d_func()->compressedData;
|
||||
reply->d_func()->compressedData.clear();
|
||||
|
||||
int ret = Z_OK;
|
||||
if (content.size())
|
||||
ret = reply->d_func()->gunzipBodyPartially(content, inflated);
|
||||
int retCheck = (dataComplete) ? Z_STREAM_END : Z_OK;
|
||||
if (ret >= retCheck) {
|
||||
if (inflated.size()) {
|
||||
reply->d_func()->totalProgress += inflated.size();
|
||||
reply->d_func()->appendUncompressedReplyData(inflated);
|
||||
if (reply->d_func()->shouldEmitSignals()) {
|
||||
// important: At the point of this readyRead(), inflated must be cleared,
|
||||
// else implicit sharing will trigger memcpy when the user is reading data!
|
||||
emit reply->readyRead();
|
||||
emit reply->dataReadProgress(reply->d_func()->totalProgress, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolFailure);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void QHttpNetworkConnectionChannel::allDone()
|
||||
{
|
||||
Q_ASSERT(reply);
|
||||
#ifndef QT_NO_COMPRESS
|
||||
// expand the whole data.
|
||||
if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd) {
|
||||
bool expandResult = expand(true);
|
||||
// If expand() failed we can just return, it had already called connection->emitReplyError()
|
||||
if (!expandResult)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!reply) {
|
||||
qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt.nokia.com/";
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ public:
|
|||
|
||||
bool ensureConnection();
|
||||
|
||||
bool expand(bool dataComplete);
|
||||
void allDone(); // reply header + body have been read
|
||||
void handleStatus(); // called from allDone()
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ QHttpNetworkReply::~QHttpNetworkReply()
|
|||
if (d->connection) {
|
||||
d->connection->d_func()->removeReply(this);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
if (d->autoDecompress && d->isCompressed())
|
||||
inflateEnd(&d->inflateStrm);
|
||||
#endif
|
||||
}
|
||||
|
||||
QUrl QHttpNetworkReply::url() const
|
||||
|
|
@ -211,7 +216,7 @@ void QHttpNetworkReply::setDownstreamLimited(bool dsl)
|
|||
bool QHttpNetworkReply::supportsUserProvidedDownloadBuffer()
|
||||
{
|
||||
Q_D(QHttpNetworkReply);
|
||||
return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0);
|
||||
return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0 && d->statusCode == 200);
|
||||
}
|
||||
|
||||
void QHttpNetworkReply::setUserProvidedDownloadBuffer(char* b)
|
||||
|
|
@ -252,7 +257,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
|
|||
chunkedTransferEncoding(false),
|
||||
connectionCloseEnabled(true),
|
||||
forceConnectionCloseEnabled(false),
|
||||
currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
|
||||
currentChunkSize(0), currentChunkRead(0), connection(0),
|
||||
autoDecompress(false), responseData(), requestIsPrepared(false)
|
||||
,pipeliningUsed(false), downstreamLimited(false)
|
||||
,userProvidedDownloadBuffer(0)
|
||||
|
|
@ -274,11 +279,9 @@ void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
|
|||
currentChunkRead = 0;
|
||||
connectionCloseEnabled = true;
|
||||
#ifndef QT_NO_COMPRESS
|
||||
if (initInflate)
|
||||
if (autoDecompress)
|
||||
inflateEnd(&inflateStrm);
|
||||
#endif
|
||||
initInflate = false;
|
||||
streamEnd = false;
|
||||
fields.clear();
|
||||
}
|
||||
|
||||
|
|
@ -297,10 +300,10 @@ qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
|
|||
return (state != ReadingDataState ? 0 : fragment.size());
|
||||
}
|
||||
|
||||
bool QHttpNetworkReplyPrivate::isGzipped()
|
||||
bool QHttpNetworkReplyPrivate::isCompressed()
|
||||
{
|
||||
QByteArray encoding = headerField("content-encoding");
|
||||
return qstricmp(encoding.constData(), "gzip") == 0;
|
||||
return qstricmp(encoding.constData(), "gzip") == 0 || qstricmp(encoding.constData(), "deflate") == 0;
|
||||
}
|
||||
|
||||
void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
|
||||
|
|
@ -358,120 +361,6 @@ QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(boo
|
|||
return method;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
bool QHttpNetworkReplyPrivate::gzipCheckHeader(QByteArray &content, int &pos)
|
||||
{
|
||||
int method = 0; // method byte
|
||||
int flags = 0; // flags byte
|
||||
bool ret = false;
|
||||
|
||||
// Assure two bytes in the buffer so we can peek ahead -- handle case
|
||||
// where first byte of header is at the end of the buffer after the last
|
||||
// gzip segment
|
||||
pos = -1;
|
||||
QByteArray &body = content;
|
||||
int maxPos = body.size()-1;
|
||||
if (maxPos < 1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Peek ahead to check the gzip magic header
|
||||
if (body[0] != char(gz_magic[0]) ||
|
||||
body[1] != char(gz_magic[1])) {
|
||||
return ret;
|
||||
}
|
||||
pos += 2;
|
||||
// Check the rest of the gzip header
|
||||
if (++pos <= maxPos)
|
||||
method = body[pos];
|
||||
if (pos++ <= maxPos)
|
||||
flags = body[pos];
|
||||
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Discard time, xflags and OS code:
|
||||
pos += 6;
|
||||
if (pos > maxPos)
|
||||
return ret;
|
||||
if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field
|
||||
unsigned len = (unsigned)body[++pos];
|
||||
len += ((unsigned)body[++pos])<<8;
|
||||
pos += len;
|
||||
if (pos > maxPos)
|
||||
return ret;
|
||||
}
|
||||
if ((flags & ORIG_NAME) != 0) { // skip the original file name
|
||||
while(++pos <= maxPos && body[pos]) {}
|
||||
}
|
||||
if ((flags & COMMENT) != 0) { // skip the .gz file comment
|
||||
while(++pos <= maxPos && body[pos]) {}
|
||||
}
|
||||
if ((flags & HEAD_CRC) != 0) { // skip the header crc
|
||||
pos += 2;
|
||||
if (pos > maxPos)
|
||||
return ret;
|
||||
}
|
||||
ret = (pos < maxPos); // return failed, if no more bytes left
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated)
|
||||
{
|
||||
int ret = Z_DATA_ERROR;
|
||||
unsigned have;
|
||||
unsigned char out[CHUNK];
|
||||
int pos = -1;
|
||||
|
||||
if (!initInflate) {
|
||||
// check the header
|
||||
if (!gzipCheckHeader(compressed, pos))
|
||||
return ret;
|
||||
// allocate inflate state
|
||||
inflateStrm.zalloc = Z_NULL;
|
||||
inflateStrm.zfree = Z_NULL;
|
||||
inflateStrm.opaque = Z_NULL;
|
||||
inflateStrm.avail_in = 0;
|
||||
inflateStrm.next_in = Z_NULL;
|
||||
ret = inflateInit2(&inflateStrm, -MAX_WBITS);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
initInflate = true;
|
||||
streamEnd = false;
|
||||
}
|
||||
|
||||
//remove the header.
|
||||
compressed.remove(0, pos+1);
|
||||
// expand until deflate stream ends
|
||||
inflateStrm.next_in = (unsigned char *)compressed.data();
|
||||
inflateStrm.avail_in = compressed.size();
|
||||
do {
|
||||
inflateStrm.avail_out = sizeof(out);
|
||||
inflateStrm.next_out = out;
|
||||
ret = inflate(&inflateStrm, Z_NO_FLUSH);
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
// and fall through
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
inflateEnd(&inflateStrm);
|
||||
initInflate = false;
|
||||
return ret;
|
||||
}
|
||||
have = sizeof(out) - inflateStrm.avail_out;
|
||||
inflated.append(QByteArray((const char *)out, have));
|
||||
} while (inflateStrm.avail_out == 0);
|
||||
// clean up and return
|
||||
if (ret <= Z_ERRNO || ret == Z_STREAM_END) {
|
||||
inflateEnd(&inflateStrm);
|
||||
initInflate = false;
|
||||
}
|
||||
streamEnd = (ret == Z_STREAM_END);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
|
||||
{
|
||||
if (fragment.isEmpty()) {
|
||||
|
|
@ -616,6 +505,24 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
|
|||
connectionCloseEnabled = (connectionHeaderField.toLower().contains("close") ||
|
||||
headerField("proxy-connection").toLower().contains("close")) ||
|
||||
(majorVersion == 1 && minorVersion == 0 && connectionHeaderField.isEmpty());
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
if (autoDecompress && isCompressed()) {
|
||||
// allocate inflate state
|
||||
inflateStrm.zalloc = Z_NULL;
|
||||
inflateStrm.zfree = Z_NULL;
|
||||
inflateStrm.opaque = Z_NULL;
|
||||
inflateStrm.avail_in = 0;
|
||||
inflateStrm.next_in = Z_NULL;
|
||||
// "windowBits can also be greater than 15 for optional gzip decoding.
|
||||
// Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection"
|
||||
// http://www.zlib.net/manual.html
|
||||
int ret = inflateInit2(&inflateStrm, MAX_WBITS+32);
|
||||
if (ret != Z_OK)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
|
@ -672,7 +579,7 @@ qint64 QHttpNetworkReplyPrivate::readBodyVeryFast(QAbstractSocket *socket, char
|
|||
qint64 haveRead = 0;
|
||||
haveRead = socket->read(b, bodyLength - contentRead);
|
||||
if (haveRead == -1) {
|
||||
return 0; // ### error checking here;
|
||||
return -1;
|
||||
}
|
||||
contentRead += haveRead;
|
||||
|
||||
|
|
@ -712,22 +619,74 @@ qint64 QHttpNetworkReplyPrivate::readBodyFast(QAbstractSocket *socket, QByteData
|
|||
qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QByteDataBuffer *out)
|
||||
{
|
||||
qint64 bytes = 0;
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
// for gzip we'll allocate a temporary one that we then decompress
|
||||
QByteDataBuffer *tempOutDataBuffer = (autoDecompress ? new QByteDataBuffer : out);
|
||||
#else
|
||||
QByteDataBuffer *tempOutDataBuffer = out;
|
||||
#endif
|
||||
|
||||
|
||||
if (isChunked()) {
|
||||
// chunked transfer encoding (rfc 2616, sec 3.6)
|
||||
bytes += readReplyBodyChunked(socket, out);
|
||||
bytes += readReplyBodyChunked(socket, tempOutDataBuffer);
|
||||
} else if (bodyLength > 0) {
|
||||
// we have a Content-Length
|
||||
bytes += readReplyBodyRaw(socket, out, bodyLength - contentRead);
|
||||
bytes += readReplyBodyRaw(socket, tempOutDataBuffer, bodyLength - contentRead);
|
||||
if (contentRead + bytes == bodyLength)
|
||||
state = AllDoneState;
|
||||
} else {
|
||||
// no content length. just read what's possible
|
||||
bytes += readReplyBodyRaw(socket, out, socket->bytesAvailable());
|
||||
bytes += readReplyBodyRaw(socket, tempOutDataBuffer, socket->bytesAvailable());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
// This is true if there is compressed encoding and we're supposed to use it.
|
||||
if (autoDecompress) {
|
||||
qint64 uncompressRet = uncompressBodyData(tempOutDataBuffer, out);
|
||||
delete tempOutDataBuffer;
|
||||
if (uncompressRet < 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
contentRead += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
qint64 QHttpNetworkReplyPrivate::uncompressBodyData(QByteDataBuffer *in, QByteDataBuffer *out)
|
||||
{
|
||||
for (int i = 0; i < in->bufferCount(); i++) {
|
||||
QByteArray &bIn = (*in)[i];
|
||||
|
||||
inflateStrm.avail_in = bIn.size();
|
||||
inflateStrm.next_in = reinterpret_cast<Bytef*>(bIn.data());
|
||||
|
||||
do {
|
||||
QByteArray bOut;
|
||||
// make a wild guess about the uncompressed size.
|
||||
bOut.reserve(inflateStrm.avail_in * 3 + 512);
|
||||
inflateStrm.avail_out = bOut.capacity();
|
||||
inflateStrm.next_out = reinterpret_cast<Bytef*>(bOut.data());
|
||||
|
||||
int ret = inflate(&inflateStrm, Z_NO_FLUSH);
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
return -1;
|
||||
}
|
||||
bOut.resize(bOut.capacity() - inflateStrm.avail_out);
|
||||
out->append(bOut);
|
||||
} while (inflateStrm.avail_in > 0);
|
||||
}
|
||||
|
||||
return out->byteAmount();
|
||||
}
|
||||
#endif
|
||||
|
||||
qint64 QHttpNetworkReplyPrivate::readReplyBodyRaw(QAbstractSocket *socket, QByteDataBuffer *out, qint64 size)
|
||||
{
|
||||
// FIXME get rid of this function and just use readBodyFast and give it socket->bytesAvailable()
|
||||
|
|
@ -841,36 +800,6 @@ qint64 QHttpNetworkReplyPrivate::getChunkSize(QAbstractSocket *socket, qint64 *c
|
|||
return bytes;
|
||||
}
|
||||
|
||||
void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteArray &qba)
|
||||
{
|
||||
responseData.append(qba);
|
||||
|
||||
// clear the original! helps with implicit sharing and
|
||||
// avoiding memcpy when the user is reading the data
|
||||
qba.clear();
|
||||
}
|
||||
|
||||
void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteDataBuffer &data)
|
||||
{
|
||||
responseData.append(data);
|
||||
|
||||
// clear the original! helps with implicit sharing and
|
||||
// avoiding memcpy when the user is reading the data
|
||||
data.clear();
|
||||
}
|
||||
|
||||
void QHttpNetworkReplyPrivate::appendCompressedReplyData(QByteDataBuffer &data)
|
||||
{
|
||||
// Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer
|
||||
// instead of one QByteArray.
|
||||
for(int i = 0; i < data.bufferCount(); i++) {
|
||||
QByteArray &byteData = data[i];
|
||||
compressedData.append(byteData.constData(), byteData.size());
|
||||
}
|
||||
data.clear();
|
||||
}
|
||||
|
||||
|
||||
bool QHttpNetworkReplyPrivate::shouldEmitSignals()
|
||||
{
|
||||
// for 401 & 407 don't emit the data signals. Content along with these
|
||||
|
|
|
|||
|
|
@ -56,15 +56,7 @@
|
|||
#ifndef QT_NO_HTTP
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
# include <zlib.h>
|
||||
static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header
|
||||
// gzip flag byte
|
||||
#define HEAD_CRC 0x02 // bit 1 set: header CRC present
|
||||
#define EXTRA_FIELD 0x04 // bit 2 set: extra field present
|
||||
#define ORIG_NAME 0x08 // bit 3 set: original file name present
|
||||
#define COMMENT 0x10 // bit 4 set: file comment present
|
||||
#define RESERVED 0xE0 // bits 5..7: reserved
|
||||
#define CHUNK 16384
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include <QtNetwork/qtcpsocket.h>
|
||||
|
|
@ -192,10 +184,6 @@ public:
|
|||
qint64 readReplyBodyChunked(QAbstractSocket *in, QByteDataBuffer *out);
|
||||
qint64 getChunkSize(QAbstractSocket *in, qint64 *chunkSize);
|
||||
|
||||
void appendUncompressedReplyData(QByteArray &qba);
|
||||
void appendUncompressedReplyData(QByteDataBuffer &data);
|
||||
void appendCompressedReplyData(QByteDataBuffer &data);
|
||||
|
||||
bool shouldEmitSignals();
|
||||
bool expectContent();
|
||||
void eraseData();
|
||||
|
|
@ -203,11 +191,8 @@ public:
|
|||
qint64 bytesAvailable() const;
|
||||
bool isChunked();
|
||||
bool isConnectionCloseEnabled();
|
||||
bool isGzipped();
|
||||
#ifndef QT_NO_COMPRESS
|
||||
bool gzipCheckHeader(QByteArray &content, int &pos);
|
||||
int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated);
|
||||
#endif
|
||||
|
||||
bool isCompressed();
|
||||
void removeAutoDecompressHeader();
|
||||
|
||||
enum ReplyState {
|
||||
|
|
@ -236,11 +221,12 @@ public:
|
|||
qint64 currentChunkRead;
|
||||
QPointer<QHttpNetworkConnection> connection;
|
||||
QPointer<QHttpNetworkConnectionChannel> connectionChannel;
|
||||
bool initInflate;
|
||||
bool streamEnd;
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
z_stream inflateStrm;
|
||||
qint64 uncompressBodyData(QByteDataBuffer *in, QByteDataBuffer *out);
|
||||
#endif
|
||||
|
||||
bool autoDecompress;
|
||||
|
||||
QByteDataBuffer responseData; // uncompressed body
|
||||
|
|
|
|||
|
|
@ -777,8 +777,16 @@ void QNetworkReplyHttpImplPrivate::postRequest()
|
|||
|
||||
if (!synchronous) {
|
||||
// Tell our zerocopy policy to the delegate
|
||||
delegate->downloadBufferMaximumSize =
|
||||
request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong();
|
||||
QVariant downloadBufferMaximumSizeAttribute = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute);
|
||||
if (downloadBufferMaximumSizeAttribute.isValid()) {
|
||||
delegate->downloadBufferMaximumSize = downloadBufferMaximumSizeAttribute.toLongLong();
|
||||
} else {
|
||||
// If there is no MaximumDownloadBufferSizeAttribute set (which is for the majority
|
||||
// of QNetworkRequest) then we can assume we'll do it anyway for small HTTP replies.
|
||||
// This helps with performance and memory fragmentation.
|
||||
delegate->downloadBufferMaximumSize = 128*1024;
|
||||
}
|
||||
|
||||
|
||||
// These atomic integers are used for signal compression
|
||||
delegate->pendingDownloadData = pendingDownloadDataEmissions;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
|
@ -666,6 +667,21 @@ QList<QSslCertificate> QSslCertificate::fromData(const QByteArray &data, QSsl::E
|
|||
: QSslCertificatePrivate::certificatesFromDer(data);
|
||||
}
|
||||
|
||||
/*!
|
||||
Verifies a certificate chain. If \a hostName is specified then the certificate is
|
||||
also checked to see if it is valid for the specified host name.
|
||||
Note that the first certificate in the list should be the leaf certificate of
|
||||
the chain to be verified.
|
||||
The root (CA) certificate should not be included in the list to be verified,
|
||||
this will be looked up automatically either using the CA list specified by
|
||||
QSslSocket::defaultCaCertificates() or, if possible, it will be loaded on demand
|
||||
on Unix.
|
||||
*/
|
||||
QList<QSslError> QSslCertificate::verify(QList<QSslCertificate> certificateChain, const QString &hostName)
|
||||
{
|
||||
return QSslSocketBackendPrivate::verify(certificateChain, hostName);
|
||||
}
|
||||
|
||||
void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat format)
|
||||
{
|
||||
if (!data.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ QT_MODULE(Network)
|
|||
|
||||
class QDateTime;
|
||||
class QIODevice;
|
||||
class QSslError;
|
||||
class QSslKey;
|
||||
class QStringList;
|
||||
template <typename T, typename U> class QMultiMap;
|
||||
|
|
@ -122,6 +123,8 @@ public:
|
|||
static QList<QSslCertificate> fromData(
|
||||
const QByteArray &data, QSsl::EncodingFormat format = QSsl::Pem);
|
||||
|
||||
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName = QString());
|
||||
|
||||
Qt::HANDLE handle() const;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1283,33 +1283,14 @@ bool QSslSocketBackendPrivate::startHandshake()
|
|||
// if we're the server, don't check CN
|
||||
if (mode == QSslSocket::SslClientMode) {
|
||||
QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
|
||||
QStringList commonNameList = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
|
||||
bool matched = false;
|
||||
|
||||
foreach (const QString &commonName, commonNameList) {
|
||||
if (isMatchingHostname(commonName.toLower(), peerName.toLower())) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
foreach (const QString &altName, configuration.peerCertificate
|
||||
.alternateSubjectNames().values(QSsl::DnsEntry)) {
|
||||
if (isMatchingHostname(altName.toLower(), peerName.toLower())) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
// No matches in common names or alternate names.
|
||||
QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
|
||||
errors << error;
|
||||
emit q->peerVerifyError(error);
|
||||
if (q->state() != QAbstractSocket::ConnectedState)
|
||||
return false;
|
||||
if (!isMatchingHostname(configuration.peerCertificate, peerName)) {
|
||||
// No matches in common names or alternate names.
|
||||
QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
|
||||
errors << error;
|
||||
emit q->peerVerifyError(error);
|
||||
if (q->state() != QAbstractSocket::ConnectedState)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1444,6 +1425,25 @@ QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
|
|||
return errorString;
|
||||
}
|
||||
|
||||
bool QSslSocketBackendPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName)
|
||||
{
|
||||
QStringList commonNameList = cert.subjectInfo(QSslCertificate::CommonName);
|
||||
|
||||
foreach (const QString &commonName, commonNameList) {
|
||||
if (isMatchingHostname(commonName.toLower(), peerName.toLower())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const QString &altName, cert.alternateSubjectNames().values(QSsl::DnsEntry)) {
|
||||
if (isMatchingHostname(altName.toLower(), peerName.toLower())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QString &hostname)
|
||||
{
|
||||
int wildcard = cn.indexOf(QLatin1Char('*'));
|
||||
|
|
@ -1484,4 +1484,133 @@ bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QStri
|
|||
return true;
|
||||
}
|
||||
|
||||
QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certificateChain, const QString &hostName)
|
||||
{
|
||||
QList<QSslError> errors;
|
||||
if (certificateChain.count() <= 0) {
|
||||
errors << QSslError(QSslError::UnspecifiedError);
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Setup the store with the default CA certificates
|
||||
X509_STORE *certStore = q_X509_STORE_new();
|
||||
if (!certStore) {
|
||||
qWarning() << "Unable to create certificate store";
|
||||
errors << QSslError(QSslError::UnspecifiedError);
|
||||
return errors;
|
||||
}
|
||||
|
||||
QList<QSslCertificate> expiredCerts;
|
||||
|
||||
foreach (const QSslCertificate &caCertificate, QSslSocket::defaultCaCertificates()) {
|
||||
// add expired certs later, so that the
|
||||
// valid ones are used before the expired ones
|
||||
if (!caCertificate.isValid()) {
|
||||
expiredCerts.append(caCertificate);
|
||||
} else {
|
||||
q_X509_STORE_add_cert(certStore, (X509 *)caCertificate.handle());
|
||||
}
|
||||
}
|
||||
|
||||
bool addExpiredCerts = true;
|
||||
#if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
|
||||
//On Leopard SSL does not work if we add the expired certificates.
|
||||
if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
|
||||
addExpiredCerts = false;
|
||||
#endif
|
||||
// now add the expired certs
|
||||
if (addExpiredCerts) {
|
||||
foreach (const QSslCertificate &caCertificate, expiredCerts) {
|
||||
q_X509_STORE_add_cert(certStore, (X509 *)caCertificate.handle());
|
||||
}
|
||||
}
|
||||
|
||||
_q_sslErrorList()->mutex.lock();
|
||||
|
||||
// Register a custom callback to get all verification errors.
|
||||
X509_STORE_set_verify_cb_func(certStore, q_X509Callback);
|
||||
|
||||
// Build the chain of intermediate certificates
|
||||
STACK_OF(X509) *intermediates = 0;
|
||||
if (certificateChain.length() > 1) {
|
||||
intermediates = (STACK_OF(X509) *) q_sk_new_null();
|
||||
|
||||
if (!intermediates) {
|
||||
q_X509_STORE_free(certStore);
|
||||
errors << QSslError(QSslError::UnspecifiedError);
|
||||
return errors;
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
foreach (const QSslCertificate &cert, certificateChain) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
q_sk_push( (_STACK *)intermediates, (X509 *)cert.handle());
|
||||
#else
|
||||
q_sk_push( (STACK *)intermediates, (X509 *)cert.handle());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
X509_STORE_CTX *storeContext = q_X509_STORE_CTX_new();
|
||||
if (!storeContext) {
|
||||
q_X509_STORE_free(certStore);
|
||||
errors << QSslError(QSslError::UnspecifiedError);
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (!q_X509_STORE_CTX_init(storeContext, certStore, (X509 *)certificateChain[0].handle(), intermediates)) {
|
||||
q_X509_STORE_CTX_free(storeContext);
|
||||
q_X509_STORE_free(certStore);
|
||||
errors << QSslError(QSslError::UnspecifiedError);
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Now we can actually perform the verification of the chain we have built.
|
||||
// We ignore the result of this function since we process errors via the
|
||||
// callback.
|
||||
(void) q_X509_verify_cert(storeContext);
|
||||
|
||||
q_X509_STORE_CTX_free(storeContext);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
q_sk_free( (_STACK *) intermediates);
|
||||
#else
|
||||
q_sk_free( (STACK *) intermediates);
|
||||
#endif
|
||||
|
||||
// Now process the errors
|
||||
const QList<QPair<int, int> > errorList = _q_sslErrorList()->errors;
|
||||
_q_sslErrorList()->errors.clear();
|
||||
|
||||
_q_sslErrorList()->mutex.unlock();
|
||||
|
||||
// Translate the errors
|
||||
if (QSslCertificatePrivate::isBlacklisted(certificateChain[0])) {
|
||||
QSslError error(QSslError::CertificateBlacklisted, certificateChain[0]);
|
||||
errors << error;
|
||||
}
|
||||
|
||||
// Check the certificate name against the hostname if one was specified
|
||||
if ((!hostName.isEmpty()) && (!isMatchingHostname(certificateChain[0], hostName))) {
|
||||
// No matches in common names or alternate names.
|
||||
QSslError error(QSslError::HostNameMismatch, certificateChain[0]);
|
||||
errors << error;
|
||||
}
|
||||
|
||||
// Translate errors from the error list into QSslErrors.
|
||||
for (int i = 0; i < errorList.size(); ++i) {
|
||||
const QPair<int, int> &errorAndDepth = errorList.at(i);
|
||||
int err = errorAndDepth.first;
|
||||
int depth = errorAndDepth.second;
|
||||
errors << _q_OpenSSL_to_QSslError(err, certificateChain.value(depth));
|
||||
}
|
||||
|
||||
q_X509_STORE_free(certStore);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -120,7 +120,9 @@ public:
|
|||
|
||||
static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher);
|
||||
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
|
||||
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
|
||||
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
|
||||
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName);
|
||||
static QString getErrorsFromOpenSsl();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -157,9 +157,13 @@ DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
|
|||
DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
|
||||
DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
|
||||
DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
|
||||
DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
|
||||
DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
|
||||
#else
|
||||
DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
|
||||
DEFINEFUNC2(void, sk_push, STACK *a, a, void *b, b, return, DUMMYARG)
|
||||
DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
|
||||
DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
|
||||
#endif
|
||||
|
|
@ -710,6 +714,8 @@ bool q_resolveOpenSslSymbols()
|
|||
RESOLVEFUNC(RAND_seed)
|
||||
RESOLVEFUNC(RAND_status)
|
||||
RESOLVEFUNC(RSA_free)
|
||||
RESOLVEFUNC(sk_new_null)
|
||||
RESOLVEFUNC(sk_push)
|
||||
RESOLVEFUNC(sk_free)
|
||||
RESOLVEFUNC(sk_num)
|
||||
RESOLVEFUNC(sk_pop_free)
|
||||
|
|
|
|||
|
|
@ -263,9 +263,13 @@ void q_RSA_free(RSA *a);
|
|||
int q_sk_num(STACK *a);
|
||||
void q_sk_pop_free(STACK *a, void (*b)(void *));
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
_STACK *q_sk_new_null();
|
||||
void q_sk_push(_STACK *st, void *data);
|
||||
void q_sk_free(_STACK *a);
|
||||
void * q_sk_value(STACK *a, int b);
|
||||
#else
|
||||
STACK *q_sk_new_null();
|
||||
void q_sk_push(STACK *st, void *data);
|
||||
void q_sk_free(STACK *a);
|
||||
char * q_sk_value(STACK *a, int b);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1638,7 +1638,8 @@ QGraphicsScene::~QGraphicsScene()
|
|||
Q_D(QGraphicsScene);
|
||||
|
||||
// Remove this scene from qApp's global scene list.
|
||||
qApp->d_func()->scene_list.removeAll(this);
|
||||
if (!QApplicationPrivate::is_app_closing)
|
||||
qApp->d_func()->scene_list.removeAll(this);
|
||||
|
||||
clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ static void my_terminate_handler()
|
|||
#ifdef __GLIBC__
|
||||
/* Use glibc's memory allocation hooks */
|
||||
|
||||
// From glibc 2.14, the malloc hook variables are declared volatile.
|
||||
// Note: The malloc hook implementation is marked as deprecated.
|
||||
|
||||
#if !defined(__MALLOC_HOOK_VOLATILE)
|
||||
# define __MALLOC_HOOK_VOLATILE
|
||||
#endif
|
||||
|
||||
/* our hooks */
|
||||
static void *my_malloc_hook(size_t, const void *);
|
||||
static void *my_realloc_hook(void *, size_t, const void *);
|
||||
|
|
@ -71,16 +78,17 @@ static void *my_memalign_hook(size_t, size_t, const void *);
|
|||
static void my_free_hook(void *, const void *);
|
||||
|
||||
/* original hooks. */
|
||||
static void *(*old_malloc_hook)(size_t, const void *);
|
||||
static void *(*old_realloc_hook)(void *, size_t, const void *);
|
||||
static void *(*old_memalign_hook)(size_t, size_t, const void *);
|
||||
static void (*old_free_hook)(void *, const void *);
|
||||
static void *(*__MALLOC_HOOK_VOLATILE old_malloc_hook)(size_t, const void *);
|
||||
static void *(*__MALLOC_HOOK_VOLATILE old_realloc_hook)(void *, size_t, const void *);
|
||||
static void *(*__MALLOC_HOOK_VOLATILE old_memalign_hook)(size_t, size_t, const void *);
|
||||
static void (*__MALLOC_HOOK_VOLATILE old_free_hook)(void *, const void *);
|
||||
|
||||
/* initializer function */
|
||||
static void my_init_hook();
|
||||
|
||||
/* Override initialising hook from the C library. */
|
||||
void (*__malloc_initialize_hook) (void) = my_init_hook;
|
||||
|
||||
void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = my_init_hook;
|
||||
|
||||
static void disableHooks()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ private slots:
|
|||
void byteRefDetaching() const;
|
||||
|
||||
void reserve();
|
||||
|
||||
void literals();
|
||||
};
|
||||
|
||||
tst_QByteArray::tst_QByteArray()
|
||||
|
|
@ -1527,14 +1529,38 @@ void tst_QByteArray::reserve()
|
|||
QVERIFY(qba.capacity() == capacity);
|
||||
char *data = qba.data();
|
||||
|
||||
// FIXME count from 0 to make it fail
|
||||
for (int i = 1; i < capacity; i++) {
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
qba.resize(i);
|
||||
QVERIFY(capacity == qba.capacity());
|
||||
QVERIFY(data == qba.data());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QByteArray::literals()
|
||||
{
|
||||
#if defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)
|
||||
QByteArray str(QByteArrayLiteral("abcd"));
|
||||
|
||||
QVERIFY(str.length() == 4);
|
||||
QVERIFY(str == "abcd");
|
||||
QVERIFY(str.data_ptr()->ref == -1);
|
||||
QVERIFY(str.data_ptr()->offset == 0);
|
||||
|
||||
const char *s = str.constData();
|
||||
QByteArray str2 = str;
|
||||
QVERIFY(str2.constData() == s);
|
||||
|
||||
// detach on non const access
|
||||
QVERIFY(str.data() != s);
|
||||
|
||||
QVERIFY(str2.constData() == s);
|
||||
QVERIFY(str2.data() != s);
|
||||
|
||||
#else
|
||||
QSKIP("Only tested on c++0x compliant compiler or gcc", SkipAll);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char globalChar = '1';
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QByteArray)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ private slots:
|
|||
void toText();
|
||||
void multipleCommonNames();
|
||||
void subjectAndIssuerAttributes();
|
||||
void verify();
|
||||
|
||||
// ### add tests for certificate bundles (multiple certificates concatenated into a single
|
||||
// structure); both PEM and DER formatted
|
||||
|
|
@ -901,6 +902,71 @@ void tst_QSslCertificate::subjectAndIssuerAttributes()
|
|||
QVERIFY(attributes.contains(QByteArray("1.3.6.1.4.1.311.60.2.1.3")));
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::verify()
|
||||
{
|
||||
QList<QSslError> errors;
|
||||
QList<QSslCertificate> toVerify;
|
||||
|
||||
// Empty chain is unspecified error
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
QVERIFY(errors.count() == 1);
|
||||
QVERIFY(errors[0] == QSslError(QSslError::UnspecifiedError));
|
||||
errors.clear();
|
||||
|
||||
// Verify a valid cert signed by a CA
|
||||
QList<QSslCertificate> caCerts = QSslCertificate::fromPath(SRCDIR "verify-certs/cacert.pem");
|
||||
QSslSocket::addDefaultCaCertificate(caCerts.first());
|
||||
|
||||
toVerify = QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem");
|
||||
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
QVERIFY(errors.count() == 0);
|
||||
errors.clear();
|
||||
|
||||
// Test a blacklisted certificate
|
||||
toVerify = QSslCertificate::fromPath(SRCDIR "verify-certs/test-addons-mozilla-org-cert.pem");
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
bool foundBlack = false;
|
||||
foreach (const QSslError &error, errors) {
|
||||
if (error.error() == QSslError::CertificateBlacklisted) {
|
||||
foundBlack = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY(foundBlack);
|
||||
errors.clear();
|
||||
|
||||
// This one is expired and untrusted
|
||||
toVerify = QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem");
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
QVERIFY(errors.contains(QSslError(QSslError::SelfSignedCertificate, toVerify[0])));
|
||||
QVERIFY(errors.contains(QSslError(QSslError::CertificateExpired, toVerify[0])));
|
||||
errors.clear();
|
||||
toVerify.clear();
|
||||
|
||||
// This one is signed by a valid cert, but the signer is not a valid CA
|
||||
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-not-ca-cert.pem").first();
|
||||
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem").first();
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
QVERIFY(errors.contains(QSslError(QSslError::InvalidCaCertificate, toVerify[1])));
|
||||
toVerify.clear();
|
||||
|
||||
// This one is signed by a valid cert, and the signer is a valid CA
|
||||
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-is-ca-cert.pem").first();
|
||||
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-ca-cert.pem").first();
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
QVERIFY(errors.length() == 0);
|
||||
|
||||
// Recheck the above with hostname validation
|
||||
errors = QSslCertificate::verify(toVerify, QLatin1String("example.com"));
|
||||
QVERIFY(errors.length() == 0);
|
||||
|
||||
// Recheck the above with a bad hostname
|
||||
errors = QSslCertificate::verify(toVerify, QLatin1String("fail.example.com"));
|
||||
QVERIFY(errors.contains(QSslError(QSslError::HostNameMismatch, toVerify[0])));
|
||||
toVerify.clear();
|
||||
}
|
||||
|
||||
#endif // QT_NO_OPENSSL
|
||||
|
||||
QTEST_MAIN(tst_QSslCertificate)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
openssl verify -CAfile cacert.pem -untrusted test-intermediate-ca-cert.pem test-intermediate-is-ca-cert.pem
|
||||
openssl verify -CAfile cacert.pem -untrusted test-ocsp-good-cert.pem test-intermediate-not-ca-cert.pem
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIID6zCCAtOgAwIBAgIJALIOhqebAhS9MA0GCSqGSIb3DQEBBQUAMIGrMSYwJAYD
|
||||
VQQDEx1XZXN0cG9pbnQgQ2VydGlmaWNhdGUgVGVzdCBDQTETMBEGA1UECBMKTGFu
|
||||
Y2FzaGlyZTELMAkGA1UEBhMCVUsxHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUu
|
||||
Y29tMUAwPgYDVQQKEzdXZXN0cG9pbnQgQ2VydGlmaWNhdGUgVGVzdCBSb290IENl
|
||||
cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTExMDYyNjE5MzYzOVoXDTExMDcyNjE5
|
||||
MzYzOVowgasxJjAkBgNVBAMTHVdlc3Rwb2ludCBDZXJ0aWZpY2F0ZSBUZXN0IENB
|
||||
MRMwEQYDVQQIEwpMYW5jYXNoaXJlMQswCQYDVQQGEwJVSzEdMBsGCSqGSIb3DQEJ
|
||||
ARYOY2FAZXhhbXBsZS5jb20xQDA+BgNVBAoTN1dlc3Rwb2ludCBDZXJ0aWZpY2F0
|
||||
ZSBUZXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCoP3znXuxcIAWkyu51aPWwXYX0kSPnBO1gcJj6
|
||||
xQa4ycOHv9Cs9XTVTGvpj4aoc6lP+6/jUe14cVCR7018zHRe7u5g4ozO1aZqISqS
|
||||
Y4hdWkTSFPmFoiyXkACl0ZGwcfv6QdFhNnK4COBrff4D6lndfQUZu8CnRYxlKGuR
|
||||
1vGiUcJ88t0dDmMEFEdYNtlDnYlxXHbTS4VdRb2u3EGFzV24ENJwgqYuFrBAG/+N
|
||||
TRXahWMsdfP0whCYJOsaNBwXaoeoxGlYz35gMU8A8AFmYOJLohsWqHcHmMV3X6hn
|
||||
aKGnL3nOa8zlNKNr948Dwenucaggf5KquDCHVf2Ms+ROxlfTAgMBAAGjEDAOMAwG
|
||||
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGmY4+AeMyx+FkpPxeNY3DAH
|
||||
Jys0WfndLZFABARYfKdJE1dqQi3uXaRkKMkV7npb46cw92jmwFT+v9rHd88UmgMs
|
||||
KGJNWjARD6Ai1dzenMNYBJz9GFkDJ0Pr4Gqj2tR9JuzEOdxss+nZ4r6vhC+/yeAB
|
||||
4jGT4QMuYU+14Rfsv5Aw0HjbcH955zTy1pJ6ck9OWWyzET8ALxz+RTFOok/4r4++
|
||||
yhE5Hh8+2aE52AcZqKa4hKXdVBCb9oewl93h3rmYcA/Yz36w+GRkSnOPZUgDDL5D
|
||||
HKnICDidtf9ZZBZ4iJxaBg4iCraeuei20V+0g+9/1aoIWJ5TrelVYVCx8O0x+E0=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIF+DCCBOCgAwIBAgIRAJI51TSPQNFpWnRUcOHyP0MwDQYJKoZIhvcNAQEFBQAw
|
||||
gZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtl
|
||||
IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMY
|
||||
aHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR8wHQYDVQQDExZVVE4tVVNFUkZpcnN0
|
||||
LUhhcmR3YXJlMB4XDTExMDMxNTAwMDAwMFoXDTE0MDMxNDIzNTk1OVowgeIxCzAJ
|
||||
BgNVBAYTAlVTMQ4wDAYDVQQREwUzODQ3NzEQMA4GA1UECBMHRmxvcmlkYTEQMA4G
|
||||
A1UEBxMHRW5nbGlzaDEXMBUGA1UECRMOU2VhIFZpbGxhZ2UgMTAxFDASBgNVBAoT
|
||||
C0dvb2dsZSBMdGQuMRMwEQYDVQQLEwpUZWNoIERlcHQuMSgwJgYDVQQLEx9Ib3N0
|
||||
ZWQgYnkgR1RJIEdyb3VwIENvcnBvcmF0aW9uMRQwEgYDVQQLEwtQbGF0aW51bVNT
|
||||
TDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEub3JnMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAq8ZtNvMVc3iDc850hdWu7LLw4CQfE4O4IKy7mv6Iu6uh
|
||||
HQsfRQCqSbc1Nwxq70dMudG+41cSBI2Sx7bsAby22seBOCCtcoXmDvyBbAetaHY4
|
||||
xUTXzMZKxZc+ZPRR5vB+suxW9yWCTUmYyxaY3SPxiZHRF5dAmSbW4qIrXt+9ifIb
|
||||
GlMtzFBBetA9KgxVcBQB6VhJEHoLk4KL4R7tOoAQgs6WijTwzNfTubRQh1VUCbid
|
||||
QihVAOWMNVS/3SWRRrcN5V2DqOWL+4TkPK522sRDK1t0C/i+XWjxeFu1zn3xXZlA
|
||||
2sruOIFQvpihbLgkrfOvjA/XESgshBhMfbXZjzC1GwIDAQABo4IB8DCCAewwHwYD
|
||||
VR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0UwHQYDVR0OBBYEFN2A0lQ990xw
|
||||
yqOw3TR6MuToO1o7MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1Ud
|
||||
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBGBgNVHSAEPzA9MDsGDCsGAQQBsjEB
|
||||
AgEDBDArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQ
|
||||
UzB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9VVE4t
|
||||
VVNFUkZpcnN0LUhhcmR3YXJlLmNybDA2oDSgMoYwaHR0cDovL2NybC5jb21vZG8u
|
||||
bmV0L1VUTi1VU0VSRmlyc3QtSGFyZHdhcmUuY3JsMHEGCCsGAQUFBwEBBGUwYzA7
|
||||
BggrBgEFBQcwAoYvaHR0cDovL2NydC5jb21vZG9jYS5jb20vVVROQWRkVHJ1c3RT
|
||||
ZXJ2ZXJDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNv
|
||||
bTA1BgNVHREELjAsghJhZGRvbnMubW96aWxsYS5vcmeCFnd3dy5hZGRvbnMubW96
|
||||
aWxsYS5vcmcwDQYJKoZIhvcNAQEFBQADggEBADM7YxX8sewULJPddZTegVrZTpm+
|
||||
+0qkOVVNoUB63hMqh6k3z+jV+63Re21vjCCHglTmV0m8ICiEzdYB2ZOLF24jZuWE
|
||||
yIA/xqFwgOTsTR35/JFac2IpmvcgHGHgizmfyrx+jd282bHjn57fFVORIVIL2Roj
|
||||
D2Y226yTlkqjpSLPKfeimaj2ttlArtl+tvZYLpusNspkj2VS3IacgqtuUEvaX/oF
|
||||
AIgwDt6NVr+BR409BuKyYpJnj57ImrLlBrhwJLh3fCMKOMN5CNixUZ2slRHHQBee
|
||||
oxyP8hGnaCfaSQWEGHxYLQFnXOWfoSm7SjlFL78Rqnmi7bTUtWVDt5NGitM=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 28 (0x1c)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: CN=Westpoint Certificate Test CA, ST=Lancashire, C=UK/emailAddress=ca@example.com, O=Westpoint Certificate Test Root Certification Authority
|
||||
Validity
|
||||
Not Before: Jun 26 19:36:42 2011 GMT
|
||||
Not After : Jun 23 19:36:42 2021 GMT
|
||||
Subject: ST=Lancashire, C=UK/emailAddress=test@example.com, O=Test intermediate CA
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:a7:ed:3f:86:ee:ad:f8:b7:60:44:63:fc:1b:2c:
|
||||
79:3c:90:8b:47:b8:51:b5:3e:96:6d:5d:f1:97:b3:
|
||||
de:90:b2:9a:aa:9e:54:7e:2b:b1:6d:91:ae:20:29:
|
||||
b6:69:7b:8a:e5:6c:41:10:b6:d3:73:4c:20:30:38:
|
||||
57:c9:c8:ef:67:7e:76:39:c4:1c:df:6b:73:4e:2b:
|
||||
21:2d:79:5a:c5:60:5e:85:11:52:3b:8e:ef:b0:e5:
|
||||
2f:0c:e8:a3:fc:05:27:91:08:64:ea:2e:5a:f2:82:
|
||||
0c:08:48:bc:bc:ca:60:02:1c:6a:38:eb:c8:02:a6:
|
||||
f7:e8:c8:31:20:29:e6:e4:8d
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
Authority Information Access:
|
||||
OCSP - URI:http://ocsp.example.com:8888/
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
94:1a:91:6a:05:41:0c:40:f9:46:35:e9:46:15:f1:3e:e4:d9:
|
||||
50:d6:0e:14:d8:1f:85:9e:a6:98:a2:db:db:ee:ff:56:55:6c:
|
||||
46:fd:0e:b0:03:79:a6:96:0f:c1:85:c3:3e:68:e0:17:10:a6:
|
||||
9c:10:34:88:96:f7:c8:ef:32:31:24:f4:3c:2d:eb:51:08:d6:
|
||||
87:83:f7:db:68:43:ed:d9:af:46:a2:48:74:d2:9d:c9:af:0f:
|
||||
29:42:ad:a2:cf:1e:ab:50:6f:ef:33:18:d3:07:ef:13:13:10:
|
||||
50:db:a9:56:db:f4:38:c1:db:05:fa:5a:67:92:72:69:fb:7a:
|
||||
5b:ec:d4:dd:fd:a2:21:06:59:b0:0d:48:5f:53:c1:65:94:aa:
|
||||
d4:4e:1c:e8:9f:b4:7d:9b:10:85:4a:b6:be:df:d8:33:b5:72:
|
||||
b0:ac:46:a9:67:55:1e:3e:58:a5:52:ed:b6:4a:cb:e9:d2:e5:
|
||||
f8:fe:56:b4:2c:5e:9f:3c:d1:7f:b4:eb:05:8d:46:1f:47:32:
|
||||
2b:4f:2e:ac:8d:c3:3c:eb:f1:0c:2f:3a:e0:fa:46:0b:e4:c5:
|
||||
f2:03:24:70:fc:ef:1a:fd:7b:a9:9c:d9:b6:4f:0e:74:07:52:
|
||||
23:eb:cd:66:61:67:a1:91:7f:76:a2:9d:42:54:d4:c6:5e:10:
|
||||
26:eb:37:e7
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUDCCAjigAwIBAgIBHDANBgkqhkiG9w0BAQUFADCBqzEmMCQGA1UEAxMdV2Vz
|
||||
dHBvaW50IENlcnRpZmljYXRlIFRlc3QgQ0ExEzARBgNVBAgTCkxhbmNhc2hpcmUx
|
||||
CzAJBgNVBAYTAlVLMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLmNvbTFAMD4G
|
||||
A1UEChM3V2VzdHBvaW50IENlcnRpZmljYXRlIFRlc3QgUm9vdCBDZXJ0aWZpY2F0
|
||||
aW9uIEF1dGhvcml0eTAeFw0xMTA2MjYxOTM2NDJaFw0yMTA2MjMxOTM2NDJaMGIx
|
||||
EzARBgNVBAgTCkxhbmNhc2hpcmUxCzAJBgNVBAYTAlVLMR8wHQYJKoZIhvcNAQkB
|
||||
FhB0ZXN0QGV4YW1wbGUuY29tMR0wGwYDVQQKExRUZXN0IGludGVybWVkaWF0ZSBD
|
||||
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp+0/hu6t+LdgRGP8Gyx5PJCL
|
||||
R7hRtT6WbV3xl7PekLKaqp5UfiuxbZGuICm2aXuK5WxBELbTc0wgMDhXycjvZ352
|
||||
OcQc32tzTishLXlaxWBehRFSO47vsOUvDOij/AUnkQhk6i5a8oIMCEi8vMpgAhxq
|
||||
OOvIAqb36MgxICnm5I0CAwEAAaNLMEkwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUF
|
||||
BzABhh1odHRwOi8vb2NzcC5leGFtcGxlLmNvbTo4ODg4LzAMBgNVHRMEBTADAQH/
|
||||
MA0GCSqGSIb3DQEBBQUAA4IBAQCUGpFqBUEMQPlGNelGFfE+5NlQ1g4U2B+FnqaY
|
||||
otvb7v9WVWxG/Q6wA3mmlg/BhcM+aOAXEKacEDSIlvfI7zIxJPQ8LetRCNaHg/fb
|
||||
aEPt2a9Gokh00p3Jrw8pQq2izx6rUG/vMxjTB+8TExBQ26lW2/Q4wdsF+lpnknJp
|
||||
+3pb7NTd/aIhBlmwDUhfU8FllKrUThzon7R9mxCFSra+39gztXKwrEapZ1UePlil
|
||||
Uu22Ssvp0uX4/la0LF6fPNF/tOsFjUYfRzIrTy6sjcM86/EMLzrg+kYL5MXyAyRw
|
||||
/O8a/XupnNm2Tw50B1Ij681mYWehkX92op1CVNTGXhAm6zfn
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 29 (0x1d)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: ST=Lancashire, C=UK/emailAddress=test@example.com, O=Test intermediate CA
|
||||
Validity
|
||||
Not Before: Jun 26 19:36:42 2011 GMT
|
||||
Not After : Jun 23 19:36:42 2021 GMT
|
||||
Subject: CN=example.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:ba:f2:dc:f9:77:b0:ad:fd:9d:42:4f:22:15:6d:
|
||||
87:40:ed:30:8a:04:ad:ac:7a:0b:d4:7a:a4:a7:ef:
|
||||
e0:e7:9b:f2:5e:62:56:24:ed:88:bd:bd:e3:64:d2:
|
||||
d4:b4:01:39:b8:9e:6f:c7:b0:fc:b9:fd:a8:4d:46:
|
||||
c8:9e:6a:43:82:ca:56:83:d4:4b:ea:63:d5:56:d1:
|
||||
99:46:4f:8b:28:d0:2f:db:bf:04:65:64:82:c2:61:
|
||||
aa:66:50:27:e5:7a:57:e3:72:e3:ae:22:8d:92:7e:
|
||||
25:90:a2:7c:0c:04:79:c5:ab:64:58:a9:83:79:67:
|
||||
7f:72:33:cc:5f:5b:cd:74:bb
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Authority Information Access:
|
||||
OCSP - URI:http://ocsp.example.com:8888/
|
||||
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
19:e8:ce:9d:4d:ef:cc:4f:6c:e5:ab:df:aa:e2:3c:d8:6b:a8:
|
||||
dd:b8:fa:50:e4:b6:04:fc:66:92:fb:e8:11:73:81:60:1a:88:
|
||||
b2:18:0b:8c:89:05:47:16:50:09:be:bc:a6:3c:fe:2e:45:01:
|
||||
00:e3:27:30:72:f6:93:49:7f:d0:3b:a8:0e:cb:e7:01:95:28:
|
||||
8b:40:95:f7:b1:5b:c9:ff:26:ff:ad:4a:c4:e4:99:f7:65:fc:
|
||||
e4:5e:d2:56:ea:98:42:dc:93:62:46:1a:33:53:0d:43:9d:ef:
|
||||
14:03:35:a7:13:fa:27:24:92:2f:9a:f9:0a:62:99:cc:c0:80:
|
||||
79:10
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICNjCCAZ+gAwIBAgIBHTANBgkqhkiG9w0BAQUFADBiMRMwEQYDVQQIEwpMYW5j
|
||||
YXNoaXJlMQswCQYDVQQGEwJVSzEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxl
|
||||
LmNvbTEdMBsGA1UEChMUVGVzdCBpbnRlcm1lZGlhdGUgQ0EwHhcNMTEwNjI2MTkz
|
||||
NjQyWhcNMjEwNjIzMTkzNjQyWjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCBnzAN
|
||||
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuvLc+Xewrf2dQk8iFW2HQO0wigStrHoL
|
||||
1Hqkp+/g55vyXmJWJO2Ivb3jZNLUtAE5uJ5vx7D8uf2oTUbInmpDgspWg9RL6mPV
|
||||
VtGZRk+LKNAv278EZWSCwmGqZlAn5XpX43LjriKNkn4lkKJ8DAR5xatkWKmDeWd/
|
||||
cjPMX1vNdLsCAwEAAaNIMEYwCQYDVR0TBAIwADA5BggrBgEFBQcBAQQtMCswKQYI
|
||||
KwYBBQUHMAGGHWh0dHA6Ly9vY3NwLmV4YW1wbGUuY29tOjg4ODgvMA0GCSqGSIb3
|
||||
DQEBBQUAA4GBABnozp1N78xPbOWr36riPNhrqN24+lDktgT8ZpL76BFzgWAaiLIY
|
||||
C4yJBUcWUAm+vKY8/i5FAQDjJzBy9pNJf9A7qA7L5wGVKItAlfexW8n/Jv+tSsTk
|
||||
mfdl/ORe0lbqmELck2JGGjNTDUOd7xQDNacT+ickki+a+QpimczAgHkQ
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 27 (0x1b)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: CN=example.com, ST=Lancashire, C=UK/emailAddress=test@example.com, O=Some organisation
|
||||
Validity
|
||||
Not Before: Jun 26 19:36:42 2011 GMT
|
||||
Not After : Jun 23 19:36:42 2021 GMT
|
||||
Subject: CN=example.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:d7:b6:a8:07:83:27:b8:72:da:85:ad:50:bf:c2:
|
||||
3f:cc:d4:e7:97:55:b5:45:aa:d2:cb:df:b6:34:6f:
|
||||
c2:8f:86:e2:15:8a:cd:3e:af:f5:c0:f9:2e:61:80:
|
||||
70:17:d3:db:0f:8a:e6:2c:a8:e3:12:2d:92:e1:8d:
|
||||
10:e0:e7:30:94:98:ec:b0:21:c3:86:f7:ff:29:58:
|
||||
2b:ab:b1:23:e4:ca:66:66:6a:18:b5:73:dc:c7:44:
|
||||
04:30:55:bf:f9:3b:74:f6:de:bd:d9:ef:46:b0:15:
|
||||
56:3b:43:cc:55:c2:cc:2e:5d:17:f8:04:dc:3d:bf:
|
||||
1b:cc:0a:41:61:c8:35:02:1b
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Authority Information Access:
|
||||
OCSP - URI:http://ocsp.example.com:8888/
|
||||
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
18:e2:06:f3:4b:42:46:b6:29:d1:8d:50:ef:5b:8b:e5:33:24:
|
||||
f3:f1:3e:58:4d:7f:3e:51:e9:c4:a2:cb:64:5f:d1:51:ce:8d:
|
||||
b6:15:63:23:30:4b:7c:70:30:61:ce:1f:70:bb:99:63:5b:15:
|
||||
d9:ce:aa:da:65:87:66:ab:ad:64:e8:09:37:ea:79:d0:3a:a2:
|
||||
e0:cf:0b:1b:a7:35:3d:f8:45:4c:4b:96:15:ec:fe:64:9f:e0:
|
||||
1d:04:52:35:a1:b4:7e:31:34:84:7e:e6:e0:58:1e:14:02:df:
|
||||
68:f6:b6:eb:dc:10:eb:da:fe:8e:06:ab:52:b7:ca:15:c3:8d:
|
||||
5a:8a
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICSTCCAbKgAwIBAgIBGzANBgkqhkiG9w0BAQUFADB1MRQwEgYDVQQDEwtleGFt
|
||||
cGxlLmNvbTETMBEGA1UECBMKTGFuY2FzaGlyZTELMAkGA1UEBhMCVUsxHzAdBgkq
|
||||
hkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20xGjAYBgNVBAoTEVNvbWUgb3JnYW5p
|
||||
c2F0aW9uMB4XDTExMDYyNjE5MzY0MloXDTIxMDYyMzE5MzY0MlowFjEUMBIGA1UE
|
||||
AxMLZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANe2qAeD
|
||||
J7hy2oWtUL/CP8zU55dVtUWq0svftjRvwo+G4hWKzT6v9cD5LmGAcBfT2w+K5iyo
|
||||
4xItkuGNEODnMJSY7LAhw4b3/ylYK6uxI+TKZmZqGLVz3MdEBDBVv/k7dPbevdnv
|
||||
RrAVVjtDzFXCzC5dF/gE3D2/G8wKQWHINQIbAgMBAAGjSDBGMAkGA1UdEwQCMAAw
|
||||
OQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC5leGFtcGxl
|
||||
LmNvbTo4ODg4LzANBgkqhkiG9w0BAQUFAAOBgQAY4gbzS0JGtinRjVDvW4vlMyTz
|
||||
8T5YTX8+UenEostkX9FRzo22FWMjMEt8cDBhzh9wu5ljWxXZzqraZYdmq61k6Ak3
|
||||
6nnQOqLgzwsbpzU9+EVMS5YV7P5kn+AdBFI1obR+MTSEfubgWB4UAt9o9rbr3BDr
|
||||
2v6OBqtSt8oVw41aig==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 1 (0x1)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: CN=Westpoint Certificate Test CA, ST=Lancashire, C=UK/emailAddress=ca@example.com, O=Westpoint Certificate Test Root Certification Authority
|
||||
Validity
|
||||
Not Before: Jun 26 19:36:39 2011 GMT
|
||||
Not After : Jun 23 19:36:39 2021 GMT
|
||||
Subject: CN=example.com, ST=Lancashire, C=UK/emailAddress=test@example.com, O=Some organisation
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:c7:d8:d4:a7:c0:a0:e7:82:b4:ec:67:52:bf:50:
|
||||
bf:b9:a6:f2:10:19:67:53:8c:99:5e:c8:fc:03:07:
|
||||
71:24:a3:a9:c4:49:f8:15:34:4a:45:ee:92:81:aa:
|
||||
3c:5a:1a:42:2b:db:d7:30:9e:85:e6:b8:74:bc:ae:
|
||||
f0:ae:7d:05:4e:c9:0f:00:33:b2:86:ba:b6:49:9a:
|
||||
07:18:92:f9:35:69:d2:ac:39:b9:85:ac:78:99:81:
|
||||
06:f5:fa:2e:5b:18:f7:6a:16:d0:e6:f9:71:0f:b0:
|
||||
05:c4:f0:5f:ed:90:81:3c:96:f5:e3:45:73:72:5f:
|
||||
ce:dc:ce:0b:56:2e:be:d2:eb
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Authority Information Access:
|
||||
OCSP - URI:http://ocsp.example.com:8888/
|
||||
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
76:84:40:52:b8:1d:6c:64:58:f1:10:30:03:db:16:91:da:b1:
|
||||
70:28:54:6f:0f:32:1c:84:65:b3:14:99:c6:59:f9:ec:f9:3f:
|
||||
46:1f:12:77:4e:f1:26:ad:46:4b:ee:48:78:bd:bf:2a:11:01:
|
||||
5b:02:cd:d2:6e:2d:8c:08:ea:a7:5a:18:16:71:e8:5d:c8:e7:
|
||||
7d:f2:4f:23:6c:59:3c:17:93:02:60:c0:d0:62:09:d2:a3:7d:
|
||||
90:77:6c:f7:0c:b2:e4:9e:73:d2:f8:dd:a3:0c:70:36:2f:5a:
|
||||
58:2b:2d:3e:0e:71:43:b2:14:00:e2:eb:2d:0e:09:91:47:83:
|
||||
e8:02:d4:7d:5c:1f:ce:d8:f5:ad:1f:ee:82:4f:23:47:db:f4:
|
||||
71:48:1b:e1:82:f1:d1:86:db:0f:b6:bb:3a:8f:40:05:48:b7:
|
||||
f2:a8:c7:c9:46:e1:ea:28:b2:02:00:90:04:00:19:32:6f:8d:
|
||||
3e:c2:67:ca:b0:80:3a:32:e3:35:92:18:a2:62:30:9d:7a:f5:
|
||||
13:3b:c7:00:3f:4e:17:a9:01:5d:a1:2c:71:76:d7:37:c8:16:
|
||||
92:f8:82:69:15:5f:7d:5e:b0:ba:0b:9f:bd:53:ad:e5:a6:b3:
|
||||
bc:6b:e4:1a:79:29:31:ff:ff:a1:2d:0b:30:46:d3:a5:2d:62:
|
||||
e6:be:68:df
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDYDCCAkigAwIBAgIBATANBgkqhkiG9w0BAQUFADCBqzEmMCQGA1UEAxMdV2Vz
|
||||
dHBvaW50IENlcnRpZmljYXRlIFRlc3QgQ0ExEzARBgNVBAgTCkxhbmNhc2hpcmUx
|
||||
CzAJBgNVBAYTAlVLMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLmNvbTFAMD4G
|
||||
A1UEChM3V2VzdHBvaW50IENlcnRpZmljYXRlIFRlc3QgUm9vdCBDZXJ0aWZpY2F0
|
||||
aW9uIEF1dGhvcml0eTAeFw0xMTA2MjYxOTM2MzlaFw0yMTA2MjMxOTM2MzlaMHUx
|
||||
FDASBgNVBAMTC2V4YW1wbGUuY29tMRMwEQYDVQQIEwpMYW5jYXNoaXJlMQswCQYD
|
||||
VQQGEwJVSzEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTEaMBgGA1UE
|
||||
ChMRU29tZSBvcmdhbmlzYXRpb24wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
|
||||
AMfY1KfAoOeCtOxnUr9Qv7mm8hAZZ1OMmV7I/AMHcSSjqcRJ+BU0SkXukoGqPFoa
|
||||
Qivb1zCehea4dLyu8K59BU7JDwAzsoa6tkmaBxiS+TVp0qw5uYWseJmBBvX6LlsY
|
||||
92oW0Ob5cQ+wBcTwX+2QgTyW9eNFc3JfztzOC1YuvtLrAgMBAAGjSDBGMAkGA1Ud
|
||||
EwQCMAAwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC5l
|
||||
eGFtcGxlLmNvbTo4ODg4LzANBgkqhkiG9w0BAQUFAAOCAQEAdoRAUrgdbGRY8RAw
|
||||
A9sWkdqxcChUbw8yHIRlsxSZxln57Pk/Rh8Sd07xJq1GS+5IeL2/KhEBWwLN0m4t
|
||||
jAjqp1oYFnHoXcjnffJPI2xZPBeTAmDA0GIJ0qN9kHds9wyy5J5z0vjdowxwNi9a
|
||||
WCstPg5xQ7IUAOLrLQ4JkUeD6ALUfVwfztj1rR/ugk8jR9v0cUgb4YLx0YbbD7a7
|
||||
Oo9ABUi38qjHyUbh6iiyAgCQBAAZMm+NPsJnyrCAOjLjNZIYomIwnXr1EzvHAD9O
|
||||
F6kBXaEscXbXN8gWkviCaRVffV6wugufvVOt5aazvGvkGnkpMf//oS0LMEbTpS1i
|
||||
5r5o3w==
|
||||
-----END CERTIFICATE-----
|
||||
Loading…
Reference in New Issue