From ab8e6cdc80fb1d9a5ce59b74f159493bd67e0e69 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 11 Jul 2011 10:56:53 -0600 Subject: [PATCH] convert classpath paths to absolute paths This is necessary because some apps expect CodeSource.getLocation() to return URL containing an absolute path. --- src/allocator.h | 33 +++++++++++++++++++++++++ src/finder.cpp | 65 ++++++++++++++++++------------------------------- src/posix.cpp | 9 +++++++ src/system.h | 3 +++ src/windows.cpp | 14 +++++++++++ 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/src/allocator.h b/src/allocator.h index c78273ad8e..fd03a4ecf3 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -22,6 +22,39 @@ class Allocator { virtual void free(const void* p, unsigned size) = 0; }; +inline const char* +append(Allocator* allocator, const char* a, const char* b, const char* c) +{ + unsigned al = strlen(a); + unsigned bl = strlen(b); + unsigned cl = strlen(c); + char* p = static_cast(allocator->allocate((al + bl + cl) + 1)); + memcpy(p, a, al); + memcpy(p + al, b, bl); + memcpy(p + al + bl, c, cl + 1); + return p; +} + +inline const char* +append(Allocator* allocator, const char* a, const char* b) +{ + unsigned al = strlen(a); + unsigned bl = strlen(b); + char* p = static_cast(allocator->allocate((al + bl) + 1)); + memcpy(p, a, al); + memcpy(p + al, b, bl + 1); + return p; +} + +inline const char* +copy(Allocator* allocator, const char* a) +{ + unsigned al = strlen(a); + char* p = static_cast(allocator->allocate(al + 1)); + memcpy(p, a, al + 1); + return p; +} + } // namespace vm #endif//ALLOCATOR_H diff --git a/src/finder.cpp b/src/finder.cpp index 88006be320..61e4a44da2 100644 --- a/src/finder.cpp +++ b/src/finder.cpp @@ -19,39 +19,6 @@ namespace { const bool DebugFind = false; -const char* -append(Allocator* allocator, const char* a, const char* b, const char* c) -{ - unsigned al = strlen(a); - unsigned bl = strlen(b); - unsigned cl = strlen(c); - char* p = static_cast(allocator->allocate((al + bl + cl) + 1)); - memcpy(p, a, al); - memcpy(p + al, b, bl); - memcpy(p + al + bl, c, cl + 1); - return p; -} - -const char* -append(Allocator* allocator, const char* a, const char* b) -{ - unsigned al = strlen(a); - unsigned bl = strlen(b); - char* p = static_cast(allocator->allocate((al + bl) + 1)); - memcpy(p, a, al); - memcpy(p + al, b, bl + 1); - return p; -} - -const char* -copy(Allocator* allocator, const char* a) -{ - unsigned al = strlen(a); - char* p = static_cast(allocator->allocate(al + 1)); - memcpy(p, a, al + 1); - return p; -} - class Element { public: class Iterator { @@ -136,9 +103,12 @@ class DirectoryElement: public Element { }; DirectoryElement(System* s, Allocator* allocator, const char* name): - s(s), allocator(allocator), name(name), - urlPrefix_(append(allocator, "file:", name, "/")), - sourceUrl_(append(allocator, "file:", name)) + s(s), + allocator(allocator), + originalName(name), + name(s->toAbsolutePath(allocator, name)), + urlPrefix_(append(allocator, "file:", this->name, "/")), + sourceUrl_(append(allocator, "file:", this->name)) { } virtual Element::Iterator* iterator() { @@ -181,6 +151,7 @@ class DirectoryElement: public Element { } virtual void dispose() { + allocator->free(originalName, strlen(originalName) + 1); allocator->free(name, strlen(name) + 1); allocator->free(urlPrefix_, strlen(urlPrefix_) + 1); allocator->free(sourceUrl_, strlen(sourceUrl_) + 1); @@ -189,6 +160,7 @@ class DirectoryElement: public Element { System* s; Allocator* allocator; + const char* originalName; const char* name; const char* urlPrefix_; const char* sourceUrl_; @@ -454,10 +426,17 @@ class JarElement: public Element { unsigned position; }; - JarElement(System* s, Allocator* allocator, const char* name): - s(s), allocator(allocator), name(name), - urlPrefix_(name ? append(allocator, "jar:file:", name, "!/") : 0), - sourceUrl_(name ? append(allocator, "file:", name) : 0), + JarElement(System* s, Allocator* allocator, const char* name, + bool canonicalizePath = true): + s(s), + allocator(allocator), + originalName(name), + name(name and canonicalizePath + ? s->toAbsolutePath(allocator, name) : name), + urlPrefix_(this->name + ? append(allocator, "jar:file:", this->name, "!/") : 0), + sourceUrl_(this->name + ? append(allocator, "file:", this->name) : 0), region(0), index(0) { } @@ -530,6 +509,9 @@ class JarElement: public Element { } virtual void dispose(unsigned size) { + if (originalName != name) { + allocator->free(originalName, strlen(originalName) + 1); + } allocator->free(name, strlen(name) + 1); allocator->free(urlPrefix_, strlen(urlPrefix_) + 1); allocator->free(sourceUrl_, strlen(sourceUrl_) + 1); @@ -544,6 +526,7 @@ class JarElement: public Element { System* s; Allocator* allocator; + const char* originalName; const char* name; const char* urlPrefix_; const char* sourceUrl_; @@ -555,7 +538,7 @@ class BuiltinElement: public JarElement { public: BuiltinElement(System* s, Allocator* allocator, const char* name, const char* libraryName): - JarElement(s, allocator, name), + JarElement(s, allocator, name, false), libraryName(libraryName ? copy(allocator, libraryName) : 0) { } diff --git a/src/posix.cpp b/src/posix.cpp index 2a5c7daf78..ffaf16ce17 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -776,6 +776,15 @@ class MySystem: public System { return SO_SUFFIX; } + virtual const char* toAbsolutePath(Allocator* allocator, const char* name) { + if (name[0] == '/') { + return copy(allocator, name); + } else { + char buffer[PATH_MAX]; + return append(allocator, getcwd(buffer, PATH_MAX), "/", name); + } + } + virtual Status load(System::Library** lib, const char* name) { diff --git a/src/system.h b/src/system.h index 6e2ea14721..06c724acd3 100644 --- a/src/system.h +++ b/src/system.h @@ -12,6 +12,7 @@ #define SYSTEM_H #include "common.h" +#include "allocator.h" namespace vm { @@ -140,6 +141,8 @@ class System { virtual Status load(Library**, const char* name) = 0; virtual char pathSeparator() = 0; virtual char fileSeparator() = 0; + virtual const char* toAbsolutePath(Allocator* allocator, + const char* name) = 0; virtual int64_t now() = 0; virtual void yield() = 0; virtual void exit(int code) = 0; diff --git a/src/windows.cpp b/src/windows.cpp index 4c75b80870..468d669738 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -752,6 +752,20 @@ class MySystem: public System { return SO_SUFFIX; } + virtual const char* toAbsolutePath(Allocator* allocator, const char* name) { + if (strncmp(name, "//", 2) == 0 + or strncmp(name, "\\\\", 2) == 0 + or strncmp(name + 1, ":/", 2) == 0 + or strncmp(name + 1, ":\\", 2) == 0) + { + return copy(allocator, name); + } else { + TCHAR buffer[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, buffer); + return append(allocator, buffer, "\\", name); + } + } + virtual Status load(System::Library** lib, const char* name) {