mirror of
https://github.com/QuasarApp/macdependency.git
synced 2025-04-28 05:14:32 +00:00
correct handling for placeholders @loader_path and @executable_path by really relying on the directory of the according file (and not the filename itself)
This commit is contained in:
parent
66202abd66
commit
2004b7a99c
@ -142,7 +142,7 @@ std::string DynamicLoader::replacePlaceholder(const std::string& name, const Mac
|
||||
if (name.find(PLACEHOLDERS[ExecutablePath]) == 0) {
|
||||
resolvedName.replace(0, strlen(PLACEHOLDERS[ExecutablePath]), architecture->getFile()->getExecutablePath());
|
||||
} else if (name.find(PLACEHOLDERS[LoaderPath]) == 0) {
|
||||
resolvedName.replace(0, strlen(PLACEHOLDERS[LoaderPath]), architecture->getFile()->getPath());
|
||||
resolvedName.replace(0, strlen(PLACEHOLDERS[LoaderPath]), architecture->getFile()->getDirectory());
|
||||
}
|
||||
return resolvedName;
|
||||
}
|
||||
|
@ -3,31 +3,31 @@
|
||||
|
||||
// use reference counting to reuse files for all used architectures
|
||||
InternalFile* InternalFile::create(InternalFile* file) {
|
||||
file->counter++;
|
||||
return file;
|
||||
file->counter++;
|
||||
return file;
|
||||
}
|
||||
|
||||
InternalFile* InternalFile::create(const std::string& filename) {
|
||||
return new InternalFile(filename);
|
||||
return new InternalFile(filename);
|
||||
}
|
||||
|
||||
void InternalFile::release() {
|
||||
counter--;
|
||||
if (counter < 1) {
|
||||
delete this;
|
||||
}
|
||||
counter--;
|
||||
if (counter < 1) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
InternalFile::InternalFile(const std::string& filename) :
|
||||
filename(filename), counter(1)
|
||||
filename(filename), counter(1)
|
||||
{
|
||||
// open file handle
|
||||
file.open(this->filename, std::ios_base::in | std::ios_base::binary);
|
||||
if (file.fail()) {
|
||||
std::ostringstream error;
|
||||
error << "Couldn't open file '" << filename << "'.";
|
||||
throw MachOException(error.str());
|
||||
}
|
||||
// open file handle
|
||||
file.open(this->filename, std::ios_base::in | std::ios_base::binary);
|
||||
if (file.fail()) {
|
||||
std::ostringstream error;
|
||||
error << "Couldn't open file '" << filename << "'.";
|
||||
throw MachOException(error.str());
|
||||
}
|
||||
|
||||
struct stat buffer;
|
||||
if (stat(filename.c_str(), &buffer) >= 0) {
|
||||
@ -38,12 +38,7 @@ InternalFile::InternalFile(const std::string& filename) :
|
||||
|
||||
// destructor is private since we use reference counting mechanism
|
||||
InternalFile::~InternalFile() {
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::string InternalFile::getPath() const {
|
||||
return filename;
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
/* returns whole filename (including path)*/
|
||||
@ -58,7 +53,7 @@ std::string InternalFile::getName() const {
|
||||
|
||||
/* returns filename without path */
|
||||
std::string InternalFile::getTitle() const {
|
||||
return filename;
|
||||
return filename;
|
||||
}
|
||||
|
||||
unsigned long long InternalFile::getSize() const {
|
||||
@ -66,27 +61,27 @@ unsigned long long InternalFile::getSize() const {
|
||||
}
|
||||
|
||||
bool InternalFile::seek(long long int position) {
|
||||
file.seekg(position, std::ios_base::beg);
|
||||
if (file.fail()) {
|
||||
file.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
file.seekg(position, std::ios_base::beg);
|
||||
if (file.fail()) {
|
||||
file.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::streamsize InternalFile::read(char* buffer, std::streamsize size) {
|
||||
file.read(buffer, size);
|
||||
if (file.fail()) {
|
||||
file.clear();
|
||||
return file.gcount();
|
||||
}
|
||||
// TODO: handle badbit
|
||||
return size;
|
||||
file.read(buffer, size);
|
||||
if (file.fail()) {
|
||||
file.clear();
|
||||
return file.gcount();
|
||||
}
|
||||
// TODO: handle badbit
|
||||
return size;
|
||||
}
|
||||
|
||||
long long int InternalFile::getPosition() {
|
||||
return file.tellg();
|
||||
}
|
||||
return file.tellg();
|
||||
}
|
||||
|
||||
time_t InternalFile::getLastModificationTime() const {
|
||||
return _lastWriteTime;
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
static InternalFile* create(const std::string& filename);
|
||||
void release();
|
||||
|
||||
std::string getPath() const;
|
||||
std::string getFolder() const;
|
||||
std::string getName() const;
|
||||
std::string getTitle() const;
|
||||
unsigned long long getSize() const;
|
||||
|
@ -204,10 +204,6 @@ std::string MachO::extractStringFromCFStringRef(CFStringRef cfStringRef) {
|
||||
return string;
|
||||
}
|
||||
|
||||
std::string MachO::getPath() const {
|
||||
return file->getPath();
|
||||
}
|
||||
|
||||
std::string MachO::getFileName() const {
|
||||
std::string filename = file->getName();
|
||||
return filename;
|
||||
|
@ -27,9 +27,7 @@ public:
|
||||
time_t getLastModificationTime() const;
|
||||
std::string getVersion() const;
|
||||
std::string getName() const;
|
||||
//sQIcon getIcon() const;*/
|
||||
const MachO* getParent() { return parent;}
|
||||
std::string getPath() const;
|
||||
static DynamicLoader* dynamicLoader;
|
||||
static int referenceCounter;
|
||||
private:
|
||||
|
@ -3,100 +3,102 @@
|
||||
#include "internalfile.h"
|
||||
|
||||
MachOFile::MachOFile(const std::string& filename,const MachOFile* parent, bool reversedByteOrder) :
|
||||
file(InternalFile::create(filename)), position(0), reversedByteOrder(reversedByteOrder), parent(parent)
|
||||
file(InternalFile::create(filename)), position(0), reversedByteOrder(reversedByteOrder), parent(parent)
|
||||
{
|
||||
if (parent) {
|
||||
executablePath = parent->executablePath;
|
||||
} else {
|
||||
executablePath = getPath();
|
||||
}
|
||||
if (parent) {
|
||||
executablePath = parent->executablePath;
|
||||
} else {
|
||||
executablePath = getDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
MachOFile::MachOFile(const MachOFile& file, bool reversedByteOrder) :
|
||||
file(InternalFile::create(file.file)), position(file.position), reversedByteOrder(reversedByteOrder), parent(file.parent), executablePath(file.executablePath)
|
||||
file(InternalFile::create(file.file)), position(file.position), reversedByteOrder(reversedByteOrder), parent(file.parent), executablePath(file.executablePath)
|
||||
{
|
||||
}
|
||||
|
||||
MachOFile::~MachOFile() {
|
||||
file->release();
|
||||
}
|
||||
|
||||
std::string MachOFile::getPath() const {
|
||||
return file->getPath();
|
||||
file->release();
|
||||
}
|
||||
|
||||
std::string MachOFile::getName() const {
|
||||
std::string filename = file->getName();
|
||||
return filename;
|
||||
std::string filename = file->getName();
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string MachOFile::getDirectory() const {
|
||||
size_t found = file->getName().find_last_of("/");
|
||||
return(file->getName().substr(0, found));
|
||||
}
|
||||
|
||||
std::string MachOFile::getTitle() const { return file->getTitle(); }
|
||||
unsigned long long MachOFile::getSize() const { return file->getSize(); }
|
||||
time_t MachOFile::getLastModificationTime() const { return file->getLastModificationTime(); }
|
||||
|
||||
uint32_t MachOFile::readUint32() {
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32(temp);
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32(temp);
|
||||
}
|
||||
|
||||
uint32_t MachOFile::readUint32LE() {
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32LE(temp);
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32LE(temp);
|
||||
}
|
||||
|
||||
uint32_t MachOFile::readUint32BE() {
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32BE(temp);
|
||||
unsigned int temp;
|
||||
readBytes((char*)&temp, sizeof(temp));
|
||||
return getUint32BE(temp);
|
||||
}
|
||||
|
||||
uint32_t MachOFile::getUint32BE(uint32_t data) {
|
||||
return convertByteOrder((char*)&data, true, sizeof(data));
|
||||
return convertByteOrder((char*)&data, true, sizeof(data));
|
||||
}
|
||||
|
||||
uint32_t MachOFile::getUint32LE(uint32_t data) {
|
||||
return convertByteOrder((char*)&data, false, sizeof(data));
|
||||
return convertByteOrder((char*)&data, false, sizeof(data));
|
||||
}
|
||||
|
||||
void MachOFile::readBytes(char* result, size_t size) {
|
||||
if (file->getPosition() != position) {
|
||||
file->seek(position);
|
||||
}
|
||||
if (file->read(result, size) != size)
|
||||
throw MachOException("File '" + file->getName() + "' not big enough. Probably no valid Mach-O!");
|
||||
position += size;
|
||||
if (file->getPosition() != position) {
|
||||
file->seek(position);
|
||||
}
|
||||
if (file->read(result, size) != size)
|
||||
throw MachOException("File '" + file->getName() + "' not big enough. Probably no valid Mach-O!");
|
||||
position += size;
|
||||
}
|
||||
|
||||
// convert from big endian or little endian to native format (Intel=little endian) and return as unsigned int (32bit)
|
||||
unsigned int MachOFile::convertByteOrder(char* data, bool isBigEndian, unsigned int numberOfBytes) {
|
||||
|
||||
assert(numberOfBytes> 0);
|
||||
assert(numberOfBytes <= 4); // max 4 byte
|
||||
assert(numberOfBytes> 0);
|
||||
assert(numberOfBytes <= 4); // max 4 byte
|
||||
|
||||
unsigned int result = 0;
|
||||
unsigned int result = 0;
|
||||
|
||||
// big endian extract (most significant byte first) (will work on little and big-endian computers)
|
||||
unsigned int numberOfShifts = isBigEndian ? numberOfBytes - 1 : 0;
|
||||
// big endian extract (most significant byte first) (will work on little and big-endian computers)
|
||||
unsigned int numberOfShifts = isBigEndian ? numberOfBytes - 1 : 0;
|
||||
|
||||
for (unsigned int n = 0; n < numberOfBytes; n++) {
|
||||
result |= static_cast<unsigned char>(data[n]) << (8 * numberOfShifts); // the bit shift will do the correct byte order for you
|
||||
numberOfShifts += isBigEndian ? -1 : +1;
|
||||
}
|
||||
return result;
|
||||
for (unsigned int n = 0; n < numberOfBytes; n++) {
|
||||
result |= static_cast<unsigned char>(data[n]) << (8 * numberOfShifts); // the bit shift will do the correct byte order for you
|
||||
numberOfShifts += isBigEndian ? -1 : +1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t MachOFile::reverseByteOrder(uint32_t data) {
|
||||
char* sourceData = (char*)&data;
|
||||
uint32_t result;
|
||||
char* destData = (char*)&result;
|
||||
char* sourceData = (char*)&data;
|
||||
uint32_t result;
|
||||
char* destData = (char*)&result;
|
||||
|
||||
destData[3] = sourceData[0];
|
||||
destData[2] = sourceData[1];
|
||||
destData[1] = sourceData[2];
|
||||
destData[0] = sourceData[3];
|
||||
destData[3] = sourceData[0];
|
||||
destData[2] = sourceData[1];
|
||||
destData[1] = sourceData[2];
|
||||
destData[0] = sourceData[3];
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
uint32_t getUint32(unsigned int data) const {return (reversedByteOrder?reverseByteOrder(data):data);}
|
||||
static uint32_t getUint32LE(uint32_t data);
|
||||
static uint32_t getUint32BE(uint32_t data);
|
||||
std::string getPath() const;
|
||||
std::string getDirectory() const;
|
||||
std::string getName() const;
|
||||
std::string getTitle() const;
|
||||
unsigned long long getSize() const;
|
||||
@ -32,6 +32,7 @@ public:
|
||||
private:
|
||||
static unsigned int convertByteOrder(char* data, bool isBigEndian, unsigned int numberOfBytes);
|
||||
static unsigned int reverseByteOrder(unsigned int data);
|
||||
static std::string getDirectory(const std::string& path);
|
||||
|
||||
InternalFile* file;
|
||||
long long int position;
|
||||
|
Loading…
x
Reference in New Issue
Block a user