Diff
Modified: trunk/Source/WebKit2/ChangeLog (136996 => 136997)
--- trunk/Source/WebKit2/ChangeLog 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/ChangeLog 2012-12-08 00:16:39 UTC (rev 136997)
@@ -1,3 +1,72 @@
+2012-12-07 Alexey Proskuryakov <[email protected]>
+
+ Network process should use a correct storage session in private browsing mode
+ <rdar://problem/12838490>
+ https://bugs.webkit.org/show_bug.cgi?id=104401
+
+ Reviewed by Brady Eidson.
+
+ Notify NetworkProcess when it needs to create or destroy a private browsing session,
+ and add a NetworkResourceLoadParameters member telling if the particular resource
+ should be requested using it.
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::cookiesForDOM):
+ (WebKit::NetworkConnectionToWebProcess::setCookiesFromDOM):
+ (WebKit::NetworkConnectionToWebProcess::cookiesEnabled):
+ (WebKit::NetworkConnectionToWebProcess::getRawCookies):
+ (WebKit::NetworkConnectionToWebProcess::deleteCookie):
+ (WebKit::NetworkConnectionToWebProcess::getHostnamesWithCookies):
+ (WebKit::NetworkConnectionToWebProcess::deleteCookiesForHostname):
+ (WebKit::NetworkConnectionToWebProcess::deleteAllCookies):
+ Added another dummy argument to dummy networking context.
+
+ * NetworkProcess/NetworkProcess.cpp: (WebKit::NetworkProcess::initializeNetworkProcess):
+ Ensure private browsing session if it's needed due to a persistent preference, not
+ an API call at runtime (which is handled below as ensure/destroy).
+
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::start): Pass private browsing state to RemoteNetworkingContext
+ used for loading.
+ (WebKit::NetworkResourceLoader::willCacheResponse): Added an implemntation that
+ matches WebCore, but may be not needed.
+
+ * NetworkProcess/mac/RemoteNetworkingContext.h: (WebKit::RemoteNetworkingContext::create):
+ Store privateBrowsingEnabled flag.
+
+ * NetworkProcess/mac/RemoteNetworkingContext.mm: (WebKit::RemoteNetworkingContext::storageSession):
+ Return a private session when it's in use.
+
+ * Shared/Network/NetworkProcessCreationParameters.cpp:
+ (WebKit::NetworkProcessCreationParameters::encode):
+ (WebKit::NetworkProcessCreationParameters::decode):
+ * Shared/Network/NetworkProcessCreationParameters.h:
+ Pass privateBrowsingEnabled flag to the new process.
+
+ * Shared/Network/NetworkResourceLoadParameters.cpp:
+ (WebKit::NetworkResourceLoadParameters::NetworkResourceLoadParameters):
+ (WebKit::NetworkResourceLoadParameters::encode):
+ (WebKit::NetworkResourceLoadParameters::decode):
+ * Shared/Network/NetworkResourceLoadParameters.h:
+ (WebKit::NetworkResourceLoadParameters::inPrivateBrowsingMode):
+ Pass inPrivateBrowsingMode flag for the request.
+
+ * UIProcess/Network/NetworkProcessManager.h: (WebKit::NetworkProcessManager::process):
+ Exposed, so that we can send messages without going through NetworkProcessManager.
+
+ * UIProcess/WebContext.cpp:
+ (WebKit::WebContext::usesNetworkProcess):
+ (WebKit::anyContextUsesNetworkProcess):
+ (WebKit::WebContext::willStartUsingPrivateBrowsing):
+ (WebKit::WebContext::willStopUsingPrivateBrowsing):
+ Notify NetworkProcess when entering or exiting private browsing.
+
+ * UIProcess/WebContext.h: Exposed usesNetworkProcess() for the new static function
+ anyContextUsesNetworkProcess to use.
+
+ * WebProcess/Network/WebResourceLoadScheduler.cpp: (WebKit::WebResourceLoadScheduler::scheduleLoad):
+ Put current private browsing state over in NetworkResourceLoadParameters.
+
2012-12-07 Helder Correia <[email protected]>
[CoordGfx] Variable name starts with upper case character
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp (136996 => 136997)
--- trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -157,19 +157,19 @@
void NetworkConnectionToWebProcess::cookiesForDOM(const KURL& firstParty, const KURL& url, String& result)
{
// FIXME (NetworkProcess): Use a correct storage session.
- result = WebCore::cookiesForDOM(RemoteNetworkingContext::create(false, false).get(), firstParty, url);
+ result = WebCore::cookiesForDOM(RemoteNetworkingContext::create(false, false, false).get(), firstParty, url);
}
void NetworkConnectionToWebProcess::setCookiesFromDOM(const KURL& firstParty, const KURL& url, const String& cookieString)
{
// FIXME (NetworkProcess): Use a correct storage session.
- WebCore::setCookiesFromDOM(RemoteNetworkingContext::create(false, false).get(), firstParty, url, cookieString);
+ WebCore::setCookiesFromDOM(RemoteNetworkingContext::create(false, false, false).get(), firstParty, url, cookieString);
}
void NetworkConnectionToWebProcess::cookiesEnabled(const KURL& firstParty, const KURL& url, bool& result)
{
// FIXME (NetworkProcess): Use a correct storage session.
- result = WebCore::cookiesEnabled(RemoteNetworkingContext::create(false, false).get(), firstParty, url);
+ result = WebCore::cookiesEnabled(RemoteNetworkingContext::create(false, false, false).get(), firstParty, url);
}
void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(const KURL& firstParty, const KURL& url, String& result)
@@ -181,33 +181,33 @@
void NetworkConnectionToWebProcess::getRawCookies(const KURL& firstParty, const KURL& url, Vector<Cookie>& result)
{
// FIXME (NetworkProcess): Use a correct storage session.
- WebCore::getRawCookies(RemoteNetworkingContext::create(false, false).get(), firstParty, url, result);
+ WebCore::getRawCookies(RemoteNetworkingContext::create(false, false, false).get(), firstParty, url, result);
}
void NetworkConnectionToWebProcess::deleteCookie(const KURL& url, const String& cookieName)
{
// FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteCookie(RemoteNetworkingContext::create(false, false).get(), url, cookieName);
+ WebCore::deleteCookie(RemoteNetworkingContext::create(false, false, false).get(), url, cookieName);
}
void NetworkConnectionToWebProcess::getHostnamesWithCookies(Vector<String>& hostnames)
{
// FIXME (NetworkProcess): Use a correct storage session.
HashSet<String> hostnamesSet;
- WebCore::getHostnamesWithCookies(RemoteNetworkingContext::create(false, false).get(), hostnamesSet);
+ WebCore::getHostnamesWithCookies(RemoteNetworkingContext::create(false, false, false).get(), hostnamesSet);
WTF::copyToVector(hostnamesSet, hostnames);
}
void NetworkConnectionToWebProcess::deleteCookiesForHostname(const String& hostname)
{
// FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteCookiesForHostname(RemoteNetworkingContext::create(false, false).get(), hostname);
+ WebCore::deleteCookiesForHostname(RemoteNetworkingContext::create(false, false, false).get(), hostname);
}
void NetworkConnectionToWebProcess::deleteAllCookies()
{
// FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteAllCookies(RemoteNetworkingContext::create(false, false).get());
+ WebCore::deleteAllCookies(RemoteNetworkingContext::create(false, false, false).get());
}
} // namespace WebKit
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (136996 => 136997)
--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -101,6 +101,9 @@
#if PLATFORM(MAC) || USE(CFNETWORK)
RemoteNetworkingContext::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
#endif
+
+ if (parameters.privateBrowsingEnabled)
+ RemoteNetworkingContext::ensurePrivateBrowsingSession();
}
void NetworkProcess::createNetworkConnectionToWebProcess()
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (136996 => 136997)
--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -82,7 +82,7 @@
ref();
// FIXME (NetworkProcess): Create RemoteNetworkingContext with actual settings.
- m_networkingContext = RemoteNetworkingContext::create(false, false);
+ m_networkingContext = RemoteNetworkingContext::create(false, false, m_requestParameters.inPrivateBrowsingMode());
// FIXME (NetworkProcess): Pass an actual value for defersLoading
m_handle = ResourceHandle::create(m_networkingContext.get(), m_requestParameters.request(), this, false /* defersLoading */, m_requestParameters.contentSniffingPolicy() == SniffContent);
@@ -234,9 +234,11 @@
notImplemented();
}
-void NetworkResourceLoader::willCacheResponse(WebCore::ResourceHandle*, WebCore::CacheStoragePolicy&)
+void NetworkResourceLoader::willCacheResponse(WebCore::ResourceHandle*, WebCore::CacheStoragePolicy& policy)
{
- notImplemented();
+ // FIXME (12838543): Unsure if this is needed, private session is in-memory anyway.
+ if (policy == StorageAllowed && m_requestParameters.inPrivateBrowsingMode())
+ policy = StorageAllowedInMemoryOnly;
}
bool NetworkResourceLoader::shouldUseCredentialStorage(ResourceHandle*)
Modified: trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h (136996 => 136997)
--- trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h 2012-12-08 00:16:39 UTC (rev 136997)
@@ -32,9 +32,9 @@
class RemoteNetworkingContext : public WebCore::NetworkingContext {
public:
- static PassRefPtr<RemoteNetworkingContext> create(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled)
+ static PassRefPtr<RemoteNetworkingContext> create(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled)
{
- return adoptRef(new RemoteNetworkingContext(needsSiteSpecificQuirks, localFileContentSniffingEnabled));
+ return adoptRef(new RemoteNetworkingContext(needsSiteSpecificQuirks, localFileContentSniffingEnabled, privateBrowsingEnabled));
}
virtual ~RemoteNetworkingContext();
@@ -43,7 +43,7 @@
static void destroyPrivateBrowsingSession();
private:
- RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled);
+ RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled);
virtual bool isValid() const OVERRIDE;
@@ -55,6 +55,7 @@
bool m_needsSiteSpecificQuirks;
bool m_localFileContentSniffingEnabled;
+ bool m_privateBrowsingEnabled;
};
}
Modified: trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm (136996 => 136997)
--- trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm 2012-12-08 00:16:39 UTC (rev 136997)
@@ -37,9 +37,10 @@
static CFURLStorageSessionRef privateBrowsingStorageSession;
-RemoteNetworkingContext::RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled)
+RemoteNetworkingContext::RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled)
: m_needsSiteSpecificQuirks(needsSiteSpecificQuirks)
, m_localFileContentSniffingEnabled(localFileContentSniffingEnabled)
+ , m_privateBrowsingEnabled(privateBrowsingEnabled)
{
}
@@ -64,7 +65,11 @@
CFURLStorageSessionRef RemoteNetworkingContext::storageSession() const
{
- // FIXME (NetworkProcess): Implement.
+ if (m_privateBrowsingEnabled) {
+ ASSERT(privateBrowsingStorageSession);
+ return privateBrowsingStorageSession;
+ }
+ // FIXME (NetworkProcess): Return a default session that's used for testing.
return 0;
}
Modified: trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp (136996 => 136997)
--- trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -42,6 +42,7 @@
encoder << parentProcessName;
encoder << uiProcessBundleIdentifier;
#endif
+ encoder << privateBrowsingEnabled;
}
bool NetworkProcessCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, NetworkProcessCreationParameters& result)
@@ -52,6 +53,8 @@
if (!decoder->decode(result.uiProcessBundleIdentifier))
return false;
#endif
+ if (!decoder->decode(result.privateBrowsingEnabled))
+ return false;
return true;
}
Modified: trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h (136996 => 136997)
--- trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h 2012-12-08 00:16:39 UTC (rev 136997)
@@ -47,6 +47,8 @@
String parentProcessName;
String uiProcessBundleIdentifier;
#endif
+
+ bool privateBrowsingEnabled;
};
} // namespace WebKit
Modified: trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.cpp (136996 => 136997)
--- trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -38,14 +38,16 @@
: m_priority(ResourceLoadPriorityVeryLow)
, m_contentSniffingPolicy(SniffContent)
, m_allowStoredCredentials(DoNotAllowStoredCredentials)
+ , m_inPrivateBrowsingMode(false)
{
}
-NetworkResourceLoadParameters::NetworkResourceLoadParameters(const ResourceRequest& request, ResourceLoadPriority priority, ContentSniffingPolicy contentSniffingPolicy, StoredCredentials allowStoredCredentials)
+NetworkResourceLoadParameters::NetworkResourceLoadParameters(const ResourceRequest& request, ResourceLoadPriority priority, ContentSniffingPolicy contentSniffingPolicy, StoredCredentials allowStoredCredentials, bool inPrivateBrowsingMode)
: m_request(request)
, m_priority(priority)
, m_contentSniffingPolicy(contentSniffingPolicy)
, m_allowStoredCredentials(allowStoredCredentials)
+ , m_inPrivateBrowsingMode(inPrivateBrowsingMode)
{
}
@@ -55,6 +57,7 @@
encoder.encodeEnum(m_priority);
encoder.encodeEnum(m_contentSniffingPolicy);
encoder.encodeEnum(m_allowStoredCredentials);
+ encoder.encode(m_inPrivateBrowsingMode);
}
bool NetworkResourceLoadParameters::decode(CoreIPC::ArgumentDecoder* decoder, NetworkResourceLoadParameters& result)
@@ -67,6 +70,8 @@
return false;
if (!decoder->decodeEnum(result.m_allowStoredCredentials))
return false;
+ if (!decoder->decode(result.m_inPrivateBrowsingMode))
+ return false;
return true;
}
Modified: trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.h (136996 => 136997)
--- trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.h 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.h 2012-12-08 00:16:39 UTC (rev 136997)
@@ -44,7 +44,7 @@
class NetworkResourceLoadParameters {
public:
NetworkResourceLoadParameters();
- NetworkResourceLoadParameters(const WebCore::ResourceRequest&, WebCore::ResourceLoadPriority, WebCore::ContentSniffingPolicy, WebCore::StoredCredentials);
+ NetworkResourceLoadParameters(const WebCore::ResourceRequest&, WebCore::ResourceLoadPriority, WebCore::ContentSniffingPolicy, WebCore::StoredCredentials, bool inPrivateBrowsingMode);
void encode(CoreIPC::ArgumentEncoder&) const;
static bool decode(CoreIPC::ArgumentDecoder*, NetworkResourceLoadParameters&);
@@ -53,12 +53,14 @@
WebCore::ResourceLoadPriority priority() const { return m_priority; }
WebCore::ContentSniffingPolicy contentSniffingPolicy() const { return m_contentSniffingPolicy; }
WebCore::StoredCredentials allowStoredCredentials() const { return m_allowStoredCredentials; }
+ bool inPrivateBrowsingMode() const { return m_inPrivateBrowsingMode; }
private:
WebCore::ResourceRequest m_request;
WebCore::ResourceLoadPriority m_priority;
WebCore::ContentSniffingPolicy m_contentSniffingPolicy;
WebCore::StoredCredentials m_allowStoredCredentials;
+ bool m_inPrivateBrowsingMode;
};
} // namespace WebKit
Modified: trunk/Source/WebKit2/UIProcess/Network/NetworkProcessManager.h (136996 => 136997)
--- trunk/Source/WebKit2/UIProcess/Network/NetworkProcessManager.h 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/UIProcess/Network/NetworkProcessManager.h 2012-12-08 00:16:39 UTC (rev 136997)
@@ -46,6 +46,8 @@
void ensureNetworkProcess();
+ NetworkProcessProxy* process() { return m_networkProcess.get(); }
+
void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>);
void removeNetworkProcessProxy(NetworkProcessProxy*);
Modified: trunk/Source/WebKit2/UIProcess/WebContext.cpp (136996 => 136997)
--- trunk/Source/WebKit2/UIProcess/WebContext.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/UIProcess/WebContext.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -73,6 +73,8 @@
#if ENABLE(NETWORK_PROCESS)
#include "NetworkProcessManager.h"
+#include "NetworkProcessMessages.h"
+#include "NetworkProcessProxy.h"
#endif
#if USE(SOUP)
@@ -324,11 +326,37 @@
#endif
}
+bool WebContext::usesNetworkProcess() const
+{
+#if ENABLE(NETWORK_PROCESS)
+ return m_usesNetworkProcess;
+#else
+ return false;
+#endif
+}
+
+#if ENABLE(NETWORK_PROCESS)
+static bool anyContextUsesNetworkProcess()
+{
+ const Vector<WebContext*>& contexts = WebContext::allContexts();
+ for (size_t i = 0, count = contexts.size(); i < count; ++i)
+ if (contexts[i]->usesNetworkProcess())
+ return true;
+
+ return false;
+}
+#endif
+
void WebContext::willStartUsingPrivateBrowsing()
{
if (m_privateBrowsingEnterCount++)
return;
+#if ENABLE(NETWORK_PROCESS)
+ if (anyContextUsesNetworkProcess())
+ NetworkProcessManager::shared().process()->send(Messages::NetworkProcess::EnsurePrivateBrowsingSession(), 0);
+#endif
+
const Vector<WebContext*>& contexts = allContexts();
for (size_t i = 0, count = contexts.size(); i < count; ++i)
contexts[i]->sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession());
@@ -341,6 +369,11 @@
if (m_privateBrowsingEnterCount && --m_privateBrowsingEnterCount)
return;
+#if ENABLE(NETWORK_PROCESS)
+ if (anyContextUsesNetworkProcess())
+ NetworkProcessManager::shared().process()->send(Messages::NetworkProcess::DestroyPrivateBrowsingSession(), 0);
+#endif
+
const Vector<WebContext*>& contexts = allContexts();
for (size_t i = 0, count = contexts.size(); i < count; ++i)
contexts[i]->sendToAllProcesses(Messages::WebProcess::DestroyPrivateBrowsingSession());
Modified: trunk/Source/WebKit2/UIProcess/WebContext.h (136996 => 136997)
--- trunk/Source/WebKit2/UIProcess/WebContext.h 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/UIProcess/WebContext.h 2012-12-08 00:16:39 UTC (rev 136997)
@@ -244,6 +244,7 @@
void textCheckerStateChanged();
void setUsesNetworkProcess(bool);
+ bool usesNetworkProcess() const;
#if PLATFORM(MAC)
static bool applicationIsOccluded() { return s_applicationIsOccluded; }
Modified: trunk/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp (136996 => 136997)
--- trunk/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp 2012-12-07 23:43:48 UTC (rev 136996)
+++ trunk/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp 2012-12-08 00:16:39 UTC (rev 136997)
@@ -104,8 +104,8 @@
// In practice clients we know about don't care about the identifier, but this is another reason
// we need to make sure ResourceLoaders get correct identifiers right off the bat.
StoredCredentials allowStoredCredentials = resourceLoader->shouldUseCredentialStorage() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
-
- NetworkResourceLoadParameters loadParameters(request, priority, resourceLoader->shouldSniffContent() ? SniffContent : DoNotSniffContent, allowStoredCredentials);
+
+ NetworkResourceLoadParameters loadParameters(request, priority, resourceLoader->shouldSniffContent() ? SniffContent : DoNotSniffContent, allowStoredCredentials, resourceLoader->frameLoader()->frame()->settings()->privateBrowsingEnabled());
if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad::Reply(identifier), 0)) {
// FIXME (NetworkProcess): What should we do if this fails?
ASSERT_NOT_REACHED();