Bug 1409692 - Use _wfopen instead of fopen on windows executed code in TraceLoggingGraph. r?jandem
MozReview-Commit-ID: BE90ptsAaFf
--- a/js/src/vm/TraceLoggingGraph.cpp
+++ b/js/src/vm/TraceLoggingGraph.cpp
@@ -11,16 +11,17 @@
#define getpid _getpid
#else
#include <unistd.h>
#endif
#include "mozilla/EndianUtils.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ScopeExit.h"
+#include "mozilla/FileAccessWrappers.h"
#include "jsstr.h"
#include "js/UniquePtr.h"
#include "threading/LockGuard.h"
#include "threading/Thread.h"
#include "vm/TraceLogging.h"
@@ -94,28 +95,28 @@ AllocTraceLogFilename(const char* patter
}
bool
TraceLoggerGraphState::init()
{
pid_ = (uint32_t) getpid();
js::UniqueChars filename = AllocTraceLogFilename("tl-data.%u.json", pid_);
- out = fopen(filename.get(), "w");
+ out = mozilla::FileOpen(filename.get(), "w");
if (!out) {
fprintf(stderr, "warning: failed to create TraceLogger output file %s\n", filename.get());
return false;
}
fprintf(out, "[");
// Write the latest tl-data.*.json file to tl-data.json.
// In most cases that is the wanted file.
js::UniqueChars masterFilename = AllocTraceLogFilename("tl-data.json");
- if (FILE* last = fopen(masterFilename.get(), "w")) {
+ if (FILE* last = mozilla::FileOpen(masterFilename.get(), "w")) {
char *basename = strrchr(filename.get(), '/');
basename = basename ? basename + 1 : filename.get();
fprintf(last, "\"%s\"", basename);
fclose(last);
}
#ifdef DEBUG
initialized = true;
@@ -233,29 +234,29 @@ TraceLoggerGraph::init(uint64_t startTim
uint32_t loggerId = traceLoggerGraphState->nextLoggerId();
if (loggerId == uint32_t(-1))
return false;
uint32_t pid = traceLoggerGraphState->pid();
js::UniqueChars dictFilename = AllocTraceLogFilename("tl-dict.%u.%d.json", pid, loggerId);
- dictFile = fopen(dictFilename.get(), "w");
+ dictFile = mozilla::FileOpen(dictFilename.get(), "w");
if (!dictFile)
return false;
auto cleanupDict = MakeScopeExit([&] { fclose(dictFile); dictFile = nullptr; });
js::UniqueChars treeFilename = AllocTraceLogFilename("tl-tree.%u.%d.tl", pid, loggerId);
- treeFile = fopen(treeFilename.get(), "w+b");
+ treeFile = mozilla::FileOpen(treeFilename.get(), "w+b");
if (!treeFile)
return false;
auto cleanupTree = MakeScopeExit([&] { fclose(treeFile); treeFile = nullptr; });
js::UniqueChars eventFilename = AllocTraceLogFilename("tl-event.%u.%d.tl", pid, loggerId);
- eventFile = fopen(eventFilename.get(), "wb");
+ eventFile = mozilla::FileOpen(eventFilename.get(), "wb");
if (!eventFile)
return false;
auto cleanupEvent = MakeScopeExit([&] { fclose(eventFile); eventFile = nullptr; });
// Create the top tree node and corresponding first stack item.
TreeEntry& treeEntry = tree.pushUninitialized();
treeEntry.setStart(startTimestamp);
treeEntry.setStop(0);
new file mode 100644
--- /dev/null
+++ b/mfbt/FileAccessWrappers.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Provides a safer way to use fopen on systems that don't support UTF file
+ * system, like Microsoft Windows. */
+
+#ifndef mozilla_FileAccessWrappers_h
+#define mozilla_FileAccessWrappers_h
+
+#include <stdio.h>
+#include <string.h>
+#ifdef XP_WIN
+#include <windows.h>
+#endif
+
+namespace mozilla {
+
+FILE*
+FileOpen(const char* path, const char* mode)
+{
+#ifdef XP_WIN
+ /* Prevent lossy conversion by using wchar_t* for path names on Windows. This
+ * is not the case on MacOS since the filesystem is always UTF-8 and nor on
+ * Linux where the 8-bit string is the canonical POSIX filename. */
+ const size_t wPathSize = strlen(path) + 1;
+ const size_t wModeSize = strlen(mode) + 1;
+ wchar_t wPath[wPathSize];
+ wchar_t wMode[wModeSize];
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, wPath, wPathSize);
+ MultiByteToWideChar(CP_UTF8, 0, mode, -1, wMode, wModeSize);
+ return _wfopen(wPath, wMode);
+#else
+ return fopen(path, mode);
+#endif
+}
+}
+
+#endif /* mozilla_FileAccessWrappers_h_ */
\ No newline at end of file
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -37,16 +37,17 @@ EXPORTS.mozilla = [
'double-conversion.h',
'DoublyLinkedList.h',
'EndianUtils.h',
'EnumeratedArray.h',
'EnumeratedRange.h',
'EnumSet.h',
'EnumTypeTraits.h',
'FastBernoulliTrial.h',
+ 'FileAccessWrappers.h',
'FloatingPoint.h',
'GuardObjects.h',
'HashFunctions.h',
'IndexSequence.h',
'IntegerPrintfMacros.h',
'IntegerRange.h',
'IntegerTypeTraits.h',
'JSONWriter.h',