Add support for relative pathnames to JSC config files
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Mar 2017 01:10:55 +0000 (01:10 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Mar 2017 01:10:55 +0000 (01:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169154

Reviewed by Saam Barati.

If the config file is a relative path, prepend the current working directory.
After canonicalizing the config file path, we extract its directory path and
use that for the directory for a relative log pathname.

* runtime/ConfigFile.cpp:
(JSC::ConfigFile::ConfigFile):
(JSC::ConfigFile::parse):
(JSC::ConfigFile::canonicalizePaths):
* runtime/ConfigFile.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213399 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ConfigFile.cpp
Source/JavaScriptCore/runtime/ConfigFile.h

index e42c7fc..84d36a3 100644 (file)
@@ -1,5 +1,22 @@
 2017-03-03  Michael Saboff  <msaboff@apple.com>
 
+        Add support for relative pathnames to JSC config files
+        https://bugs.webkit.org/show_bug.cgi?id=169154
+
+        Reviewed by Saam Barati.
+
+        If the config file is a relative path, prepend the current working directory.
+        After canonicalizing the config file path, we extract its directory path and
+        use that for the directory for a relative log pathname.
+
+        * runtime/ConfigFile.cpp:
+        (JSC::ConfigFile::ConfigFile):
+        (JSC::ConfigFile::parse):
+        (JSC::ConfigFile::canonicalizePaths):
+        * runtime/ConfigFile.h:
+
+2017-03-03  Michael Saboff  <msaboff@apple.com>
+
         Add load / store exclusive instruction group to ARM64 disassembler
         https://bugs.webkit.org/show_bug.cgi?id=169152
 
index cd61d95..37a2dda 100644 (file)
 namespace JSC {
 
 static const size_t s_processNameMax = 128;
-#if PLATFORM(WIN)
-static const size_t s_maxPathLength = 260; // Windows value for "MAX_PATH"
-#else
-static const size_t s_maxPathLength = PATH_MAX;
-#endif
 char ConfigFile::s_processName[s_processNameMax + 1] = { 0 };
 char ConfigFile::s_parentProcessName[s_processNameMax + 1] = { 0 };
 
@@ -211,8 +206,15 @@ private:
 };
 
 ConfigFile::ConfigFile(const char* filename)
-    : m_filename(filename)
 {
+    if (!filename)
+        m_filename[0] = '\0';
+    else {
+        strncpy(m_filename, filename, s_maxPathLength);
+        m_filename[s_maxPathLength] = '\0';
+    }
+
+    m_configDirectory[0] = '\0';
 }
 
 void ConfigFile::setProcessName(const char* processName)
@@ -230,6 +232,8 @@ void ConfigFile::parse()
     enum StatementNesting { TopLevelStatment, NestedStatement, NestedStatementFailedCriteria };
     enum ParseResult { ParseOK, ParseError, NestedStatementDone };
 
+    canonicalizePaths();
+
     ConfigFileScanner scanner(m_filename);
 
     if (!scanner.start())
@@ -242,8 +246,12 @@ void ConfigFile::parse()
     auto parseLogFile = [&](StatementNesting statementNesting) {
         char* filename = nullptr;
         if (scanner.tryConsume('=') && (filename = scanner.tryConsumeString())) {
-            if (statementNesting != NestedStatementFailedCriteria)
-                strncpy(logPathname, filename, s_maxPathLength);
+            if (statementNesting != NestedStatementFailedCriteria) {
+                if (filename[0] != '/')
+                    snprintf(logPathname, s_maxPathLength + 1, "%s/%s", m_configDirectory, filename);
+                else
+                    strncpy(logPathname, filename, s_maxPathLength);
+            }
 
             return ParseOK;
         }
@@ -410,4 +418,40 @@ void ConfigFile::parse()
         WTF::dataLogF("Error in JSC Config file on or near line %u, parsing '%s'\n", scanner.lineNumber(), scanner.currentBuffer());
 }
 
+void ConfigFile::canonicalizePaths()
+{
+    if (!m_filename[0])
+        return;
+
+#if OS(UNIX) || OS(DARWIN)
+    if (m_filename[0] != '/') {
+        // Relative path
+        char filenameBuffer[s_maxPathLength + 1];
+
+        if (getcwd(filenameBuffer, sizeof(filenameBuffer))) {
+            size_t pathnameLength = strlen(filenameBuffer);
+            bool shouldAddPathSeparator = filenameBuffer[pathnameLength - 1] != '/';
+            if (sizeof(filenameBuffer) - 1  >= pathnameLength + shouldAddPathSeparator) {
+                if (shouldAddPathSeparator)
+                    strncat(filenameBuffer, "/", 1);
+                strncat(filenameBuffer, m_filename, sizeof(filenameBuffer) - strlen(filenameBuffer) - 1);
+                strncpy(m_filename, filenameBuffer, s_maxPathLength);
+                m_filename[s_maxPathLength] = '\0';
+            }
+        }
+    }
+
+    char* lastPathSeperator = strrchr(m_filename, '/');
+
+    if (lastPathSeperator) {
+        unsigned dirnameLength = lastPathSeperator - &m_filename[0];
+        strncpy(m_configDirectory, m_filename, dirnameLength);
+        m_configDirectory[dirnameLength] = '\0';
+    } else {
+        m_configDirectory[0] = '/';
+        m_configDirectory[1] = '\0';
+    }
+#endif
+}
+
 } // namespace JSC
index a8964f4..10f60dc 100644 (file)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <limits.h>
+
 namespace JSC {
 
 class ConfigFile {
@@ -36,10 +38,19 @@ public:
     JS_EXPORT_PRIVATE void parse();
 
 private:
+    void canonicalizePaths();
+
+#if PLATFORM(WIN)
+    static const size_t s_maxPathLength = 260; // Windows value for "MAX_PATH"
+#else
+    static const size_t s_maxPathLength = PATH_MAX;
+#endif
+
     static char s_processName[];
     static char s_parentProcessName[];
 
-    const char* m_filename;
+    char m_filename[s_maxPathLength + 1];
+    char m_configDirectory[s_maxPathLength + 1];
 };
 
 } // namespace JSC