WebKit Bugzilla
Attachment 372708 Details for
Bug 187460
: ResourceResponseBase wastes a lot of space because of std::optional<>
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-187460-20190623224059.patch (text/plain), 20.64 KB, created by
Rob Buis
on 2019-06-23 13:41:00 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rob Buis
Created:
2019-06-23 13:41:00 PDT
Size:
20.64 KB
patch
obsolete
>Subversion Revision: 246709 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 80896f8e9f86f52bb683773c1f23577bb9458c6b..9387989836d25c5ff54b0c9452c2a4dcd30f6df1 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,46 @@ >+2019-06-23 Rob Buis <rbuis@igalia.com> >+ >+ ResourceResponseBase wastes a lot of space because of std::optional<> >+ https://bugs.webkit.org/show_bug.cgi?id=187460 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Waste less space in ResourceResponseBase by shrinking >+ ParsedContentRange. >+ >+ No new tests because there is no behavior change. >+ >+ * inspector/NetworkResourcesData.cpp: >+ (WebCore::NetworkResourcesData::responseReceived): >+ * inspector/NetworkResourcesData.h: >+ (WebCore::NetworkResourcesData::ResourceData::httpStatusCode const): >+ (WebCore::NetworkResourcesData::ResourceData::setHTTPStatusCode): >+ * inspector/agents/InspectorNetworkAgent.cpp: >+ (WebCore::InspectorNetworkAgent::buildObjectForResourceResponse): >+ * platform/network/BlobResourceHandle.cpp: >+ * platform/network/NetworkLoadMetrics.h: >+ * platform/network/ParsedContentRange.cpp: >+ (WebCore::areContentRangeValuesValid): >+ (WebCore::parseContentRange): >+ (WebCore::ParsedContentRange::ParsedContentRange): >+ (WebCore::ParsedContentRange::headerValue const): >+ * platform/network/ParsedContentRange.h: >+ (WebCore::ParsedContentRange::isValid const): >+ (WebCore::ParsedContentRange::lastBytePosition const): >+ * platform/network/ResourceResponseBase.cpp: >+ (WebCore::ResourceResponseBase::ResourceResponseBase): >+ (WebCore::ResourceResponseBase::includeCertificateInfo const): >+ (WebCore::ResourceResponseBase::isSuccessful const): >+ (WebCore::ResourceResponseBase::httpStatusCode const): >+ (WebCore::ResourceResponseBase::setHTTPStatusCode): >+ * platform/network/ResourceResponseBase.h: >+ (WebCore::ResourceResponseBase::isRedirectionStatusCode): >+ (WebCore::ResourceResponseBase::certificateInfo const): >+ (WebCore::ResourceResponseBase::encode const): >+ (WebCore::ResourceResponseBase::decode): >+ * platform/network/curl/ResourceResponseCurl.cpp: >+ (WebCore::ResourceResponse::setCertificateInfo): >+ > 2019-06-21 Sihui Liu <sihui_liu@apple.com> > > openDatabase should return an empty object when WebSQL is disabled >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 1bce3f913699aae1c55275fd405482c8604bfb01..75c626a88a1451db79499d96ed6c3de87f297a69 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,12 @@ >+2019-06-23 Rob Buis <rbuis@igalia.com> >+ >+ ResourceResponseBase wastes a lot of space because of std::optional<> >+ https://bugs.webkit.org/show_bug.cgi?id=187460 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * NetworkProcess/NetworkDataTaskBlob.cpp: >+ > 2019-06-21 Jiewen Tan <jiewen_tan@apple.com> > > Unreviewed, a build fix after r246701 >diff --git a/Source/WebCore/inspector/NetworkResourcesData.cpp b/Source/WebCore/inspector/NetworkResourcesData.cpp >index d3b759f29ccf1ae180280d5e173670d29c4f8cc1..10104006a76e7f1990e9bf6c0fe513aaaa59592e 100644 >--- a/Source/WebCore/inspector/NetworkResourcesData.cpp >+++ b/Source/WebCore/inspector/NetworkResourcesData.cpp >@@ -165,7 +165,7 @@ void NetworkResourcesData::responseReceived(const String& requestId, const Strin > if (InspectorNetworkAgent::shouldTreatAsText(response.mimeType())) > resourceData->setDecoder(InspectorNetworkAgent::createTextDecoder(response.mimeType(), response.textEncodingName())); > >- if (auto& certificateInfo = response.certificateInfo()) >+ if (auto certificateInfo = response.certificateInfo()) > resourceData->setCertificateInfo(certificateInfo); > } > >diff --git a/Source/WebCore/inspector/NetworkResourcesData.h b/Source/WebCore/inspector/NetworkResourcesData.h >index 8c428fccd5062ca33772009ed4c991da31ce9afd..642c3def7ea83dd62c5b509fe34c613a2836f3c7 100644 >--- a/Source/WebCore/inspector/NetworkResourcesData.h >+++ b/Source/WebCore/inspector/NetworkResourcesData.h >@@ -72,8 +72,8 @@ public: > InspectorPageAgent::ResourceType type() const { return m_type; } > void setType(InspectorPageAgent::ResourceType type) { m_type = type; } > >- int httpStatusCode() const { return m_httpStatusCode; } >- void setHTTPStatusCode(int httpStatusCode) { m_httpStatusCode = httpStatusCode; } >+ int16_t httpStatusCode() const { return m_httpStatusCode; } >+ void setHTTPStatusCode(int16_t httpStatusCode) { m_httpStatusCode = httpStatusCode; } > > const String& textEncodingName() const { return m_textEncodingName; } > void setTextEncodingName(const String& textEncodingName) { m_textEncodingName = textEncodingName; } >@@ -113,7 +113,7 @@ public: > Optional<CertificateInfo> m_certificateInfo; > CachedResource* m_cachedResource { nullptr }; > InspectorPageAgent::ResourceType m_type { InspectorPageAgent::OtherResource }; >- int m_httpStatusCode { 0 }; >+ int16_t m_httpStatusCode { 0 }; > bool m_isContentEvicted { false }; > bool m_base64Encoded { false }; > bool m_forceBufferData { false }; >diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp >index 3e4e96eb231a054b2121247bc2cb09165f0265b3..e24fc3b15127b476d0a888ef1312e523014a9f07 100644 >--- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp >+++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp >@@ -335,7 +335,7 @@ RefPtr<Inspector::Protocol::Network::Response> InspectorNetworkAgent::buildObjec > if (resourceLoader) > responseObject->setTiming(buildObjectForTiming(response.deprecatedNetworkLoadMetrics(), *resourceLoader)); > >- if (auto& certificateInfo = response.certificateInfo()) { >+ if (auto certificateInfo = response.certificateInfo()) { > auto securityPayload = Inspector::Protocol::Security::Security::create() > .release(); > >diff --git a/Source/WebCore/platform/network/BlobResourceHandle.cpp b/Source/WebCore/platform/network/BlobResourceHandle.cpp >index cc67ce688f3bca222690b43f105878ba9e3c28f8..42fd325c575a07887500996d9f9b8f3a49ae1422 100644 >--- a/Source/WebCore/platform/network/BlobResourceHandle.cpp >+++ b/Source/WebCore/platform/network/BlobResourceHandle.cpp >@@ -53,11 +53,11 @@ namespace WebCore { > > static const unsigned bufferSize = 512 * 1024; > >-static const int httpOK = 200; >-static const int httpPartialContent = 206; >-static const int httpNotAllowed = 403; >-static const int httpRequestedRangeNotSatisfiable = 416; >-static const int httpInternalError = 500; >+static const int16_t httpOK = 200; >+static const int16_t httpPartialContent = 206; >+static const int16_t httpNotAllowed = 403; >+static const int16_t httpRequestedRangeNotSatisfiable = 416; >+static const int16_t httpInternalError = 500; > static const char* httpOKText = "OK"; > static const char* httpPartialContentText = "Partial Content"; > static const char* httpNotAllowedText = "Not Allowed"; >diff --git a/Source/WebCore/platform/network/NetworkLoadMetrics.h b/Source/WebCore/platform/network/NetworkLoadMetrics.h >index 03c18b6927a2d4060e98f4d23f1db52841d275ae..b1170837f9cbb687ed696fd466cdc54e81ec2f60 100644 >--- a/Source/WebCore/platform/network/NetworkLoadMetrics.h >+++ b/Source/WebCore/platform/network/NetworkLoadMetrics.h >@@ -168,12 +168,12 @@ public: > String connectionIdentifier; > NetworkLoadPriority priority; > >- String tlsProtocol; >- String tlsCipher; >- > // Whether or not all of the properties (0 or otherwise) have been set. > bool complete { false }; > >+ String tlsProtocol; >+ String tlsCipher; >+ > HTTPHeaderMap requestHeaders; > > uint64_t requestHeaderBytesSent; >diff --git a/Source/WebCore/platform/network/ParsedContentRange.cpp b/Source/WebCore/platform/network/ParsedContentRange.cpp >index a3d4f044059dfd9a57b31929db8f112c15f62113..233ba3996592cef2a95d3b6f143432d56e3cd6b2 100644 >--- a/Source/WebCore/platform/network/ParsedContentRange.cpp >+++ b/Source/WebCore/platform/network/ParsedContentRange.cpp >@@ -31,7 +31,7 @@ > > namespace WebCore { > >-static bool areContentRangeValuesValid(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength) >+static bool areContentRangeValuesValid(int64_t firstBytePosition, ParsedContentRange::BytePosition lastBytePosition, int64_t instanceLength) > { > // From <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html> > // 14.16 Content-Range >@@ -40,16 +40,16 @@ static bool areContentRangeValuesValid(int64_t firstBytePosition, int64_t lastBy > if (firstBytePosition < 0) > return false; > >- if (lastBytePosition < firstBytePosition) >+ if (lastBytePosition.value() < firstBytePosition) > return false; > > if (instanceLength == ParsedContentRange::UnknownLength) > return true; > >- return lastBytePosition < instanceLength; >+ return lastBytePosition.value() < instanceLength; > } > >-static bool parseContentRange(const String& headerValue, int64_t& firstBytePosition, int64_t& lastBytePosition, int64_t& instanceLength) >+static bool parseContentRange(const String& headerValue, int64_t& firstBytePosition, ParsedContentRange::BytePosition& lastBytePosition, int64_t& instanceLength) > { > // From <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html> > // 14.16 Content-Range >@@ -111,7 +111,8 @@ static bool parseContentRange(const String& headerValue, int64_t& firstBytePosit > > ParsedContentRange::ParsedContentRange(const String& headerValue) > { >- m_isValid = parseContentRange(headerValue, m_firstBytePosition, m_lastBytePosition, m_instanceLength); >+ if (!parseContentRange(headerValue, m_firstBytePosition, m_lastBytePosition, m_instanceLength)) >+ m_lastBytePosition = -1; > } > > ParsedContentRange::ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength) >@@ -119,16 +120,17 @@ ParsedContentRange::ParsedContentRange(int64_t firstBytePosition, int64_t lastBy > , m_lastBytePosition(lastBytePosition) > , m_instanceLength(instanceLength) > { >- m_isValid = areContentRangeValuesValid(m_firstBytePosition, m_lastBytePosition, m_instanceLength); >+ if (!areContentRangeValuesValid(m_firstBytePosition, m_lastBytePosition, m_instanceLength)) >+ m_lastBytePosition = -1; > } > > String ParsedContentRange::headerValue() const > { >- if (!m_isValid) >+ if (!isValid()) > return String(); > if (m_instanceLength == UnknownLength) >- return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition, "/*"); >- return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition, '/', m_instanceLength); >+ return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition.value(), "/*"); >+ return makeString("bytes ", m_firstBytePosition, '-', m_lastBytePosition.value(), '/', m_instanceLength); > } > > } >diff --git a/Source/WebCore/platform/network/ParsedContentRange.h b/Source/WebCore/platform/network/ParsedContentRange.h >index 5a0704bd4b96fdcba90dc14ca466cb8efd7de5c0..426a96d00783b5fca3c98391fbdcc52e6ab13583 100644 >--- a/Source/WebCore/platform/network/ParsedContentRange.h >+++ b/Source/WebCore/platform/network/ParsedContentRange.h >@@ -27,6 +27,7 @@ > #define ParsedContentRange_h > > #include <wtf/Forward.h> >+#include <wtf/Markable.h> > > namespace WebCore { > >@@ -36,22 +37,23 @@ public: > ParsedContentRange() { } > WEBCORE_EXPORT ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength); > >- bool isValid() const { return m_isValid; } >+ bool isValid() const { return (bool)m_lastBytePosition; } > int64_t firstBytePosition() const { return m_firstBytePosition; } >- int64_t lastBytePosition() const { return m_lastBytePosition; } >+ int64_t lastBytePosition() const { return m_lastBytePosition.value(); } > int64_t instanceLength() const { return m_instanceLength; } > > WEBCORE_EXPORT String headerValue() const; > > enum { UnknownLength = std::numeric_limits<int64_t>::max() }; > >+ using BytePosition = Markable<int64_t, IntegralMarkableTraits<int64_t, -1>>; >+ > private: > template<typename T> static bool isPositive(T); > > int64_t m_firstBytePosition { 0 }; >- int64_t m_lastBytePosition { 0 }; >+ BytePosition m_lastBytePosition; > int64_t m_instanceLength { UnknownLength }; >- bool m_isValid { false }; > }; > > } >diff --git a/Source/WebCore/platform/network/ResourceResponseBase.cpp b/Source/WebCore/platform/network/ResourceResponseBase.cpp >index 20ac64d57034c69ea92bc7a43536f16d795ffa29..8ad60f0a8bda8c682b88d8d8cce30e112939a7a1 100644 >--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp >+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp >@@ -48,7 +48,8 @@ bool isScriptAllowedByNosniff(const ResourceResponse& response) > } > > ResourceResponseBase::ResourceResponseBase() >- : m_haveParsedCacheControlHeader(false) >+ : m_includesCertificateInfo(false) >+ , m_haveParsedCacheControlHeader(false) > , m_haveParsedAgeHeader(false) > , m_haveParsedDateHeader(false) > , m_haveParsedExpiresHeader(false) >@@ -64,7 +65,7 @@ ResourceResponseBase::ResourceResponseBase(const URL& url, const String& mimeTyp > , m_mimeType(mimeType) > , m_expectedContentLength(expectedLength) > , m_textEncodingName(textEncodingName) >- , m_certificateInfo(CertificateInfo()) // Empty but valid for synthetic responses. >+ , m_includesCertificateInfo(true) // Empty but valid for synthetic responses. > , m_haveParsedCacheControlHeader(false) > , m_haveParsedAgeHeader(false) > , m_haveParsedDateHeader(false) >@@ -261,8 +262,9 @@ void ResourceResponseBase::setType(Type type) > > void ResourceResponseBase::includeCertificateInfo() const > { >- if (m_certificateInfo) >+ if (m_includesCertificateInfo) > return; >+ m_includesCertificateInfo = true; > m_certificateInfo = static_cast<const ResourceResponse*>(this)->platformCertificateInfo(); > } > >@@ -286,18 +288,18 @@ String ResourceResponseBase::sanitizeSuggestedFilename(const String& suggestedFi > > bool ResourceResponseBase::isSuccessful() const > { >- int code = httpStatusCode(); >+ int16_t code = httpStatusCode(); > return code >= 200 && code < 300; > } > >-int ResourceResponseBase::httpStatusCode() const >+int16_t ResourceResponseBase::httpStatusCode() const > { > lazyInit(CommonFieldsOnly); > > return m_httpStatusCode; > } > >-void ResourceResponseBase::setHTTPStatusCode(int statusCode) >+void ResourceResponseBase::setHTTPStatusCode(int16_t statusCode) > { > lazyInit(CommonFieldsOnly); > >diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h >index 9f1b3b2e7fc67935bf788d4977190dee5305855d..4136e336d624a93afc09ad4c0aa5e23e633c7f86 100644 >--- a/Source/WebCore/platform/network/ResourceResponseBase.h >+++ b/Source/WebCore/platform/network/ResourceResponseBase.h >@@ -48,7 +48,7 @@ public: > enum class Type : uint8_t { Basic, Cors, Default, Error, Opaque, Opaqueredirect }; > enum class Tainting : uint8_t { Basic, Cors, Opaque, Opaqueredirect }; > >- static bool isRedirectionStatusCode(int code) { return code == 301 || code == 302 || code == 303 || code == 307 || code == 308; } >+ static bool isRedirectionStatusCode(int16_t code) { return code == 301 || code == 302 || code == 303 || code == 307 || code == 308; } > > struct CrossThreadData { > CrossThreadData(const CrossThreadData&) = delete; >@@ -60,7 +60,7 @@ public: > String mimeType; > long long expectedContentLength; > String textEncodingName; >- int httpStatusCode; >+ int16_t httpStatusCode; > String httpStatusText; > String httpVersion; > HTTPHeaderMap httpHeaderFields; >@@ -89,8 +89,8 @@ public: > WEBCORE_EXPORT const String& textEncodingName() const; > WEBCORE_EXPORT void setTextEncodingName(const String& name); > >- WEBCORE_EXPORT int httpStatusCode() const; >- WEBCORE_EXPORT void setHTTPStatusCode(int); >+ WEBCORE_EXPORT int16_t httpStatusCode() const; >+ WEBCORE_EXPORT void setHTTPStatusCode(int16_t); > WEBCORE_EXPORT bool isRedirection() const; > > WEBCORE_EXPORT const String& httpStatusText() const; >@@ -127,7 +127,13 @@ public: > WEBCORE_EXPORT static String sanitizeSuggestedFilename(const String&); > > WEBCORE_EXPORT void includeCertificateInfo() const; >- const Optional<CertificateInfo>& certificateInfo() const { return m_certificateInfo; }; >+ Optional<CertificateInfo> certificateInfo() const >+ { >+ if (m_includesCertificateInfo) >+ return m_certificateInfo; >+ return WTF::nullopt; >+ } >+ > > // These functions return parsed values of the corresponding response headers. > WEBCORE_EXPORT bool cacheControlContainsNoCache() const; >@@ -214,8 +220,6 @@ protected: > HTTPHeaderMap m_httpHeaderFields; > mutable NetworkLoadMetrics m_networkLoadMetrics; > >- mutable Optional<CertificateInfo> m_certificateInfo; >- > private: > mutable Markable<Seconds, Seconds::MarkableTraits> m_age; > mutable Markable<WallTime, WallTime::MarkableTraits> m_date; >@@ -224,6 +228,10 @@ private: > mutable ParsedContentRange m_contentRange; > mutable CacheControlDirectives m_cacheControlDirectives; > >+protected: >+ mutable bool m_includesCertificateInfo : 1; >+ >+private: > mutable bool m_haveParsedCacheControlHeader : 1; > mutable bool m_haveParsedAgeHeader : 1; > mutable bool m_haveParsedDateHeader : 1; >@@ -240,7 +248,8 @@ private: > Tainting m_tainting { Tainting::Basic }; > > protected: >- int m_httpStatusCode { 0 }; >+ int16_t m_httpStatusCode; >+ mutable CertificateInfo m_certificateInfo; > }; > > inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); } >@@ -267,7 +276,9 @@ void ResourceResponseBase::encode(Encoder& encoder) const > if (Encoder::isIPCEncoder) > encoder << m_networkLoadMetrics; > >- encoder << m_httpStatusCode; >+ encoder << static_cast<int32_t>(m_httpStatusCode); >+ bool includesCertificateInfo = m_includesCertificateInfo; >+ encoder << includesCertificateInfo; > encoder << m_certificateInfo; > encoder.encodeEnum(m_source); > encoder.encodeEnum(m_type); >@@ -304,8 +315,14 @@ bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& respon > // The networkLoadMetrics info is only send over IPC and not stored in disk cache. > if (Decoder::isIPCDecoder && !decoder.decode(response.m_networkLoadMetrics)) > return false; >- if (!decoder.decode(response.m_httpStatusCode)) >+ int32_t httpStatusCode; >+ if (!decoder.decode(httpStatusCode)) >+ return false; >+ response.m_httpStatusCode = httpStatusCode; >+ bool includesCertificateInfo = false; >+ if (!decoder.decode(includesCertificateInfo)) > return false; >+ response.m_includesCertificateInfo = includesCertificateInfo; > if (!decoder.decode(response.m_certificateInfo)) > return false; > if (!decoder.decodeEnum(response.m_source)) >diff --git a/Source/WebCore/platform/network/curl/ResourceResponseCurl.cpp b/Source/WebCore/platform/network/curl/ResourceResponseCurl.cpp >index 190a0f20c30a5ab737a5ad1ea6be5f709e0cfcac..3ed2ef0df0dc31e67ca7dc73efe51107b58a3583 100644 >--- a/Source/WebCore/platform/network/curl/ResourceResponseCurl.cpp >+++ b/Source/WebCore/platform/network/curl/ResourceResponseCurl.cpp >@@ -149,6 +149,7 @@ void ResourceResponse::setStatusLine(const String& header) > void ResourceResponse::setCertificateInfo(CertificateInfo&& certificateInfo) > { > m_certificateInfo = WTFMove(certificateInfo); >+ m_includesCertificateInfo = true; > } > > void ResourceResponse::setDeprecatedNetworkLoadMetrics(NetworkLoadMetrics&& networkLoadMetrics) >diff --git a/Source/WebKit/NetworkProcess/NetworkDataTaskBlob.cpp b/Source/WebKit/NetworkProcess/NetworkDataTaskBlob.cpp >index beb8b36c8b7f47fbd6cae9ccb0609f2b73f50c1d..eea297ffce2e8f8048ae91f76c575a3da6480e47 100644 >--- a/Source/WebKit/NetworkProcess/NetworkDataTaskBlob.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkDataTaskBlob.cpp >@@ -52,11 +52,11 @@ using namespace WebCore; > > static const unsigned bufferSize = 512 * 1024; > >-static const int httpOK = 200; >-static const int httpPartialContent = 206; >-static const int httpNotAllowed = 403; >-static const int httpRequestedRangeNotSatisfiable = 416; >-static const int httpInternalError = 500; >+static const int16_t httpOK = 200; >+static const int16_t httpPartialContent = 206; >+static const int16_t httpNotAllowed = 403; >+static const int16_t httpRequestedRangeNotSatisfiable = 416; >+static const int16_t httpInternalError = 500; > static const char* httpOKText = "OK"; > static const char* httpPartialContentText = "Partial Content"; > static const char* httpNotAllowedText = "Not Allowed";
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 187460
:
346147
|
372680
|
372681
|
372682
|
372683
|
372684
|
372698
|
372702
|
372703
|
372704
|
372706
|
372707
|
372708
|
372712
|
372713
|
372716
|
372738
|
372783
|
372788
|
372789
|
372799
|
372802
|
373173
|
373175
|
373176
|
373194