diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-09-22 08:50:43 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-09-22 08:50:43 +0200 |
commit | 4c70a1a6666a079872b8f1966bd398e924dc1d1a (patch) | |
tree | 0215f94340e0d86c4e0a422fb45ddfdb9ee3769d | |
parent | b078e0d638514b298616838fae090b8294bac32f (diff) |
Check harder whether file is really under WORKDIR
1977b57bc9aaea71252358fa502110c348153c70 "vcl: loplugin:override" had only hit
in out-of-tree builds, where the #include in the generated
workdir/CustomTarget/vcl/unx/kde4/tst_exclude_socket_notifiers.moc is an
absolute path. For in-tree builds, the generated #include line is
"../../../../../vcl/unx/kde4/tst_exclude_socket_notifiers.hxx", so the returned
getFileName() is .../workdir/../../../../../vcl/..., so was erroneously
considered to be under WORKDIR.
Change-Id: I9abef04b90ecb4921087a53ff196b833940085e5
-rw-r--r-- | compilerplugins/clang/plugin.cxx | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index 31648a5f9d2c..9f13ee7441b9 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -12,6 +12,7 @@ #include "plugin.hxx" #include <cassert> +#include <string> #include <clang/Basic/FileManager.h> #include <clang/Lex/Lexer.h> @@ -41,9 +42,51 @@ bool Plugin::ignoreLocation( SourceLocation loc ) return true; const char* bufferName = compiler.getSourceManager().getPresumedLoc( expansionLoc ).getFilename(); if( bufferName == NULL - || strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0 || strncmp( bufferName, SRCDIR "/external/", strlen( SRCDIR "/external/" )) == 0 ) return true; + if( strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0 ) + { + // workdir/CustomTarget/vcl/unx/kde4/tst_exclude_socket_notifiers.moc + // includes + // "../../../../../vcl/unx/kde4/tst_exclude_socket_notifiers.hxx", + // making the latter file erroneously match here; so strip any ".." + // segments: + if (strstr(bufferName, "/..") == nullptr) { + return true; + } + std::string s(bufferName); + for (std::string::size_type i = 0;;) { + i = s.find("/.", i); + if (i == std::string::npos) { + break; + } + if (i + 2 == s.length() || s[i + 2] == '/') { + s.erase(i, 2); // [AAA]/.[/CCC] -> [AAA][/CCC] + } else if (s[i + 2] == '.' + && (i + 3 == s.length() || s[i + 3] == '/')) + { + if (i == 0) { // /..[/CCC] -> /..[/CCC] + break; + } + auto j = s.rfind('/', i - 1); + if (j == std::string::npos) { + // BBB/..[/CCC] -> BBB/..[/CCC] (instead of BBB/../CCC -> + // CCC, to avoid wrong ../../CCC -> CCC; relative paths + // shouldn't happen anyway, and even if they did, wouldn't + // match against WORKDIR anyway, as WORKDIR should be + // absolute): + break; + } + s.erase(j, i + 3 - j); // AAA/BBB/..[/CCC] -> AAA[/CCC] + i = j; + } else { + i += 2; + } + } + if (strncmp(s.c_str(), WORKDIR, strlen(WORKDIR)) == 0) { + return true; + } + } if( strncmp( bufferName, BUILDDIR, strlen( BUILDDIR )) == 0 || strncmp( bufferName, SRCDIR, strlen( SRCDIR )) == 0 ) return false; // ok |