Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / loader / cache / CachedScript.cpp
1 /*
2     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3     Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4     Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5     Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6     Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Library General Public
10     License as published by the Free Software Foundation; either
11     version 2 of the License, or (at your option) any later version.
12
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Library General Public License for more details.
17
18     You should have received a copy of the GNU Library General Public License
19     along with this library; see the file COPYING.LIB.  If not, write to
20     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21     Boston, MA 02110-1301, USA.
22
23     This class provides all functionality needed for loading images, style sheets and html
24     pages from the web. It has a memory cache for these objects.
25 */
26
27 #include "config.h"
28 #include "CachedScript.h"
29
30 #include "CachedResourceClient.h"
31 #include "CachedResourceClientWalker.h"
32 #include "CachedResourceRequest.h"
33 #include "RuntimeApplicationChecks.h"
34 #include "SharedBuffer.h"
35 #include "TextResourceDecoder.h"
36
37 namespace WebCore {
38
39 CachedScript::CachedScript(CachedResourceRequest&& request, PAL::SessionID sessionID)
40     : CachedResource(WTFMove(request), Script, sessionID)
41     , m_decoder(TextResourceDecoder::create(ASCIILiteral("application/javascript"), request.charset()))
42 {
43 }
44
45 CachedScript::~CachedScript() = default;
46
47 void CachedScript::setEncoding(const String& chs)
48 {
49     m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
50 }
51
52 String CachedScript::encoding() const
53 {
54     return m_decoder->encoding().name();
55 }
56
57 StringView CachedScript::script()
58 {
59     if (!m_data)
60         return { };
61
62     if (m_decodingState == NeverDecoded
63         && TextEncoding(encoding()).isByteBasedEncoding()
64         && m_data->size()
65         && charactersAreAllASCII(reinterpret_cast<const LChar*>(m_data->data()), m_data->size())) {
66
67         m_decodingState = DataAndDecodedStringHaveSameBytes;
68
69         // If the encoded and decoded data are the same, there is no decoded data cost!
70         setDecodedSize(0);
71         m_decodedDataDeletionTimer.stop();
72
73         m_scriptHash = StringHasher::computeHashAndMaskTop8Bits(reinterpret_cast<const LChar*>(m_data->data()), m_data->size());
74     }
75
76     if (m_decodingState == DataAndDecodedStringHaveSameBytes)
77         return { reinterpret_cast<const LChar*>(m_data->data()), static_cast<unsigned>(m_data->size()) };
78
79     if (!m_script) {
80         m_script = m_decoder->decodeAndFlush(m_data->data(), encodedSize());
81         ASSERT(!m_scriptHash || m_scriptHash == m_script.impl()->hash());
82         if (m_decodingState == NeverDecoded)
83             m_scriptHash = m_script.impl()->hash();
84         m_decodingState = DataAndDecodedStringHaveDifferentBytes;
85         setDecodedSize(m_script.sizeInBytes());
86     }
87
88     m_decodedDataDeletionTimer.restart();
89     return m_script;
90 }
91
92 unsigned CachedScript::scriptHash()
93 {
94     if (m_decodingState == NeverDecoded)
95         script();
96     return m_scriptHash;
97 }
98
99 void CachedScript::finishLoading(SharedBuffer* data)
100 {
101     m_data = data;
102     setEncodedSize(data ? data->size() : 0);
103     CachedResource::finishLoading(data);
104 }
105
106 void CachedScript::destroyDecodedData()
107 {
108     m_script = String();
109     setDecodedSize(0);
110 }
111
112 void CachedScript::setBodyDataFrom(const CachedResource& resource)
113 {
114     ASSERT(resource.type() == type());
115     auto& script = static_cast<const CachedScript&>(resource);
116
117     CachedResource::setBodyDataFrom(resource);
118
119     m_script = script.m_script;
120     m_scriptHash = script.m_scriptHash;
121     m_decodingState = script.m_decodingState;
122     m_decoder = script.m_decoder;
123 }
124
125 bool CachedScript::shouldIgnoreHTTPStatusCodeErrors() const
126 {
127 #if PLATFORM(MAC)
128     // This is a workaround for <rdar://problem/13916291>
129     // REGRESSION (r119759): Adobe Flash Player "smaller" installer relies on the incorrect firing
130     // of a load event and needs an app-specific hack for compatibility.
131     // The installer in question tries to load .js file that doesn't exist, causing the server to
132     // return a 404 response. Normally, this would trigger an error event to be dispatched, but the
133     // installer expects a load event instead so we work around it here.
134     if (MacApplication::isSolidStateNetworksDownloader())
135         return true;
136 #endif
137
138     return CachedResource::shouldIgnoreHTTPStatusCodeErrors();
139 }
140
141 } // namespace WebCore