[post build lint] Check for absolute paths (#172)
This commit is contained in:
Родитель
7fbe87b0d3
Коммит
fcfbfa4a21
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
test="${CURRENT_INSTALLED_DIR}"
|
|
@ -0,0 +1,36 @@
|
|||
set(VCPKG_POLICY_EMPTY_INCLUDE_FOLDER enabled)
|
||||
|
||||
if("usage" IN_LIST FEATURES)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/usage" "Set TEST=${CURRENT_INSTALLED_DIR} to use the port\n")
|
||||
endif()
|
||||
if("header" IN_LIST FEATURES)
|
||||
configure_file("${CURRENT_PORT_DIR}/source.h.in" "${CURRENT_PACKAGES_DIR}/include/test.h")
|
||||
endif()
|
||||
if("header-comment" IN_LIST FEATURES)
|
||||
configure_file("${CURRENT_PORT_DIR}/source-comment.h.in" "${CURRENT_PACKAGES_DIR}/include/test.h")
|
||||
endif()
|
||||
if("python" IN_LIST FEATURES)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py" "test = \"${CURRENT_INSTALLED_DIR}\"\n")
|
||||
message(STATUS "Wtite to ${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py")
|
||||
endif()
|
||||
if("python-comment" IN_LIST FEATURES)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py" "# test = \"${CURRENT_INSTALLED_DIR}\"\n")
|
||||
endif()
|
||||
if("hash" IN_LIST FEATURES)
|
||||
configure_file("${CURRENT_PORT_DIR}/hash.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/test")
|
||||
endif()
|
||||
if("new-policy" IN_LIST FEATURES)
|
||||
set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)
|
||||
endif()
|
||||
if("packages" IN_LIST FEATURES)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py" "${CURRENT_PACKAGES_DIR}")
|
||||
endif()
|
||||
if("buildtrees" IN_LIST FEATURES)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py" "${CURRENT_BUILDTREES_DIR}")
|
||||
endif()
|
||||
if("native" IN_LIST FEATURES)
|
||||
cmake_path(NATIVE_PATH CURRENT_INSTALLED_DIR CURRENT_INSTALLED_DIR_NATIVE)
|
||||
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/test.py" "${CURRENT_INSTALLED_DIR_NATIVE}")
|
||||
endif()
|
||||
|
||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/../../../../LICENSE.txt" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
// char * test = "${CURRENT_INSTALLED_DIR}"
|
||||
|
||||
/*
|
||||
${CURRENT_INSTALLED_DIR}
|
||||
*/
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
char * test2 = R"--(/*
|
||||
|
||||
// ${CURRENT_INSTALLED_DIR} */
|
||||
)--";
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
|
||||
"name": "absolute-paths",
|
||||
"version": "1.0.0",
|
||||
"features": {
|
||||
"usage": {
|
||||
"description": ""
|
||||
},
|
||||
"header": {
|
||||
"description": ""
|
||||
},
|
||||
"header-comment": {
|
||||
"description": ""
|
||||
},
|
||||
"python": {
|
||||
"description": ""
|
||||
},
|
||||
"python-comment": {
|
||||
"description": ""
|
||||
},
|
||||
"hash": {
|
||||
"description": ""
|
||||
},
|
||||
"new-policy": {
|
||||
"description": ""
|
||||
},
|
||||
"packages": {
|
||||
"description": ""
|
||||
},
|
||||
"buildtrees": {
|
||||
"description": ""
|
||||
},
|
||||
"native": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
. $PSScriptRoot/../end-to-end-tests-prelude.ps1
|
||||
|
||||
$CurrentTest = "No absolute paths"
|
||||
|
||||
$commonArgs += @("--enforce-port-checks", "--binarysource=clear")
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[hash]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[python]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[python-comment]"
|
||||
Throw-IfFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[header]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[header-comment]"
|
||||
Throw-IfFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[usage]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[usage, new-policy]"
|
||||
Throw-IfFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[packages]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
||||
|
||||
Run-Vcpkg @commonArgs install "absolute-paths[native]"
|
||||
Throw-IfNotFailed
|
||||
Remove-Item -Recurse -Force $installRoot
|
|
@ -1338,6 +1338,13 @@ namespace vcpkg
|
|||
"One or more {vendor} credential providers failed to authenticate. See '{url}' for more details "
|
||||
"on how to provide credentials.");
|
||||
DECLARE_MESSAGE(FeedbackAppreciated, (), "", "Thank you for your feedback!");
|
||||
DECLARE_MESSAGE(
|
||||
FilesContainAbsolutePath1,
|
||||
(),
|
||||
"This message is printed before a list of found absolute paths, followed by FilesContainAbsolutePath2, "
|
||||
"followed by a list of found files.",
|
||||
"There should be no absolute paths, such as the following, in an installed package:");
|
||||
DECLARE_MESSAGE(FilesContainAbsolutePath2, (), "", "Absolute paths were found in the following files:");
|
||||
DECLARE_MESSAGE(FetchingBaselineInfo,
|
||||
(msg::package_name),
|
||||
"",
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "vcpkg/base/fwd/span.h"
|
||||
|
||||
namespace vcpkg::Strings::details
|
||||
{
|
||||
// first looks up to_string on `T` using ADL; then, if that isn't found,
|
||||
|
@ -218,6 +220,12 @@ namespace vcpkg::Strings
|
|||
|
||||
Optional<StringView> find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag);
|
||||
|
||||
bool contains_any_ignoring_c_comments(const std::string& source, View<StringView> to_find);
|
||||
|
||||
bool contains_any_ignoring_hash_comments(StringView source, View<StringView> to_find);
|
||||
|
||||
bool contains_any(StringView source, View<StringView> to_find);
|
||||
|
||||
bool equals(StringView a, StringView b);
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -266,6 +266,13 @@ namespace vcpkg::Util
|
|||
return std::find(begin(cont), end(cont), v);
|
||||
}
|
||||
|
||||
template<class Range, class T>
|
||||
bool contains(const Range& r, const T& el)
|
||||
{
|
||||
using std::end;
|
||||
return Util::find(r, el) != end(r);
|
||||
}
|
||||
|
||||
template<class Container, class Pred>
|
||||
auto find_if(Container&& cont, Pred pred)
|
||||
{
|
||||
|
|
|
@ -106,6 +106,7 @@ namespace vcpkg
|
|||
SKIP_DUMPBIN_CHECKS,
|
||||
SKIP_ARCHITECTURE_CHECK,
|
||||
CMAKE_HELPER_PORT,
|
||||
SKIP_ABSOLUTE_PATHS_CHECK,
|
||||
// Must be last
|
||||
COUNT,
|
||||
};
|
||||
|
|
|
@ -540,6 +540,9 @@
|
|||
"FileSeekFailed": "Failed to seek to position {byte_offset} in {path}.",
|
||||
"_FileSeekFailed.comment": "An example of {path} is /foo/bar. An example of {byte_offset} is 42.",
|
||||
"FileSystemOperationFailed": "Filesystem operation failed:",
|
||||
"FilesContainAbsolutePath1": "There should be no absolute paths, such as the following, in an installed package:",
|
||||
"_FilesContainAbsolutePath1.comment": "This message is printed before a list of found absolute paths, followed by FilesContainAbsolutePath2, followed by a list of found files.",
|
||||
"FilesContainAbsolutePath2": "Absolute paths were found in the following files:",
|
||||
"FilesExported": "Files exported at: {path}",
|
||||
"_FilesExported.comment": "An example of {path} is /foo/bar.",
|
||||
"FishCompletion": "vcpkg fish completion is already added at \"{path}\".",
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <vcpkg/base/api-stable-format.h>
|
||||
#include <vcpkg/base/expected.h>
|
||||
#include <vcpkg/base/span.h>
|
||||
#include <vcpkg/base/strings.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -55,6 +56,75 @@ TEST_CASE ("find_first_of", "[strings]")
|
|||
REQUIRE(find_first_of("abcdefg", "gb") == std::string("bcdefg"));
|
||||
}
|
||||
|
||||
TEST_CASE ("contains_any_ignoring_c_comments", "[strings]")
|
||||
{
|
||||
using vcpkg::Strings::contains_any_ignoring_c_comments;
|
||||
vcpkg::StringView to_find[] = {"abc", "wer"};
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"(abc)", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"("abc")", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"("" //abc)", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"(/*abc*/ "")", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"(/**abc*/ "")", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"(/**abc**/ "")", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"(/*abc)", to_find));
|
||||
// note that the line end is escaped making the single line comment include the abc
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments("// test \\\nabc", to_find));
|
||||
// note that the comment start is in a string literal so it isn't a comment
|
||||
REQUIRE(contains_any_ignoring_c_comments("\"//\" test abc", to_find));
|
||||
// note that the comment is in a raw string literal so it isn't a comment
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"( // abc )")-", to_find));
|
||||
// found after the raw string literal
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"( // )" abc)-", to_find));
|
||||
// comment after the raw string literal
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"( // )" // abc)-", to_find));
|
||||
// the above, but with a d_char_sequence for the raw literal
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"hello( // abc )hello")-", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"hello( // )hello" abc)-", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"hello( // )hello" // abc)-", to_find));
|
||||
// the above, but with a d_char_sequence that is a needle
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"abc( // abc )abc")-", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"abc( // )abc" abc)-", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"abc( // )abc" // abc)-", to_find));
|
||||
// raw literal termination edge cases
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R")-", to_find)); // ends input
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"h)-", to_find)); // ends input d_char
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"()-", to_find)); // ends input paren
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"h()-", to_find)); // ends input paren d_char
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"())-", to_find)); // ends input close paren
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"-(R"()")-", to_find)); // ends input exactly
|
||||
// raw literal termination edge cases (success)
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR")-", to_find)); // ends input
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR"h)-", to_find)); // ends input d_char
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR"()-", to_find)); // ends input paren
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR"h()-", to_find)); // ends input paren d_char
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR"())-", to_find)); // ends input close paren
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(abcR"()")-", to_find)); // ends input exactly
|
||||
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"()"abc)-", to_find));
|
||||
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"-(R"hello( hello" // abc )")-", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"(R"-( // abc )-")", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_c_comments(R"(R"-( // hello )-" // abc)", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"(R"-( /* abc */ )-")", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"(R"-()- /* abc */ )-")", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments(R"(qwer )", to_find));
|
||||
REQUIRE(contains_any_ignoring_c_comments("\"a\" \"g\" // er \n abc)", to_find));
|
||||
}
|
||||
|
||||
TEST_CASE ("contains_any_ignoring_hash_comments", "[strings]")
|
||||
{
|
||||
using vcpkg::Strings::contains_any_ignoring_hash_comments;
|
||||
vcpkg::StringView to_find[] = {"abc", "wer"};
|
||||
REQUIRE(contains_any_ignoring_hash_comments("abc", to_find));
|
||||
REQUIRE(contains_any_ignoring_hash_comments("wer", to_find));
|
||||
REQUIRE(contains_any_ignoring_hash_comments("wer # test", to_find));
|
||||
REQUIRE(contains_any_ignoring_hash_comments("\n wer # \n test", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_hash_comments("# wer", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_hash_comments("\n# wer", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_hash_comments("\n # wer\n", to_find));
|
||||
REQUIRE_FALSE(contains_any_ignoring_hash_comments("\n test # wer", to_find));
|
||||
}
|
||||
|
||||
TEST_CASE ("edit distance", "[strings]")
|
||||
{
|
||||
using vcpkg::Strings::byte_edit_distance;
|
||||
|
|
|
@ -659,13 +659,15 @@ namespace vcpkg
|
|||
REGISTER_MESSAGE(FeedbackAppreciated);
|
||||
REGISTER_MESSAGE(FetchingBaselineInfo);
|
||||
REGISTER_MESSAGE(FetchingRegistryInfo);
|
||||
REGISTER_MESSAGE(FishCompletion);
|
||||
REGISTER_MESSAGE(FloatingPointConstTooBig);
|
||||
REGISTER_MESSAGE(FileNotFound);
|
||||
REGISTER_MESSAGE(FileReadFailed);
|
||||
REGISTER_MESSAGE(FileSeekFailed);
|
||||
REGISTER_MESSAGE(FilesExported);
|
||||
REGISTER_MESSAGE(FileSystemOperationFailed);
|
||||
REGISTER_MESSAGE(FishCompletion);
|
||||
REGISTER_MESSAGE(FilesContainAbsolutePath1);
|
||||
REGISTER_MESSAGE(FilesContainAbsolutePath2);
|
||||
REGISTER_MESSAGE(FollowingPackagesMissingControl);
|
||||
REGISTER_MESSAGE(FollowingPackagesNotInstalled);
|
||||
REGISTER_MESSAGE(FollowingPackagesUpgraded);
|
||||
|
|
|
@ -382,6 +382,102 @@ Optional<StringView> Strings::find_at_most_one_enclosed(StringView input, String
|
|||
return result.front();
|
||||
}
|
||||
|
||||
bool vcpkg::Strings::contains_any_ignoring_c_comments(const std::string& source, View<StringView> to_find)
|
||||
{
|
||||
std::string::size_type offset = 0;
|
||||
std::string::size_type no_comment_offset = 0;
|
||||
while (offset != std::string::npos)
|
||||
{
|
||||
no_comment_offset = std::max(offset, no_comment_offset);
|
||||
auto start = source.find_first_of("/\"", no_comment_offset);
|
||||
if (start == std::string::npos || start + 1 == source.size() || no_comment_offset == std::string::npos)
|
||||
{
|
||||
return Strings::contains_any(StringView(source).substr(offset), to_find);
|
||||
}
|
||||
|
||||
if (source[start] == '/')
|
||||
{
|
||||
if (source[start + 1] == '/' || source[start + 1] == '*')
|
||||
{
|
||||
if (Strings::contains_any(StringView(source).substr(offset, start - offset), to_find))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (source[start + 1] == '/')
|
||||
{
|
||||
offset = source.find_first_of('\n', start);
|
||||
while (offset != std::string::npos && source[offset - 1] == '\\')
|
||||
offset = source.find_first_of('\n', offset + 1);
|
||||
if (offset != std::string::npos) ++offset;
|
||||
continue;
|
||||
}
|
||||
offset = source.find_first_of('/', start + 1);
|
||||
while (offset != std::string::npos && source[offset - 1] != '*')
|
||||
offset = source.find_first_of('/', offset + 1);
|
||||
if (offset != std::string::npos) ++offset;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (source[start] == '\"')
|
||||
{
|
||||
if (start > 0 && source[start - 1] == 'R') // raw string literals
|
||||
{
|
||||
auto end = source.find_first_of('(', start);
|
||||
if (end == std::string::npos)
|
||||
{
|
||||
// invalid c++, but allowed: auto test = 'R"'
|
||||
no_comment_offset = start + 1;
|
||||
continue;
|
||||
}
|
||||
auto d_char_sequence = ')' + source.substr(start + 1, end - start - 1);
|
||||
d_char_sequence.push_back('\"');
|
||||
no_comment_offset = source.find(d_char_sequence, end);
|
||||
if (no_comment_offset != std::string::npos) no_comment_offset += d_char_sequence.size();
|
||||
continue;
|
||||
}
|
||||
no_comment_offset = source.find_first_of('"', start + 1);
|
||||
while (no_comment_offset != std::string::npos && source[no_comment_offset - 1] == '\\')
|
||||
no_comment_offset = source.find_first_of('"', no_comment_offset + 1);
|
||||
if (no_comment_offset != std::string::npos) ++no_comment_offset;
|
||||
continue;
|
||||
}
|
||||
no_comment_offset = start + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Strings::contains_any_ignoring_hash_comments(StringView source, View<StringView> to_find)
|
||||
{
|
||||
auto first = source.data();
|
||||
auto block_start = first;
|
||||
const auto last = first + source.size();
|
||||
for (; first != last; ++first)
|
||||
{
|
||||
if (*first == '#')
|
||||
{
|
||||
if (Strings::contains_any(StringView{block_start, first}, to_find))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
first = std::find(first, last, '\n'); // skip comment
|
||||
if (first == last)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
block_start = first;
|
||||
}
|
||||
}
|
||||
|
||||
return Strings::contains_any(StringView{block_start, last}, to_find);
|
||||
}
|
||||
|
||||
bool Strings::contains_any(StringView source, View<StringView> to_find)
|
||||
{
|
||||
return Util::any_of(to_find, [=](StringView s) { return Strings::contains(source, s); });
|
||||
}
|
||||
|
||||
bool Strings::equals(StringView a, StringView b)
|
||||
{
|
||||
if (a.size() != b.size()) return false;
|
||||
|
|
|
@ -219,6 +219,7 @@ namespace vcpkg
|
|||
static const std::string NAME_SKIP_DUMPBIN_CHECKS = "PolicySkipDumpbinChecks";
|
||||
static const std::string NAME_SKIP_ARCHITECTURE_CHECK = "PolicySkipArchitectureCheck";
|
||||
static const std::string NAME_CMAKE_HELPER_PORT = "PolicyCmakeHelperPort";
|
||||
static const std::string NAME_SKIP_ABSOLUTE_PATHS_CHECK = "PolicySkipAbsolutePathsCheck";
|
||||
|
||||
static std::remove_const_t<decltype(ALL_POLICIES)> generate_all_policies()
|
||||
{
|
||||
|
@ -249,6 +250,7 @@ namespace vcpkg
|
|||
case BuildPolicy::SKIP_DUMPBIN_CHECKS: return NAME_SKIP_DUMPBIN_CHECKS;
|
||||
case BuildPolicy::SKIP_ARCHITECTURE_CHECK: return NAME_SKIP_ARCHITECTURE_CHECK;
|
||||
case BuildPolicy::CMAKE_HELPER_PORT: return NAME_CMAKE_HELPER_PORT;
|
||||
case BuildPolicy::SKIP_ABSOLUTE_PATHS_CHECK: return NAME_SKIP_ABSOLUTE_PATHS_CHECK;
|
||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +271,7 @@ namespace vcpkg
|
|||
case BuildPolicy::SKIP_DUMPBIN_CHECKS: return "VCPKG_POLICY_SKIP_DUMPBIN_CHECKS";
|
||||
case BuildPolicy::SKIP_ARCHITECTURE_CHECK: return "VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK";
|
||||
case BuildPolicy::CMAKE_HELPER_PORT: return "VCPKG_POLICY_CMAKE_HELPER_PORT";
|
||||
case BuildPolicy::SKIP_ABSOLUTE_PATHS_CHECK: return "VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK";
|
||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include <vcpkg/base/cofffilereader.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/base/messages.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/system.process.h>
|
||||
#include <vcpkg/base/util.h>
|
||||
|
||||
#include <vcpkg/build.h>
|
||||
#include <vcpkg/installedpaths.h>
|
||||
#include <vcpkg/packagespec.h>
|
||||
#include <vcpkg/postbuildlint.buildtype.h>
|
||||
#include <vcpkg/postbuildlint.h>
|
||||
|
@ -972,6 +974,98 @@ namespace vcpkg::PostBuildLint
|
|||
return LintStatus::SUCCESS;
|
||||
}
|
||||
|
||||
static bool file_contains_absolute_paths(const Filesystem& fs,
|
||||
const Path& file,
|
||||
const std::vector<StringView> stringview_paths)
|
||||
{
|
||||
const auto extension = file.extension();
|
||||
if (extension == ".h" || extension == ".hpp" || extension == ".hxx")
|
||||
{
|
||||
return Strings::contains_any_ignoring_c_comments(fs.read_contents(file, IgnoreErrors{}), stringview_paths);
|
||||
}
|
||||
|
||||
if (extension == ".cfg" || extension == ".ini" || file.filename() == "usage")
|
||||
{
|
||||
const auto contents = fs.read_contents(file, IgnoreErrors{});
|
||||
return Strings::contains_any(contents, stringview_paths);
|
||||
}
|
||||
|
||||
if (extension == ".py" || extension == ".sh" || extension == ".cmake" || extension == ".pc" ||
|
||||
extension == ".conf")
|
||||
{
|
||||
const auto contents = fs.read_contents(file, IgnoreErrors{});
|
||||
return Strings::contains_any_ignoring_hash_comments(contents, stringview_paths);
|
||||
}
|
||||
|
||||
if (extension.empty())
|
||||
{
|
||||
std::error_code ec;
|
||||
ReadFilePointer read_file(file, ec);
|
||||
if (ec) return false;
|
||||
char buffer[5];
|
||||
if (read_file.read(buffer, 1, sizeof(buffer)) < sizeof(buffer)) return false;
|
||||
if (Strings::starts_with(StringView(buffer, sizeof(buffer)), "#!") ||
|
||||
Strings::starts_with(StringView(buffer, sizeof(buffer)), "\xEF\xBB\xBF#!") /* ignore byte-order mark */)
|
||||
{
|
||||
const auto contents = fs.read_contents(file, IgnoreErrors{});
|
||||
return Strings::contains_any_ignoring_hash_comments(contents, stringview_paths);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static LintStatus check_no_absolute_paths_in(const Filesystem& fs, const Path& dir, Span<Path> absolute_paths)
|
||||
{
|
||||
std::vector<std::string> string_paths;
|
||||
for (const auto& path : absolute_paths)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// As supplied, all /s, and all \s
|
||||
string_paths.push_back(path.native());
|
||||
auto path_preferred = path;
|
||||
path_preferred.make_preferred();
|
||||
string_paths.push_back(path_preferred.native());
|
||||
string_paths.push_back(path.generic_u8string());
|
||||
#else
|
||||
string_paths.push_back(path.native());
|
||||
#endif
|
||||
}
|
||||
|
||||
Util::sort_unique_erase(string_paths);
|
||||
|
||||
const auto stringview_paths = Util::fmap(string_paths, [](std::string& s) { return StringView(s); });
|
||||
|
||||
std::vector<Path> failing_files;
|
||||
for (auto&& file : fs.get_regular_files_recursive(dir, IgnoreErrors{}))
|
||||
{
|
||||
if (file_contains_absolute_paths(fs, file, stringview_paths))
|
||||
{
|
||||
failing_files.push_back(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (failing_files.empty())
|
||||
{
|
||||
return LintStatus::SUCCESS;
|
||||
}
|
||||
|
||||
auto error_message = msg::format(msgFilesContainAbsolutePath1);
|
||||
for (auto&& absolute_path : absolute_paths)
|
||||
{
|
||||
error_message.append_raw('\n').append_indent().append_raw(absolute_path);
|
||||
}
|
||||
|
||||
error_message.append_raw('\n').append(msgFilesContainAbsolutePath2);
|
||||
for (auto&& failure : failing_files)
|
||||
{
|
||||
error_message.append_raw('\n').append_indent().append_raw(failure);
|
||||
}
|
||||
|
||||
msg::println_warning(error_message);
|
||||
return LintStatus::PROBLEM_DETECTED;
|
||||
}
|
||||
|
||||
static void operator+=(size_t& left, const LintStatus& right) { left += static_cast<size_t>(right); }
|
||||
|
||||
static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec,
|
||||
|
@ -1100,6 +1194,11 @@ namespace vcpkg::PostBuildLint
|
|||
error_count += check_no_files_in_dir(fs, package_dir);
|
||||
error_count += check_no_files_in_dir(fs, package_dir / "debug");
|
||||
error_count += check_pkgconfig_dir_only_in_lib_dir(fs, package_dir);
|
||||
if (!build_info.policies.is_enabled(BuildPolicy::SKIP_ABSOLUTE_PATHS_CHECK))
|
||||
{
|
||||
error_count += check_no_absolute_paths_in(
|
||||
fs, package_dir, std::vector<Path>{package_dir, paths.installed().root(), paths.build_dir(spec)});
|
||||
}
|
||||
|
||||
return error_count;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче