From 7c34e0a7b48572be1f9e3fb45911a13b01798e37 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 8 Jun 2018 21:18:11 +0200 Subject: qmake: escape colons and hashmarks in dependency paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit these characters can appear in file names, but are meta characters in dependency context. they have different semantics in make commands, so this required some reshuffling in the windows generator (which just treated dependencies and commands the same way). we don't actually escape colons for nmake, because it has magic treatment of drive letters anyway (and colons cannot appear elsewhere). also, if a target's filename gets quoted, batch rules will blow up. therefore, "funny" file names are really only supported as inputs - which is just enough to make resource embedding work. Task-number: QTBUG-22863 Task-number: QTBUG-68635 Change-Id: I473b0bf47d045298fd2ae481a29de603a3c1be30 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 13 +++++++++++++ qmake/generators/makefile.h | 4 ++-- qmake/generators/projectgenerator.h | 3 +++ qmake/generators/win32/mingw_make.cpp | 3 +-- qmake/generators/win32/mingw_make.h | 4 ++-- qmake/generators/win32/winmakefile.cpp | 12 ++++++++++++ qmake/generators/win32/winmakefile.h | 4 +++- 7 files changed, 36 insertions(+), 7 deletions(-) (limited to 'qmake') diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index dda323535d..580df85c1e 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2823,6 +2823,19 @@ MakefileGenerator::escapeFilePaths(const ProStringList &paths) const return ret; } +QString +MakefileGenerator::escapeDependencyPath(const QString &path) const +{ + QString ret = path; + if (!ret.isEmpty()) { + // Unix make semantics, to be inherited by unix and mingw generators. + static const QRegExp criticalChars(QStringLiteral("([\t :#])")); + ret.replace(criticalChars, QStringLiteral("\\\\1")); + debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); + } + return ret; +} + ProString MakefileGenerator::escapeDependencyPath(const ProString &path) const { diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 6341a141b9..f32bec650e 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -130,11 +130,11 @@ protected: QMakeProject *project; //escape - virtual QString escapeFilePath(const QString &path) const { return path; } + virtual QString escapeFilePath(const QString &path) const = 0; ProString escapeFilePath(const ProString &path) const; QStringList escapeFilePaths(const QStringList &paths) const; ProStringList escapeFilePaths(const ProStringList &paths) const; - virtual QString escapeDependencyPath(const QString &path) const { return escapeFilePath(path); } + virtual QString escapeDependencyPath(const QString &path) const; ProString escapeDependencyPath(const ProString &path) const; QStringList escapeDependencyPaths(const QStringList &paths) const; ProStringList escapeDependencyPaths(const ProStringList &paths) const; diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h index 587c415055..89c66f1ec8 100644 --- a/qmake/generators/projectgenerator.h +++ b/qmake/generators/projectgenerator.h @@ -42,6 +42,9 @@ class ProjectGenerator : public MakefileGenerator protected: virtual void init(); virtual bool writeMakefile(QTextStream &); + + virtual QString escapeFilePath(const QString &path) const { Q_ASSERT(false); return QString(); } + public: ProjectGenerator(); ~ProjectGenerator(); diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 6140debf05..6fcfe96380 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -46,8 +46,7 @@ QString MingwMakefileGenerator::escapeDependencyPath(const QString &path) const { QString ret = path; ret.replace('\\', "/"); // ### this shouldn't be here - ret.replace(' ', QLatin1String("\\ ")); - return ret; + return MakefileGenerator::escapeDependencyPath(ret); } QString MingwMakefileGenerator::getManifestFileForRcFile() const diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index ab9e5a9961..6f041cfd4a 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -39,8 +39,8 @@ public: MingwMakefileGenerator(); ~MingwMakefileGenerator(); protected: - QString escapeDependencyPath(const QString &path) const; - ProString escapeDependencyPath(const ProString &path) const { return MakefileGenerator::escapeDependencyPath(path); } + using MakefileGenerator::escapeDependencyPath; + virtual QString escapeDependencyPath(const QString &path) const; virtual ProString fixLibFlag(const ProString &lib); virtual QString getManifestFileForRcFile() const; bool writeMakefile(QTextStream &); diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 75bb5d236d..bca27b7044 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -773,6 +773,18 @@ QString Win32MakefileGenerator::escapeFilePath(const QString &path) const return ret; } +QString Win32MakefileGenerator::escapeDependencyPath(const QString &path) const +{ + QString ret = path; + if (!ret.isEmpty()) { + static const QRegExp criticalChars(QStringLiteral("([\t #])")); + if (ret.contains(criticalChars)) + ret = "\"" + ret + "\""; + debug_msg(2, "EscapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); + } + return ret; +} + QString Win32MakefileGenerator::cQuoted(const QString &str) { QString ret = str; diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 4d5ee9812b..b85a6b67df 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -47,8 +47,10 @@ protected: virtual void writeObjectsPart(QTextStream &t); virtual void writeImplicitRulesPart(QTextStream &t); virtual void writeBuildRulesPart(QTextStream &); + using MakefileGenerator::escapeFilePath; virtual QString escapeFilePath(const QString &path) const; - ProString escapeFilePath(const ProString &path) const { return MakefileGenerator::escapeFilePath(path); } + using MakefileGenerator::escapeDependencyPath; + virtual QString escapeDependencyPath(const QString &path) const; virtual void writeRcFilePart(QTextStream &t); -- cgit v1.2.3