summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/crypto/CryptoDigest.h60
-rw-r--r--Source/WebCore/platform/crypto/qt/CryptoDigestQt.cpp93
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h1
-rw-r--r--Source/WebCore/platform/graphics/WOFFFileFormat.cpp8
-rw-r--r--Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp10
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp35
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp1
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp64
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp15
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h1
-rw-r--r--Source/WebCore/platform/network/qt/BlobUrlConversion.cpp98
-rw-r--r--Source/WebCore/platform/network/qt/BlobUrlConversion.h29
-rw-r--r--Source/WebCore/platform/network/qt/CookieJarQt.cpp32
-rw-r--r--Source/WebCore/platform/network/qt/DNSQt.cpp7
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp5
-rw-r--r--Source/WebCore/platform/network/qt/ResourceRequestQt.cpp82
-rw-r--r--Source/WebCore/platform/qt/EventLoopQt.cpp2
-rw-r--r--Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp52
-rw-r--r--Source/WebCore/platform/qt/UserAgentQt.cpp4
-rw-r--r--Source/WebCore/platform/text/TextCodecUTF8.cpp156
-rw-r--r--Source/WebCore/platform/text/TextCodecUTF8.h19
-rw-r--r--Source/WebCore/platform/text/TextEncoding.h106
-rw-r--r--Source/WebCore/platform/text/TextEncodingRegistry.h30
23 files changed, 658 insertions, 252 deletions
diff --git a/Source/WebCore/platform/crypto/CryptoDigest.h b/Source/WebCore/platform/crypto/CryptoDigest.h
new file mode 100644
index 000000000..31f075aa3
--- /dev/null
+++ b/Source/WebCore/platform/crypto/CryptoDigest.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CryptoDigest_h
+#define CryptoDigest_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct CryptoDigestContext;
+
+class CryptoDigest {
+ WTF_MAKE_NONCOPYABLE(CryptoDigest);
+public:
+ enum class Algorithm {
+ SHA_1,
+ SHA_224,
+ SHA_256,
+ SHA_384,
+ SHA_512,
+ };
+ static std::unique_ptr<CryptoDigest> create(Algorithm);
+ ~CryptoDigest();
+
+ void addBytes(const void* input, size_t length);
+ Vector<uint8_t> computeHash();
+
+private:
+ CryptoDigest();
+
+ std::unique_ptr<CryptoDigestContext> m_context;
+};
+
+} // namespace WebCore
+
+#endif // CryptoDigest_h
diff --git a/Source/WebCore/platform/crypto/qt/CryptoDigestQt.cpp b/Source/WebCore/platform/crypto/qt/CryptoDigestQt.cpp
new file mode 100644
index 000000000..1dcb8bf72
--- /dev/null
+++ b/Source/WebCore/platform/crypto/qt/CryptoDigestQt.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 Konstantin Tokavev <annulen@yandex.ru>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CryptoDigest.h"
+
+#include <QCryptographicHash>
+#include <QDebug>
+
+namespace WebCore {
+
+static QCryptographicHash::Algorithm toQtAlgorithm(CryptoDigest::Algorithm algorithm)
+{
+ switch (algorithm) {
+ case CryptoDigest::Algorithm::SHA_1:
+ return QCryptographicHash::Sha1;
+
+ case CryptoDigest::Algorithm::SHA_224:
+ return QCryptographicHash::Sha224;
+
+ case CryptoDigest::Algorithm::SHA_256:
+ return QCryptographicHash::Sha256;
+
+ case CryptoDigest::Algorithm::SHA_384:
+ return QCryptographicHash::Sha384;
+
+ case CryptoDigest::Algorithm::SHA_512:
+ return QCryptographicHash::Sha512;
+ }
+
+ ASSERT_NOT_REACHED();
+ return QCryptographicHash::Algorithm();
+}
+
+struct CryptoDigestContext {
+ CryptoDigestContext(QCryptographicHash::Algorithm algorithm)
+ : hash(algorithm)
+ {
+ }
+ QCryptographicHash hash;
+};
+
+CryptoDigest::CryptoDigest()
+{
+}
+
+CryptoDigest::~CryptoDigest()
+{
+}
+
+std::unique_ptr<CryptoDigest> CryptoDigest::create(CryptoDigest::Algorithm algorithm)
+{
+ std::unique_ptr<CryptoDigest> digest(new CryptoDigest);
+ digest->m_context.reset(new CryptoDigestContext(toQtAlgorithm(algorithm)));
+ return digest;
+}
+
+void CryptoDigest::addBytes(const void* input, size_t length)
+{
+ m_context->hash.addData(static_cast<const char*>(input), length);
+}
+
+Vector<uint8_t> CryptoDigest::computeHash()
+{
+ QByteArray digest = m_context->hash.result();
+ Vector<uint8_t> result(digest.size());
+ memcpy(result.data(), digest.constData(), digest.size());
+ return result;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index d7f529cf8..8b821fa98 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -563,6 +563,7 @@ public:
#if PLATFORM(QT)
void pushTransparencyLayerInternal(const QRect&, qreal, QPixmap&);
+ void popTransparencyLayerInternal();
void takeOwnershipOfPlatformContext();
#endif
diff --git a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
index c2323cf04..d8f4a5da7 100644
--- a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
+++ b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
@@ -31,8 +31,8 @@
#include <wtf/ByteOrder.h>
#if USE(WOFF2)
-#include "woff2_common.h"
-#include "woff2_dec.h"
+#include <woff2/decode.h>
+static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2"
#endif
namespace WebCore {
@@ -84,7 +84,7 @@ bool isWOFF(SharedBuffer& buffer)
return false;
#if USE(WOFF2)
- return signature == woffSignature || signature == woff2::kWoff2Signature;
+ return signature == woffSignature || signature == kWoff2Signature;
#else
return signature == woffSignature;
#endif
@@ -140,7 +140,7 @@ bool convertWOFFToSfnt(SharedBuffer& woff, Vector<char>& sfnt)
}
#if USE(WOFF2)
- if (signature == woff2::kWoff2Signature) {
+ if (signature == kWoff2Signature) {
const uint8_t* woffData = reinterpret_cast_ptr<const uint8_t*>(woff.data());
const size_t woffSize = woff.size();
const size_t sfntSize = woff2::ComputeWOFF2FinalSize(woffData, woffSize);
diff --git a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
index c502a0c3b..8ae96b94c 100644
--- a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
@@ -29,7 +29,11 @@
#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "TemporaryOpenGLSetting.h"
-#if USE(OPENGL_ES_2)
+#if PLATFORM(QT)
+#define FUNCTIONS m_functions
+#include "OpenGLShimsQt.h"
+#define glIsEnabled(...) m_functions->glIsEnabled(__VA_ARGS__)
+#elif USE(OPENGL_ES_2)
#include <GLES2/gl2.h>
#include "OpenGLESShims.h"
#elif PLATFORM(IOS)
@@ -38,10 +42,6 @@
#include <OpenGL/gl.h>
#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
-#elif PLATFORM(QT)
-#define FUNCTIONS m_functions
-#include "OpenGLShimsQt.h"
-#define glIsEnabled(...) m_functions->glIsEnabled(__VA_ARGS__)
#endif
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 260081946..1e041050e 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -358,7 +358,7 @@ void GraphicsContext::restorePlatformState()
{
if (!m_data->layers.isEmpty() && !m_data->layers.top()->alphaMask.isNull())
if (!--m_data->layers.top()->saveCounter)
- endPlatformTransparencyLayer();
+ popTransparencyLayerInternal();
m_data->p()->restore();
}
@@ -1313,18 +1313,39 @@ void GraphicsContext::beginPlatformTransparencyLayer(float opacity)
++m_data->layerCount;
}
+void GraphicsContext::popTransparencyLayerInternal()
+{
+ TransparencyLayer* layer = m_data->layers.pop();
+ ASSERT(!layer->alphaMask.isNull());
+ ASSERT(layer->saveCounter == 0);
+ layer->painter.resetTransform();
+ layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ layer->painter.drawPixmap(QPoint(), layer->alphaMask);
+ layer->painter.end();
+
+ QPainter* p = m_data->p();
+ p->save();
+ p->resetTransform();
+ p->setOpacity(layer->opacity);
+ p->drawPixmap(layer->offset, layer->pixmap);
+ p->restore();
+
+ delete layer;
+}
+
void GraphicsContext::endPlatformTransparencyLayer()
{
if (paintingDisabled())
return;
+ while ( ! m_data->layers.top()->alphaMask.isNull() ){
+ --m_data->layers.top()->saveCounter;
+ popTransparencyLayerInternal();
+ if (m_data->layers.isEmpty())
+ return;
+ }
TransparencyLayer* layer = m_data->layers.pop();
- if (!layer->alphaMask.isNull()) {
- layer->painter.resetTransform();
- layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- layer->painter.drawPixmap(QPoint(), layer->alphaMask);
- } else
- --m_data->layerCount; // see the comment for layerCount
+ --m_data->layerCount; // see the comment for layerCount
layer->painter.end();
QPainter* p = m_data->p();
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 2295362aa..af798f761 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -34,7 +34,6 @@
#include "IntRect.h"
#include "MIMETypeRegistry.h"
#include "StillImageQt.h"
-#include "TransparencyLayer.h"
#include <runtime/JSCInlines.h>
#include <runtime/TypedArrayInlines.h>
#include <wtf/text/WTFString.h>
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
index 48130eba4..b8b605805 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
@@ -114,14 +114,70 @@ void TextureMapperImageBuffer::drawSolidColor(const FloatRect& rect, const Trans
context->restore();
}
-void TextureMapperImageBuffer::drawBorder(const Color&, float /* borderWidth */, const FloatRect&, const TransformationMatrix&)
+void TextureMapperImageBuffer::drawBorder(const Color& color, float borderWidth , const FloatRect& rect, const TransformationMatrix& matrix)
{
- notImplemented();
+#if PLATFORM(QT)
+ GraphicsContext* context = currentContext();
+ if (!context)
+ return;
+
+ context->save();
+ context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
+#if ENABLE(3D_TRANSFORMS)
+ context->concat3DTransform(matrix);
+#else
+ context->concatCTM(matrix.toAffineTransform());
+#endif
+
+ QPainter& painter = *context->platformContext();
+ painter.setBrush(Qt::NoBrush);
+ QPen newPen(color);
+ newPen.setWidthF(borderWidth);
+ painter.setPen(newPen);
+ painter.drawRect(rect);
+
+ context->restore();
+#endif
}
-void TextureMapperImageBuffer::drawNumber(int /* number */, const Color&, const FloatPoint&, const TransformationMatrix&)
+void TextureMapperImageBuffer::drawNumber(int number, const Color& color, const FloatPoint& targetPoint, const TransformationMatrix& matrix)
{
- notImplemented();
+#if PLATFORM(QT)
+ GraphicsContext* context = currentContext();
+ if (!context)
+ return;
+
+ context->save();
+ context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
+#if ENABLE(3D_TRANSFORMS)
+ context->concat3DTransform(matrix);
+#else
+ context->concatCTM(matrix.toAffineTransform());
+#endif
+
+ // Partially duplicates TextureMapperGL::drawNumber
+ int pointSize = 8;
+ QString counterString = QString::number(number);
+
+ QFont font(QString::fromLatin1("Monospace"), pointSize, QFont::Bold);
+ font.setStyleHint(QFont::TypeWriter);
+
+ QFontMetrics fontMetrics(font);
+ int width = fontMetrics.width(counterString) + 4;
+ int height = fontMetrics.height();
+
+ IntSize size(width, height);
+ IntRect sourceRect(IntPoint::zero(), size);
+
+ QPainter& painter = *context->platformContext();
+ painter.translate(targetPoint);
+ painter.fillRect(sourceRect, color);
+ painter.setFont(font);
+ painter.setPen(Qt::white);
+ painter.drawText(2, height * 0.85, counterString);
+
+ context->restore();
+#endif
}
PassRefPtr<BitmapTexture> BitmapTextureImageBuffer::applyFilters(TextureMapper&, const FilterOperations& filters)
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
index 0610c85b6..98f2ec964 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
@@ -542,6 +542,16 @@ bool MediaPlayerPrivateMediaFoundation::endGetEvent(IMFAsyncResult* asyncResult)
break;
}
+ case MESessionStarted: {
+ auto weakPtr = m_weakPtrFactory.createWeakPtr();
+ callOnMainThread([weakPtr] {
+ if (!weakPtr)
+ return;
+ weakPtr->onSessionStarted();
+ });
+ break;
+ }
+
case MEBufferingStarted: {
auto weakPtr = m_weakPtrFactory.createWeakPtr();
callOnMainThread([weakPtr] {
@@ -940,6 +950,11 @@ void MediaPlayerPrivateMediaFoundation::onBufferingStopped()
updateReadyState();
}
+void MediaPlayerPrivateMediaFoundation::onSessionStarted()
+{
+ updateReadyState();
+}
+
void MediaPlayerPrivateMediaFoundation::onSessionEnded()
{
m_networkState = MediaPlayer::Loaded;
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
index c3303cf7b..0fe07fa13 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
@@ -152,6 +152,7 @@ private:
void onTopologySet();
void onBufferingStarted();
void onBufferingStopped();
+ void onSessionStarted();
void onSessionEnded();
LPCWSTR registerVideoWindowClass();
diff --git a/Source/WebCore/platform/network/qt/BlobUrlConversion.cpp b/Source/WebCore/platform/network/qt/BlobUrlConversion.cpp
new file mode 100644
index 000000000..8f61eaeb9
--- /dev/null
+++ b/Source/WebCore/platform/network/qt/BlobUrlConversion.cpp
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2017 Konstantin Tokarev <annulen@yandex.ru>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "BlobUrlConversion.h"
+
+#include "BlobData.h"
+#include "BlobRegistryImpl.h"
+
+#include <QUrl>
+#include <wtf/text/Base64.h>
+
+namespace WebCore {
+
+static bool appendBlobResolved(Vector<char>& out, const URL& url, QString* contentType = 0)
+{
+ RefPtr<BlobData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
+ if (!blobData)
+ return false;
+
+ if (contentType)
+ *contentType = blobData->contentType();
+
+ BlobDataItemList::const_iterator it = blobData->items().begin();
+ const BlobDataItemList::const_iterator itend = blobData->items().end();
+ for (; it != itend; ++it) {
+ const BlobDataItem& blobItem = *it;
+ if (blobItem.type() == BlobDataItem::Type::Data) {
+ if (!out.tryAppend(reinterpret_cast<const char*>(blobItem.data().data()->data()) + blobItem.offset(), blobItem.length()))
+ return false;
+ } else if (blobItem.type() == BlobDataItem::Type::File) {
+ // File types are not allowed here, so just ignore it.
+ RELEASE_ASSERT_WITH_MESSAGE(false, "File types are not allowed here");
+ } else
+ ASSERT_NOT_REACHED();
+ }
+ return true;
+}
+
+static QUrl resolveBlobUrl(const URL& url)
+{
+ RefPtr<BlobData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
+ if (!blobData)
+ return QUrl();
+
+ Vector<char> data;
+ QString contentType;
+ if (!appendBlobResolved(data, url, &contentType)) {
+ qWarning("Failed to convert blob data to base64: cannot allocate memory for continuous blob data");
+ return QUrl();
+ }
+
+ // QByteArray::{from,to}Base64 are prone to integer overflow, this is the maximum size that can be safe
+ size_t maxBase64Size = std::numeric_limits<int>::max() / 3 - 1;
+
+ Vector<char> base64;
+ WTF::base64Encode(data, base64, WTF::Base64URLPolicy);
+ if (base64.isEmpty() || base64.size() > maxBase64Size) {
+ qWarning("Failed to convert blob data to base64: data is too large");
+ return QUrl();
+ }
+
+ QString dataUri(QStringLiteral("data:"));
+ dataUri.append(contentType);
+ dataUri.append(QStringLiteral(";base64,"));
+ dataUri.reserve(dataUri.size() + base64.size());
+ dataUri.append(QLatin1String(base64.data(), base64.size()));
+ return QUrl(dataUri);
+}
+
+QUrl convertBlobToDataUrl(const QUrl& url)
+{
+ QT_TRY {
+ return resolveBlobUrl(url);
+ } QT_CATCH(const std::bad_alloc &) {
+ qWarning("Failed to convert blob data to base64: not enough memory");
+ }
+ return QUrl();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/network/qt/BlobUrlConversion.h b/Source/WebCore/platform/network/qt/BlobUrlConversion.h
new file mode 100644
index 000000000..2dbd0a680
--- /dev/null
+++ b/Source/WebCore/platform/network/qt/BlobUrlConversion.h
@@ -0,0 +1,29 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2017 Konstantin Tokarev <annulen@yandex.ru>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
+
+namespace WebCore {
+
+QUrl convertBlobToDataUrl(const QUrl&);
+
+}
diff --git a/Source/WebCore/platform/network/qt/CookieJarQt.cpp b/Source/WebCore/platform/network/qt/CookieJarQt.cpp
index 3b08c06cd..d1cf87fdd 100644
--- a/Source/WebCore/platform/network/qt/CookieJarQt.cpp
+++ b/Source/WebCore/platform/network/qt/CookieJarQt.cpp
@@ -42,12 +42,21 @@
#include <QNetworkCookie>
#include <QStringList>
#include <QVariant>
+#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
static SharedCookieJarQt* s_sharedCookieJarQt = 0;
+static void appendCookie(StringBuilder& builder, const QNetworkCookie& cookie)
+{
+ if (!builder.isEmpty())
+ builder.append("; ");
+ QByteArray rawData = cookie.toRawForm(QNetworkCookie::NameAndValueOnly);
+ builder.append(rawData.constData(), rawData.length());
+}
+
void setCookiesFromDOM(const NetworkStorageSession& session, const URL& firstParty, const URL& url, const String& value)
{
QNetworkCookieJar* jar = session.context() ? session.context()->networkAccessManager()->cookieJar() : SharedCookieJarQt::shared();
@@ -59,7 +68,8 @@ void setCookiesFromDOM(const NetworkStorageSession& session, const URL& firstPar
if (!thirdPartyCookiePolicyPermits(session.context(), urlForCookies, firstPartyUrl))
return;
- QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(QString(value).toLatin1());
+ CString cookieString = value.latin1();
+ QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(QByteArray::fromRawData(cookieString.data(), cookieString.length()));
QList<QNetworkCookie>::Iterator it = cookies.begin();
while (it != cookies.end()) {
if (it->isHttpOnly())
@@ -86,14 +96,13 @@ String cookiesForDOM(const NetworkStorageSession& session, const URL& firstParty
if (cookies.isEmpty())
return String();
- QStringList resultCookies;
- foreach (const QNetworkCookie& networkCookie, cookies) {
- if (networkCookie.isHttpOnly())
+ StringBuilder builder;
+ for (const auto& cookie : cookies) {
+ if (cookie.isHttpOnly())
continue;
- resultCookies.append(QString::fromLatin1(networkCookie.toRawForm(QNetworkCookie::NameAndValueOnly).constData()));
+ appendCookie(builder, cookie);
}
-
- return resultCookies.join(QLatin1String("; "));
+ return builder.toString();
}
String cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const URL& /*firstParty*/, const URL& url)
@@ -106,11 +115,10 @@ String cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const
if (cookies.isEmpty())
return String();
- QStringList resultCookies;
- foreach (QNetworkCookie networkCookie, cookies)
- resultCookies.append(QString::fromLatin1(networkCookie.toRawForm(QNetworkCookie::NameAndValueOnly).constData()));
-
- return resultCookies.join(QLatin1String("; "));
+ StringBuilder builder;
+ for (const auto& cookie : cookies)
+ appendCookie(builder, cookie);
+ return builder.toString();
}
bool cookiesEnabled(const NetworkStorageSession& session, const URL& /*firstParty*/, const URL& /*url*/)
diff --git a/Source/WebCore/platform/network/qt/DNSQt.cpp b/Source/WebCore/platform/network/qt/DNSQt.cpp
index b12cbaa09..4559d17a0 100644
--- a/Source/WebCore/platform/network/qt/DNSQt.cpp
+++ b/Source/WebCore/platform/network/qt/DNSQt.cpp
@@ -24,6 +24,7 @@
#include <QHostInfo>
#include <QObject>
#include <QString>
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -34,7 +35,7 @@ public:
DnsPrefetchHelper() : QObject() { }
public Q_SLOTS:
- void lookup(QString hostname)
+ void lookup(const String& hostname)
{
if (hostname.isEmpty()) {
DNSResolveQueue::singleton().decrementRequestCount();
@@ -71,8 +72,8 @@ void DNSResolveQueue::updateIsUsingProxy()
// This is called by the platform-independent DNSResolveQueue.
void DNSResolveQueue::platformResolve(const String& hostname)
{
- static DnsPrefetchHelper dnsPrefetchHelper;
- dnsPrefetchHelper.lookup(QString(hostname));
+ static NeverDestroyed<DnsPrefetchHelper> dnsPrefetchHelper;
+ dnsPrefetchHelper.get().lookup(hostname);
}
} // namespace
diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index cd096bfe7..1b60c5131 100644
--- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -647,7 +647,10 @@ void QNetworkReplyHandler::redirect(ResourceResponse& response, const QUrl& redi
{
ASSERT(!m_queue.deferSignals());
- QUrl newUrl = m_replyWrapper->reply()->url().resolved(redirection);
+ QUrl currentUrl = m_replyWrapper->reply()->url();
+ QUrl newUrl = currentUrl.resolved(redirection);
+ if (currentUrl.hasFragment())
+ newUrl.setFragment(currentUrl.fragment());
ResourceHandleClient* client = m_resourceHandle->client();
ASSERT(client);
diff --git a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
index 655724a4c..c54a8115b 100644
--- a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -18,18 +18,27 @@
*/
#include "config.h"
-#include "NetworkingContext.h"
#include "ResourceRequest.h"
-#include "ThirdPartyCookiesQt.h"
-
-#include "BlobData.h"
-#include "BlobRegistryImpl.h"
-#include <qglobal.h>
+#include "BlobUrlConversion.h"
+#include "NetworkingContext.h"
+#include "ThirdPartyCookiesQt.h"
#include <QNetworkRequest>
#include <QUrl>
+// HTTP/2 is implemented since Qt 5.8, but QTBUG-64359 makes it unusable in browser
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 4)
+#define USE_HTTP2 1
+#endif
+
+// HTTP2AllowedAttribute enforces HTTP/2 instead of negotiating, see QTBUG-61397
+#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
+#define HTTP2_IS_BUGGY_WITHOUT_HTTPS 1
+#else
+#define HTTP2_IS_BUGGY_WITHOUT_HTTPS 0
+#endif
+
namespace WebCore {
// The limit can be found in qhttpnetworkconnection.cpp.
@@ -43,44 +52,11 @@ unsigned initializeMaximumHTTPConnectionCountPerHost()
return 6 * (1 + 3 + 2);
}
-static void appendBlobResolved(QByteArray& data, const QUrl& url, QString* contentType = 0)
+static QUrl toQUrl(const URL& url)
{
- RefPtr<BlobData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
- if (!blobData)
- return;
-
- if (contentType)
- *contentType = blobData->contentType();
-
- BlobDataItemList::const_iterator it = blobData->items().begin();
- const BlobDataItemList::const_iterator itend = blobData->items().end();
- for (; it != itend; ++it) {
- const BlobDataItem& blobItem = *it;
- if (blobItem.type() == BlobDataItem::Type::Data)
- data.append(reinterpret_cast<const char*>(blobItem.data().data()->data()) + static_cast<int>(blobItem.offset()), static_cast<int>(blobItem.length()));
- else if (blobItem.type() == BlobDataItem::Type::File) {
- // File types are not allowed here, so just ignore it.
- RELEASE_ASSERT_WITH_MESSAGE(false, "File types are not allowed here");
- } else
- ASSERT_NOT_REACHED();
- }
-}
-
-static void resolveBlobUrl(const QUrl& url, QUrl& resolvedUrl)
-{
- RefPtr<BlobData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
- if (!blobData)
- return;
-
- QByteArray data;
- QString contentType;
- appendBlobResolved(data, url, &contentType);
-
- QString dataUri(QStringLiteral("data:"));
- dataUri.append(contentType);
- dataUri.append(QStringLiteral(";base64,"));
- dataUri.append(QString::fromLatin1(data.toBase64()));
- resolvedUrl = QUrl(dataUri);
+ if (url.protocolIsBlob())
+ return convertBlobToDataUrl(url);
+ return url;
}
static inline QByteArray stringToByteArray(const String& string)
@@ -93,19 +69,19 @@ static inline QByteArray stringToByteArray(const String& string)
QNetworkRequest ResourceRequest::toNetworkRequest(NetworkingContext *context) const
{
QNetworkRequest request;
- QUrl newurl = url();
-
- if (newurl.scheme() == QLatin1String("blob"))
- resolveBlobUrl(url(), newurl);
-
- request.setUrl(newurl);
+ const URL& originalUrl = url();
+ request.setUrl(toQUrl(originalUrl));
request.setOriginatingObject(context ? context->originatingObject() : 0);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
- // HTTP2AllowedAttribute enforces HTTP/2 instead of negotiating, see QTBUG-61397
- if (newurl.scheme().toLower() == QLatin1String("https"))
- request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
+#if USE(HTTP2)
+#if HTTP2_IS_BUGGY_WITHOUT_HTTPS
+ if (originalUrl.protocolIs("https"))
#endif
+ {
+ request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
+ }
+#endif // USE(HTTP2)
+
const HTTPHeaderMap &headers = httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end();
diff --git a/Source/WebCore/platform/qt/EventLoopQt.cpp b/Source/WebCore/platform/qt/EventLoopQt.cpp
index 39bb54c53..c0ca31ec5 100644
--- a/Source/WebCore/platform/qt/EventLoopQt.cpp
+++ b/Source/WebCore/platform/qt/EventLoopQt.cpp
@@ -26,7 +26,7 @@ namespace WebCore {
void EventLoop::cycle()
{
- QCoreApplication::processEvents();
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
index a0e67e494..2e667e2da 100644
--- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
+++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
@@ -808,6 +808,7 @@ static bool isVirtualKeyCodeRepresentingCharacter(int code)
}
}
+template<bool unmodified>
static String keyTextForKeyEvent(const QKeyEvent* event)
{
switch (event->key()) {
@@ -820,6 +821,53 @@ static String keyTextForKeyEvent(const QKeyEvent* event)
case Qt::Key_Enter:
if (event->text().isNull())
return ASCIILiteral("\r");
+ break;
+
+// Workaround for broken accesskey when QKeyEvent has modifier, see QTBUG-64891
+#define MAKE_TEXT_FOR_KEY(QtKey, Character) \
+ case Qt::Key_##QtKey: \
+ if (unmodified && event->text().isNull()) \
+ return ASCIILiteral(#Character); \
+ break;
+
+ MAKE_TEXT_FOR_KEY(0, 0);
+ MAKE_TEXT_FOR_KEY(1, 1);
+ MAKE_TEXT_FOR_KEY(2, 2);
+ MAKE_TEXT_FOR_KEY(3, 3);
+ MAKE_TEXT_FOR_KEY(4, 4);
+ MAKE_TEXT_FOR_KEY(5, 5);
+ MAKE_TEXT_FOR_KEY(6, 6);
+ MAKE_TEXT_FOR_KEY(7, 7);
+ MAKE_TEXT_FOR_KEY(8, 8);
+ MAKE_TEXT_FOR_KEY(9, 9);
+ MAKE_TEXT_FOR_KEY(A, a);
+ MAKE_TEXT_FOR_KEY(B, b);
+ MAKE_TEXT_FOR_KEY(C, c);
+ MAKE_TEXT_FOR_KEY(D, d);
+ MAKE_TEXT_FOR_KEY(E, e);
+ MAKE_TEXT_FOR_KEY(F, f);
+ MAKE_TEXT_FOR_KEY(G, g);
+ MAKE_TEXT_FOR_KEY(H, h);
+ MAKE_TEXT_FOR_KEY(I, i);
+ MAKE_TEXT_FOR_KEY(J, j);
+ MAKE_TEXT_FOR_KEY(K, k);
+ MAKE_TEXT_FOR_KEY(L, l);
+ MAKE_TEXT_FOR_KEY(M, m);
+ MAKE_TEXT_FOR_KEY(N, n);
+ MAKE_TEXT_FOR_KEY(O, o);
+ MAKE_TEXT_FOR_KEY(P, p);
+ MAKE_TEXT_FOR_KEY(Q, q);
+ MAKE_TEXT_FOR_KEY(R, r);
+ MAKE_TEXT_FOR_KEY(S, s);
+ MAKE_TEXT_FOR_KEY(T, t);
+ MAKE_TEXT_FOR_KEY(U, u);
+ MAKE_TEXT_FOR_KEY(V, v);
+ MAKE_TEXT_FOR_KEY(W, w);
+ MAKE_TEXT_FOR_KEY(X, x);
+ MAKE_TEXT_FOR_KEY(Y, y);
+ MAKE_TEXT_FOR_KEY(Z, z);
+
+#undef MAKE_TEXT_FOR_KEY
}
return event->text();
}
@@ -840,8 +888,8 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(QKeyEvent* event, bool useNativeVir
m_modifiers |= MetaKey;
m_useNativeVirtualKeyAsDOMKey = useNativeVirtualKeyAsDOMKey;
- m_text = keyTextForKeyEvent(event);
- m_unmodifiedText = m_text; // FIXME: not correct
+ m_text = keyTextForKeyEvent<false>(event);
+ m_unmodifiedText = keyTextForKeyEvent<true>(event);
m_keyIdentifier = keyIdentifierForQtKeyCode(event->key());
m_autoRepeat = event->isAutoRepeat();
m_isKeypad = (state & Qt::KeypadModifier);
diff --git a/Source/WebCore/platform/qt/UserAgentQt.cpp b/Source/WebCore/platform/qt/UserAgentQt.cpp
index 4b8876220..fc5eab7a8 100644
--- a/Source/WebCore/platform/qt/UserAgentQt.cpp
+++ b/Source/WebCore/platform/qt/UserAgentQt.cpp
@@ -37,7 +37,7 @@ namespace WebCore {
This implementation returns the following value:
- "Mozilla/5.0 (%Platform%%Security%%Subplatform%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Version/9.0 Safari/%WebKitVersion%"
+ "Mozilla/5.0 (%Platform%%Security%%Subplatform%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Version/10.0 Safari/%WebKitVersion%"
In this string the following values are replaced the first time the function is called:
\list
@@ -58,7 +58,7 @@ String UserAgentQt::standardUserAgent(const String &applicationNameForUserAgent,
if (ua.isNull()) {
- ua = QStringLiteral("Mozilla/5.0 (%1%2%3) AppleWebKit/%4 (KHTML, like Gecko) %99 Version/9.0 Safari/%5");
+ ua = QStringLiteral("Mozilla/5.0 (%1%2%3) AppleWebKit/%4 (KHTML, like Gecko) %99 Version/10.0 Safari/%5");
// Platform.
ua = ua.arg(
diff --git a/Source/WebCore/platform/text/TextCodecUTF8.cpp b/Source/WebCore/platform/text/TextCodecUTF8.cpp
index 6b32955c1..31f548662 100644
--- a/Source/WebCore/platform/text/TextCodecUTF8.cpp
+++ b/Source/WebCore/platform/text/TextCodecUTF8.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,18 +31,10 @@
#include <wtf/text/StringBuffer.h>
#include <wtf/unicode/CharacterNames.h>
-using namespace WTF;
-using namespace WTF::Unicode;
-
namespace WebCore {
const int nonCharacter = -1;
-std::unique_ptr<TextCodec> TextCodecUTF8::create(const TextEncoding&, const void*)
-{
- return std::make_unique<TextCodecUTF8>();
-}
-
void TextCodecUTF8::registerEncodingNames(EncodingNameRegistrar registrar)
{
registrar("UTF-8", "UTF-8");
@@ -59,7 +51,9 @@ void TextCodecUTF8::registerEncodingNames(EncodingNameRegistrar registrar)
void TextCodecUTF8::registerCodecs(TextCodecRegistrar registrar)
{
- registrar("UTF-8", create, 0);
+ registrar("UTF-8", [] (const TextEncoding&, const void*) -> std::unique_ptr<TextCodec> {
+ return std::make_unique<TextCodecUTF8>();
+ }, nullptr);
}
static inline int nonASCIISequenceLength(uint8_t firstByte)
@@ -73,11 +67,11 @@ static inline int nonASCIISequenceLength(uint8_t firstByte)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -85,55 +79,76 @@ static inline int nonASCIISequenceLength(uint8_t firstByte)
return lengths[firstByte];
}
-static inline int decodeNonASCIISequence(const uint8_t* sequence, unsigned length)
+static inline int decodeNonASCIISequence(const uint8_t* sequence, int& length)
{
ASSERT(!isASCII(sequence[0]));
if (length == 2) {
+ ASSERT(sequence[0] >= 0xC2);
ASSERT(sequence[0] <= 0xDF);
- if (sequence[0] < 0xC2)
- return nonCharacter;
- if (sequence[1] < 0x80 || sequence[1] > 0xBF)
+ if (sequence[1] < 0x80 || sequence[1] > 0xBF) {
+ length = 1;
return nonCharacter;
+ }
return ((sequence[0] << 6) + sequence[1]) - 0x00003080;
}
if (length == 3) {
- ASSERT(sequence[0] >= 0xE0 && sequence[0] <= 0xEF);
+ ASSERT(sequence[0] >= 0xE0);
+ ASSERT(sequence[0] <= 0xEF);
switch (sequence[0]) {
case 0xE0:
- if (sequence[1] < 0xA0 || sequence[1] > 0xBF)
+ if (sequence[1] < 0xA0 || sequence[1] > 0xBF) {
+ length = 1;
return nonCharacter;
+ }
break;
case 0xED:
- if (sequence[1] < 0x80 || sequence[1] > 0x9F)
+ if (sequence[1] < 0x80 || sequence[1] > 0x9F) {
+ length = 1;
return nonCharacter;
+ }
break;
default:
- if (sequence[1] < 0x80 || sequence[1] > 0xBF)
+ if (sequence[1] < 0x80 || sequence[1] > 0xBF) {
+ length = 1;
return nonCharacter;
+ }
}
- if (sequence[2] < 0x80 || sequence[2] > 0xBF)
+ if (sequence[2] < 0x80 || sequence[2] > 0xBF) {
+ length = 2;
return nonCharacter;
+ }
return ((sequence[0] << 12) + (sequence[1] << 6) + sequence[2]) - 0x000E2080;
}
ASSERT(length == 4);
- ASSERT(sequence[0] >= 0xF0 && sequence[0] <= 0xF4);
+ ASSERT(sequence[0] >= 0xF0);
+ ASSERT(sequence[0] <= 0xF4);
switch (sequence[0]) {
case 0xF0:
- if (sequence[1] < 0x90 || sequence[1] > 0xBF)
+ if (sequence[1] < 0x90 || sequence[1] > 0xBF) {
+ length = 1;
return nonCharacter;
+ }
break;
case 0xF4:
- if (sequence[1] < 0x80 || sequence[1] > 0x8F)
+ if (sequence[1] < 0x80 || sequence[1] > 0x8F) {
+ length = 1;
return nonCharacter;
+ }
break;
default:
- if (sequence[1] < 0x80 || sequence[1] > 0xBF)
+ if (sequence[1] < 0x80 || sequence[1] > 0xBF) {
+ length = 1;
return nonCharacter;
+ }
}
- if (sequence[2] < 0x80 || sequence[2] > 0xBF)
+ if (sequence[2] < 0x80 || sequence[2] > 0xBF) {
+ length = 2;
return nonCharacter;
- if (sequence[3] < 0x80 || sequence[3] > 0xBF)
+ }
+ if (sequence[3] < 0x80 || sequence[3] > 0xBF) {
+ length = 3;
return nonCharacter;
+ }
return ((sequence[0] << 18) + (sequence[1] << 12) + (sequence[2] << 6) + sequence[3]) - 0x03C82080;
}
@@ -156,18 +171,7 @@ void TextCodecUTF8::consumePartialSequenceByte()
memmove(m_partialSequence, m_partialSequence + 1, m_partialSequenceSize);
}
-void TextCodecUTF8::handleError(UChar*& destination, bool stopOnError, bool& sawError)
-{
- sawError = true;
- if (stopOnError)
- return;
- // Each error generates a replacement character and consumes one byte.
- *destination++ = replacementCharacter;
- consumePartialSequenceByte();
-}
-
-template <>
-bool TextCodecUTF8::handlePartialSequence<LChar>(LChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool, bool&)
+bool TextCodecUTF8::handlePartialSequence(LChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush)
{
ASSERT(m_partialSequenceSize);
do {
@@ -199,7 +203,7 @@ bool TextCodecUTF8::handlePartialSequence<LChar>(LChar*& destination, const uint
m_partialSequenceSize = count;
}
int character = decodeNonASCIISequence(m_partialSequence, count);
- if ((character == nonCharacter) || (character > 0xff))
+ if (character == nonCharacter || character > 0xFF)
return true;
m_partialSequenceSize -= count;
@@ -209,8 +213,7 @@ bool TextCodecUTF8::handlePartialSequence<LChar>(LChar*& destination, const uint
return false;
}
-template <>
-bool TextCodecUTF8::handlePartialSequence<UChar>(UChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError)
+void TextCodecUTF8::handlePartialSequence(UChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError)
{
ASSERT(m_partialSequenceSize);
do {
@@ -221,9 +224,11 @@ bool TextCodecUTF8::handlePartialSequence<UChar>(UChar*& destination, const uint
}
int count = nonASCIISequenceLength(m_partialSequence[0]);
if (!count) {
- handleError(destination, stopOnError, sawError);
+ sawError = true;
if (stopOnError)
- return false;
+ return;
+ *destination++ = replacementCharacter;
+ consumePartialSequenceByte();
continue;
}
if (count > m_partialSequenceSize) {
@@ -233,12 +238,15 @@ bool TextCodecUTF8::handlePartialSequence<UChar>(UChar*& destination, const uint
// add it to the existing partial sequence.
memcpy(m_partialSequence + m_partialSequenceSize, source, end - source);
m_partialSequenceSize += end - source;
- return false;
+ return;
}
// An incomplete partial sequence at the end is an error.
- handleError(destination, stopOnError, sawError);
+ sawError = true;
if (stopOnError)
- return false;
+ return;
+ *destination++ = replacementCharacter;
+ m_partialSequenceSize = 0;
+ source = end;
continue;
}
memcpy(m_partialSequence + m_partialSequenceSize, source, count - m_partialSequenceSize);
@@ -247,17 +255,18 @@ bool TextCodecUTF8::handlePartialSequence<UChar>(UChar*& destination, const uint
}
int character = decodeNonASCIISequence(m_partialSequence, count);
if (character == nonCharacter) {
- handleError(destination, stopOnError, sawError);
+ sawError = true;
if (stopOnError)
- return false;
+ return;
+ *destination++ = replacementCharacter;
+ m_partialSequenceSize -= count;
+ memmove(m_partialSequence, m_partialSequence + count, m_partialSequenceSize);
continue;
}
m_partialSequenceSize -= count;
destination = appendCharacter(destination, character);
} while (m_partialSequenceSize);
-
- return false;
}
String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool stopOnError, bool& sawError)
@@ -269,7 +278,7 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool
const uint8_t* source = reinterpret_cast<const uint8_t*>(bytes);
const uint8_t* end = source + length;
- const uint8_t* alignedEnd = alignToMachineWord(end);
+ const uint8_t* alignedEnd = WTF::alignToMachineWord(end);
LChar* destination = buffer.characters();
do {
@@ -279,7 +288,7 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool
// in some compilers.
LChar* destinationForHandlePartialSequence = destination;
const uint8_t* sourceForHandlePartialSequence = source;
- if (handlePartialSequence(destinationForHandlePartialSequence, sourceForHandlePartialSequence, end, flush, stopOnError, sawError)) {
+ if (handlePartialSequence(destinationForHandlePartialSequence, sourceForHandlePartialSequence, end, flush)) {
source = sourceForHandlePartialSequence;
goto upConvertTo16Bit;
}
@@ -292,14 +301,14 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool
while (source < end) {
if (isASCII(*source)) {
// Fast path for ASCII. Most UTF-8 text will be ASCII.
- if (isAlignedToMachineWord(source)) {
+ if (WTF::isAlignedToMachineWord(source)) {
while (source < alignedEnd) {
- MachineWord chunk = *reinterpret_cast_ptr<const MachineWord*>(source);
- if (!isAllASCII<LChar>(chunk))
+ auto chunk = *reinterpret_cast_ptr<const WTF::MachineWord*>(source);
+ if (!WTF::isAllASCII<LChar>(chunk))
break;
copyASCIIMachineWord(destination, source);
- source += sizeof(MachineWord);
- destination += sizeof(MachineWord);
+ source += sizeof(WTF::MachineWord);
+ destination += sizeof(WTF::MachineWord);
}
if (source == end)
break;
@@ -328,10 +337,10 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool
sawError = true;
if (stopOnError)
break;
-
+
goto upConvertTo16Bit;
}
- if (character > 0xff)
+ if (character > 0xFF)
goto upConvertTo16Bit;
source += count;
@@ -369,14 +378,14 @@ upConvertTo16Bit:
while (source < end) {
if (isASCII(*source)) {
// Fast path for ASCII. Most UTF-8 text will be ASCII.
- if (isAlignedToMachineWord(source)) {
+ if (WTF::isAlignedToMachineWord(source)) {
while (source < alignedEnd) {
- MachineWord chunk = *reinterpret_cast_ptr<const MachineWord*>(source);
- if (!isAllASCII<LChar>(chunk))
+ auto chunk = *reinterpret_cast_ptr<const WTF::MachineWord*>(source);
+ if (!WTF::isAllASCII<LChar>(chunk))
break;
copyASCIIMachineWord(destination16, source);
- source += sizeof(MachineWord);
- destination16 += sizeof(MachineWord);
+ source += sizeof(WTF::MachineWord);
+ destination16 += sizeof(WTF::MachineWord);
}
if (source == end)
break;
@@ -405,9 +414,8 @@ upConvertTo16Bit:
sawError = true;
if (stopOnError)
break;
- // Each error generates a replacement character and consumes one byte.
*destination16++ = replacementCharacter;
- ++source;
+ source += count ? count : 1;
continue;
}
source += count;
@@ -427,17 +435,15 @@ CString TextCodecUTF8::encode(const UChar* characters, size_t length, Unencodabl
// Non-BMP characters take two UTF-16 code units and can take up to 4 bytes (2x).
if (length > std::numeric_limits<size_t>::max() / 3)
CRASH();
- Vector<uint8_t> bytes(length * 3);
- size_t i = 0;
+ Vector<char, 3000> bytes(length * 3);
size_t bytesWritten = 0;
- while (i < length) {
+ for (size_t i = 0; i < length; ) {
UChar32 character;
U16_NEXT(characters, i, length, character);
U8_APPEND_UNSAFE(bytes.data(), bytesWritten, character);
}
-
- return CString(reinterpret_cast<char*>(bytes.data()), bytesWritten);
+ return CString { bytes.data(), bytesWritten };
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/TextCodecUTF8.h b/Source/WebCore/platform/text/TextCodecUTF8.h
index 94305ce18..636a0cb8d 100644
--- a/Source/WebCore/platform/text/TextCodecUTF8.h
+++ b/Source/WebCore/platform/text/TextCodecUTF8.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TextCodecUTF8_h
-#define TextCodecUTF8_h
+#pragma once
#include "TextCodec.h"
@@ -32,12 +31,6 @@ namespace WebCore {
class TextCodecUTF8 : public TextCodec {
public:
- static std::unique_ptr<TextCodec> create(const TextEncoding&, const void*);
- TextCodecUTF8()
- : m_partialSequenceSize(0)
- {
- }
-
static void registerEncodingNames(EncodingNameRegistrar);
static void registerCodecs(TextCodecRegistrar);
@@ -45,16 +38,14 @@ private:
virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError);
virtual CString encode(const UChar*, size_t length, UnencodableHandling);
- template <typename CharType>
- bool handlePartialSequence(CharType*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError);
- void handleError(UChar*& destination, bool stopOnError, bool& sawError);
+ bool handlePartialSequence(LChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush);
+ void handlePartialSequence(UChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError);
void consumePartialSequenceByte();
- int m_partialSequenceSize;
+ int m_partialSequenceSize { 0 };
uint8_t m_partialSequence[U8_MAX_LENGTH];
};
} // namespace WebCore
-#endif // TextCodecUTF8_h
diff --git a/Source/WebCore/platform/text/TextEncoding.h b/Source/WebCore/platform/text/TextEncoding.h
index d9943024f..922fc3e21 100644
--- a/Source/WebCore/platform/text/TextEncoding.h
+++ b/Source/WebCore/platform/text/TextEncoding.h
@@ -31,68 +31,68 @@
namespace WebCore {
- class TextEncoding {
- public:
- TextEncoding() : m_name(0) { }
- TextEncoding(const char* name);
- WEBCORE_EXPORT TextEncoding(const String& name);
+class TextEncoding {
+public:
+ TextEncoding() : m_name(0) { }
+ WEBCORE_EXPORT TextEncoding(const char* name);
+ WEBCORE_EXPORT TextEncoding(const String& name);
- bool isValid() const { return m_name; }
- const char* name() const { return m_name; }
- const char* domName() const; // name exposed via DOM
- bool usesVisualOrdering() const;
- bool isJapanese() const;
-
- PassRefPtr<StringImpl> displayString(PassRefPtr<StringImpl> str) const
- {
- if (m_backslashAsCurrencySymbol == '\\' || !str)
- return str;
- return str->replace('\\', m_backslashAsCurrencySymbol);
- }
- template <typename CharacterType>
- void displayBuffer(CharacterType* characters, unsigned len) const
- {
- if (m_backslashAsCurrencySymbol == '\\')
- return;
- for (unsigned i = 0; i < len; ++i) {
- if (characters[i] == '\\')
- characters[i] = m_backslashAsCurrencySymbol;
- }
+ bool isValid() const { return m_name; }
+ const char* name() const { return m_name; }
+ const char* domName() const; // name exposed via DOM
+ bool usesVisualOrdering() const;
+ bool isJapanese() const;
+
+ PassRefPtr<StringImpl> displayString(PassRefPtr<StringImpl> str) const
+ {
+ if (m_backslashAsCurrencySymbol == '\\' || !str)
+ return str;
+ return str->replace('\\', m_backslashAsCurrencySymbol);
+ }
+ template <typename CharacterType>
+ void displayBuffer(CharacterType* characters, unsigned len) const
+ {
+ if (m_backslashAsCurrencySymbol == '\\')
+ return;
+ for (unsigned i = 0; i < len; ++i) {
+ if (characters[i] == '\\')
+ characters[i] = m_backslashAsCurrencySymbol;
}
+ }
- const TextEncoding& closestByteBasedEquivalent() const;
- const TextEncoding& encodingForFormSubmission() const;
+ const TextEncoding& closestByteBasedEquivalent() const;
+ const TextEncoding& encodingForFormSubmission() const;
- String decode(const char* str, size_t length) const
- {
- bool ignored;
- return decode(str, length, false, ignored);
- }
- WEBCORE_EXPORT String decode(const char*, size_t length, bool stopOnError, bool& sawError) const;
- CString encode(StringView, UnencodableHandling) const;
+ String decode(const char* str, size_t length) const
+ {
+ bool ignored;
+ return decode(str, length, false, ignored);
+ }
+ WEBCORE_EXPORT String decode(const char*, size_t length, bool stopOnError, bool& sawError) const;
+ CString encode(StringView, UnencodableHandling) const;
- UChar backslashAsCurrencySymbol() const;
- bool isByteBasedEncoding() const { return !isNonByteBasedEncoding(); }
+ UChar backslashAsCurrencySymbol() const;
+ bool isByteBasedEncoding() const { return !isNonByteBasedEncoding(); }
- private:
- bool isNonByteBasedEncoding() const;
- bool isUTF7Encoding() const;
+private:
+ bool isNonByteBasedEncoding() const;
+ bool isUTF7Encoding() const;
- const char* m_name;
- UChar m_backslashAsCurrencySymbol;
- };
+ const char* m_name;
+ UChar m_backslashAsCurrencySymbol;
+};
- inline bool operator==(const TextEncoding& a, const TextEncoding& b) { return a.name() == b.name(); }
- inline bool operator!=(const TextEncoding& a, const TextEncoding& b) { return a.name() != b.name(); }
+inline bool operator==(const TextEncoding& a, const TextEncoding& b) { return a.name() == b.name(); }
+inline bool operator!=(const TextEncoding& a, const TextEncoding& b) { return a.name() != b.name(); }
- const TextEncoding& ASCIIEncoding();
- const TextEncoding& Latin1Encoding();
- const TextEncoding& UTF16BigEndianEncoding();
- const TextEncoding& UTF16LittleEndianEncoding();
- const TextEncoding& UTF32BigEndianEncoding();
- const TextEncoding& UTF32LittleEndianEncoding();
- WEBCORE_EXPORT const TextEncoding& UTF8Encoding();
- WEBCORE_EXPORT const TextEncoding& WindowsLatin1Encoding();
+const TextEncoding& ASCIIEncoding();
+const TextEncoding& Latin1Encoding();
+const TextEncoding& UTF16BigEndianEncoding();
+const TextEncoding& UTF16LittleEndianEncoding();
+const TextEncoding& UTF32BigEndianEncoding();
+const TextEncoding& UTF32LittleEndianEncoding();
+WEBCORE_EXPORT const TextEncoding& UTF8Encoding();
+WEBCORE_EXPORT const TextEncoding& WindowsLatin1Encoding();
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/TextEncodingRegistry.h b/Source/WebCore/platform/text/TextEncodingRegistry.h
index e882a9ab3..6623fb949 100644
--- a/Source/WebCore/platform/text/TextEncodingRegistry.h
+++ b/Source/WebCore/platform/text/TextEncodingRegistry.h
@@ -31,26 +31,26 @@
namespace WebCore {
- class TextCodec;
- class TextEncoding;
+class TextCodec;
+class TextEncoding;
- // Use TextResourceDecoder::decode to decode resources, since it handles BOMs.
- // Use TextEncoding::encode to encode, since it takes care of normalization.
- std::unique_ptr<TextCodec> newTextCodec(const TextEncoding&);
+// Use TextResourceDecoder::decode to decode resources, since it handles BOMs.
+// Use TextEncoding::encode to encode, since it takes care of normalization.
+WEBCORE_EXPORT std::unique_ptr<TextCodec> newTextCodec(const TextEncoding&);
- // Only TextEncoding should use the following functions directly.
- const char* atomicCanonicalTextEncodingName(const char* alias);
- template <typename CharacterType>
- const char* atomicCanonicalTextEncodingName(const CharacterType*, size_t);
- const char* atomicCanonicalTextEncodingName(const String&);
- bool noExtendedTextEncodingNameUsed();
- bool isJapaneseEncoding(const char* canonicalEncodingName);
- bool shouldShowBackslashAsCurrencySymbolIn(const char* canonicalEncodingName);
+// Only TextEncoding should use the following functions directly.
+const char* atomicCanonicalTextEncodingName(const char* alias);
+template <typename CharacterType>
+const char* atomicCanonicalTextEncodingName(const CharacterType*, size_t);
+const char* atomicCanonicalTextEncodingName(const String&);
+bool noExtendedTextEncodingNameUsed();
+bool isJapaneseEncoding(const char* canonicalEncodingName);
+bool shouldShowBackslashAsCurrencySymbolIn(const char* canonicalEncodingName);
- WEBCORE_EXPORT String defaultTextEncodingNameForSystemLanguage();
+WEBCORE_EXPORT String defaultTextEncodingNameForSystemLanguage();
#ifndef NDEBUG
- void dumpTextEncodingNameMap();
+void dumpTextEncodingNameMap();
#endif
}