Network Cache: Crash in WebCore::CachedResource::tryReplaceEncodedData
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / cache / NetworkCacheIOChannelCocoa.mm
index a59f555409d4147492b59bdf06b0cef69a2dacc9..b1629403334c67bf97c94c7fe763cf01e401c738 100644 (file)
 namespace WebKit {
 namespace NetworkCache {
 
-IOChannel::IOChannel(int fd)
-    : m_fileDescriptor(fd)
-{
-    m_dispatchIO = adoptDispatch(dispatch_io_create(DISPATCH_IO_RANDOM, fd, dispatch_get_main_queue(), [fd](int) {
-        close(fd);
-    }));
-    ASSERT(m_dispatchIO.get());
-    // This makes the channel read/write all data before invoking the handlers.
-    dispatch_io_set_low_water(m_dispatchIO.get(), std::numeric_limits<size_t>::max());
-}
-
-Ref<IOChannel> IOChannel::open(const String& filePath, IOChannel::Type type)
+IOChannel::IOChannel(const String& filePath, Type type)
+    : m_path(filePath)
+    , m_type(type)
 {
+    auto path = WebCore::fileSystemRepresentation(filePath);
     int oflag;
     mode_t mode;
 
-    switch (type) {
+    switch (m_type) {
     case Type::Create:
-        oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK;
+        // We don't want to truncate any existing file (with O_TRUNC) as another thread might be mapping it.
+        unlink(path.data());
+        oflag = O_RDWR | O_CREAT | O_NONBLOCK;
         mode = S_IRUSR | S_IWUSR;
         break;
     case Type::Write:
@@ -69,10 +63,20 @@ Ref<IOChannel> IOChannel::open(const String& filePath, IOChannel::Type type)
         mode = 0;
     }
 
-    CString path = WebCore::fileSystemRepresentation(filePath);
     int fd = ::open(path.data(), oflag, mode);
+    m_fileDescriptor = fd;
 
-    return adoptRef(*new IOChannel(fd));
+    m_dispatchIO = adoptDispatch(dispatch_io_create(DISPATCH_IO_RANDOM, fd, dispatch_get_main_queue(), [fd](int) {
+        close(fd);
+    }));
+    ASSERT(m_dispatchIO.get());
+    // This makes the channel read/write all data before invoking the handlers.
+    dispatch_io_set_low_water(m_dispatchIO.get(), std::numeric_limits<size_t>::max());
+}
+
+Ref<IOChannel> IOChannel::open(const String& filePath, IOChannel::Type type)
+{
+    return adoptRef(*new IOChannel(filePath, type));
 }
 
 void IOChannel::read(size_t offset, size_t size, std::function<void (Data&, int error)> completionHandler)