Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash while parsing malformed manifest files and make errors prettier #1219

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/vcpkg/base/jsonreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,11 @@ namespace vcpkg::Json
virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) const override;
static const PackageNameDeserializer instance;
};

struct FeatureNameDeserializer final : Json::IDeserializer<std::string>
{
virtual LocalizedString type_name() const override;
virtual Optional<std::string> visit_string(Json::Reader&, StringView sv) const override;
static const FeatureNameDeserializer instance;
};
}
58 changes: 44 additions & 14 deletions include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
DECLARE_MESSAGE(ABaseline, (), "", "a baseline")
DECLARE_MESSAGE(ABaselineObject, (), "", "a baseline object")
DECLARE_MESSAGE(ADefaultFeature, (), "", "a default feature")
DECLARE_MESSAGE(ABoolean, (), "", "a boolean")
DECLARE_MESSAGE(ABuiltinRegistry, (), "", "a builtin registry")
DECLARE_MESSAGE(AConfigurationObject, (), "", "a configuration object")
DECLARE_MESSAGE(ADependency, (), "", "a dependency")
DECLARE_MESSAGE(ADependencyFeature, (), "", "a feature in a dependency")
DECLARE_MESSAGE(ADependencyFeature, (), "", "a feature of a dependency")
DECLARE_MESSAGE(ADemandObject,
(),
"'demands' are a concept in the schema of a JSON file the user can edit",
Expand Down Expand Up @@ -94,6 +95,7 @@ DECLARE_MESSAGE(AddVersionVersionAlreadyInFile, (msg::version, msg::path), "", "
DECLARE_MESSAGE(AddVersionVersionIs, (msg::version), "", "version: {version}")
DECLARE_MESSAGE(ADictionaryOfContacts, (), "", "a dictionary of contacts")
DECLARE_MESSAGE(AFeature, (), "", "a feature")
DECLARE_MESSAGE(AFeatureName, (), "", "a feature name")
DECLARE_MESSAGE(AFilesystemRegistry, (), "", "a filesystem registry")
DECLARE_MESSAGE(AGitObjectSha, (), "", "a git object SHA")
DECLARE_MESSAGE(AGitReference, (), "", "a git reference (for example, a branch)")
Expand Down Expand Up @@ -123,6 +125,7 @@ DECLARE_MESSAGE(AmbiguousConfigDeleteConfigFile,
"configuration file {path}")
DECLARE_MESSAGE(AnArtifactsGitRegistryUrl, (), "", "an artifacts git registry URL")
DECLARE_MESSAGE(AnArtifactsRegistry, (), "", "an artifacts registry")
DECLARE_MESSAGE(AnArrayOfDefaultFeatures, (), "", "an array of default features")
DECLARE_MESSAGE(AnArrayOfDependencies, (), "", "an array of dependencies")
DECLARE_MESSAGE(AnArrayOfDependencyOverrides, (), "", "an array of dependency overrides")
DECLARE_MESSAGE(AnArrayOfFeatures, (), "", "an array of features")
Expand Down Expand Up @@ -980,6 +983,16 @@ DECLARE_MESSAGE(DefaultBinaryCacheRequiresDirectory,
(msg::path),
"",
"Environment variable VCPKG_DEFAULT_BINARY_CACHE must be a directory (was: {path})")
DECLARE_MESSAGE(DefaultFeatureCore,
(),
"The word \"core\" is an on-disk name that must not be localized.",
"the feature \"core\" turns off default features and thus can't be in the default features list")
DECLARE_MESSAGE(
DefaultFeatureDefault,
(),
"The word \"default\" is an on-disk name that must not be localized.",
"the feature \"default\" refers to the set of default features and thus can't be in the default features list")
DECLARE_MESSAGE(DefaultFeatureIdentifier, (), "", "the names of default features must be identifiers")
DECLARE_MESSAGE(DefaultFlag, (msg::option), "", "Defaulting to --{option} being on.")
DECLARE_MESSAGE(DefaultRegistryIsArtifact, (), "", "The default registry cannot be an artifact registry.")
DECLARE_MESSAGE(
Expand All @@ -994,6 +1007,20 @@ DECLARE_MESSAGE(DeleteVcpkgConfigFromManifest,
(msg::path),
"",
"-- Or remove \"vcpkg-configuration\" from the manifest file {path}.")
DECLARE_MESSAGE(
DependencyFeatureCore,
(),
"The word \"core\" is an on-disk name that must not be localized. The \"default-features\" part is JSON "
"syntax that must be copied verbatim into the user's file.",
"the feature \"core\" cannot be in a dependency's feature list. To turn off default features, add "
"\"default-features\": false instead.")
DECLARE_MESSAGE(
DependencyFeatureDefault,
(),
"The word \"default\" is an on-disk name that must not be localized. The \"default-features\" part is JSON "
"syntax that must be copied verbatim into the user's file.",
"the feature \"default\" cannot be in a dependency's feature list. To turn on default features, add "
"\"default-features\": true instead.")
DECLARE_MESSAGE(DependencyGraphCalculation, (), "", "Dependency graph submission enabled.")
DECLARE_MESSAGE(DependencyGraphFailure, (), "", "Dependency graph submission failed.")
DECLARE_MESSAGE(DependencyGraphSuccess, (), "", "Dependency graph submission successful.")
Expand Down Expand Up @@ -1903,10 +1930,6 @@ DECLARE_MESSAGE(InvalidCommentStyle,
"comments.")
DECLARE_MESSAGE(InvalidCommitId, (msg::commit_sha), "", "Invalid commit id: {commit_sha}")
DECLARE_MESSAGE(InvalidDefaultFeatureName, (), "", "'default' is a reserved feature name")
DECLARE_MESSAGE(InvalidDependency,
(),
"",
"dependencies must be lowercase alphanumeric+hyphens, and not one of the reserved names")
DECLARE_MESSAGE(InvalidFeature,
(),
"",
Expand Down Expand Up @@ -2269,22 +2292,29 @@ DECLARE_MESSAGE(ParseControlErrorInfoWhileLoading,
"Error messages are is printed after this.",
"while loading {path}:")
DECLARE_MESSAGE(ParseControlErrorInfoWrongTypeFields, (), "", "The following fields had the wrong types:")
DECLARE_MESSAGE(
ParseFeatureNameError,
(msg::package_name, msg::url),
"",
"\"{package_name}\" is not a valid feature name. "
"Feature names must be lowercase alphanumeric+hypens and not reserved (see {url} for more information).")
DECLARE_MESSAGE(ParseIdentifierError,
(msg::value, msg::url),
"{value} is a lowercase identifier like 'boost'",
"\"{value}\" is not a valid identifier. "
"Identifiers must be lowercase alphanumeric+hypens and not reserved (see {url} for more information)")
DECLARE_MESSAGE(ParsePackageNameError,
(msg::package_name, msg::url),
"",
"\"{package_name}\" is not a valid package name. "
"Package names must be lowercase alphanumeric+hypens and not reserved (see {url} for more information)")
"Identifiers must be lowercase alphanumeric+hypens and not reserved (see {url} for more information).")
DECLARE_MESSAGE(
ParsePackageNameError,
(msg::package_name, msg::url),
"",
"\"{package_name}\" is not a valid package name. "
"Package names must be lowercase alphanumeric+hypens and not reserved (see {url} for more information).")
DECLARE_MESSAGE(ParsePackagePatternError,
(msg::package_name, msg::url),
"",
"\"{package_name}\" is not a valid package pattern. "
"Package patterns must use only one wildcard character (*) and it must be the last character in "
"the pattern (see {url} for more information)")
"the pattern (see {url} for more information).")
DECLARE_MESSAGE(PathMustBeAbsolute,
(msg::path),
"",
Expand All @@ -2296,11 +2326,11 @@ DECLARE_MESSAGE(PECoffHeaderTooShort,
DECLARE_MESSAGE(PEConfigCrossesSectionBoundary,
(msg::path),
"Portable executable is a term-of-art, see https://learn.microsoft.com/windows/win32/debug/pe-format",
"While parsing Portable Executable {path}, image config directory crosses a secion boundary.")
"While parsing Portable Executable {path}, image config directory crosses a section boundary.")
DECLARE_MESSAGE(PEImportCrossesSectionBoundary,
(msg::path),
"Portable executable is a term-of-art, see https://learn.microsoft.com/windows/win32/debug/pe-format",
"While parsing Portable Executable {path}, import table crosses a secion boundary.")
"While parsing Portable Executable {path}, import table crosses a section boundary.")
DECLARE_MESSAGE(PEPlusTagInvalid,
(msg::path),
"Portable executable is a term-of-art, see https://learn.microsoft.com/windows/win32/debug/pe-format",
Expand Down
29 changes: 22 additions & 7 deletions include/vcpkg/base/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,42 @@ namespace vcpkg
static LocalizedString from_raw(std::basic_string<T>&& s) noexcept;
static LocalizedString from_raw(StringView s);

LocalizedString& append_raw(char c);
LocalizedString& append_raw(StringView s);
LocalizedString& append_raw(char c) &;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just stole this out of #1210 :)

LocalizedString&& append_raw(char c) &&;
LocalizedString& append_raw(StringView s) &;
LocalizedString&& append_raw(StringView s) &&;
template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
LocalizedString& append_raw(const T& s)
LocalizedString& append_raw(const T& s) &
{
s.to_string(m_data);
return *this;
}
LocalizedString& append(const LocalizedString& s);
template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
LocalizedString&& append_raw(const T& s) &&
{
return std::move(append_raw(s));
}
LocalizedString& append(const LocalizedString& s) &;
LocalizedString&& append(const LocalizedString& s) &&;
template<VCPKG_DECL_MSG_TEMPLATE>
LocalizedString& append(VCPKG_DECL_MSG_ARGS)
LocalizedString& append(VCPKG_DECL_MSG_ARGS) &
{
msg::format_to(*this, VCPKG_EXPAND_MSG_ARGS);
return *this;
}
LocalizedString& append_indent(size_t indent = 1);
template<VCPKG_DECL_MSG_TEMPLATE>
LocalizedString&& append(VCPKG_DECL_MSG_ARGS) &&
{
return std::move(append(VCPKG_EXPAND_MSG_ARGS));
}
LocalizedString& append_indent(size_t indent = 1) &;
LocalizedString&& append_indent(size_t indent = 1) &&;

// 0 items - Does nothing
// 1 item - .append_raw(' ').append(item)
// 2+ items - foreach: .append_raw('\n').append_indent(indent).append(item)
LocalizedString& append_floating_list(int indent, View<LocalizedString> items);
LocalizedString& append_floating_list(int indent, View<LocalizedString> items) &;
LocalizedString&& append_floating_list(int indent, View<LocalizedString> items) &&;
friend bool operator==(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
friend bool operator!=(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
friend bool operator<(const LocalizedString& lhs, const LocalizedString& rhs) noexcept;
Expand Down
5 changes: 1 addition & 4 deletions include/vcpkg/platform-expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ namespace vcpkg::PlatformExpression
static Expr And(std::vector<Expr>&& exprs);
static Expr Or(std::vector<Expr>&& exprs);

// The empty expression is always true
static Expr Empty() { return Expr(); }

// since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file
Expr();
Expr(); // always true
Expr(const Expr&);
Expr(Expr&&);
Expr& operator=(const Expr& e);
Expand Down
10 changes: 1 addition & 9 deletions include/vcpkg/sourceparagraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,7 @@ namespace vcpkg
{
std::string name;
PlatformExpression::Expr platform;
DependencyRequestedFeature(std::string name)
: DependencyRequestedFeature(std::move(name), PlatformExpression::Expr::Empty())
{
}
DependencyRequestedFeature(std::string name, PlatformExpression::Expr platform)
: name(std::move(name)), platform(std::move(platform))
{
Checks::check_exit(VCPKG_LINE_INFO, !this->name.empty() && this->name != "core" && this->name != "default");
}

friend bool operator==(const DependencyRequestedFeature& lhs, const DependencyRequestedFeature& rhs);
friend bool operator!=(const DependencyRequestedFeature& lhs, const DependencyRequestedFeature& rhs);
};
Expand Down
Loading