Coverage Report

Created: 2026-09-28 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/validator/component_name.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
#pragma once
4
5
#include "common/errcode.h"
6
#include "common/expected.h"
7
8
#include <cstdint>
9
#include <string_view>
10
11
namespace WasmEdge {
12
namespace Validator {
13
namespace Component {
14
15
/// A parsed extern name of a component import or export.
16
class ExternName {
17
public:
18
  enum class Kind : uint8_t {
19
    Invalid,
20
    Constructor,
21
    Method,
22
    Static,
23
    InterfaceType,
24
    Label,
25
    LockedDep,
26
    UnlockedDep,
27
    Url,
28
    Integrity
29
  };
30
31
  /// Fragments as views into the input; the kind decides which are set.
32
  struct Detail {
33
    std::string_view Resource;     // Constructor, Method, Static
34
    std::string_view Method;       // Method, Static
35
    std::string_view Namespace;    // InterfaceType, LockedDep, UnlockedDep
36
    std::string_view Package;      // InterfaceType, LockedDep, UnlockedDep
37
    std::string_view Interface;    // InterfaceType
38
    std::string_view Version;      // InterfaceType, LockedDep
39
    std::string_view VersionRange; // UnlockedDep
40
    std::string_view Url;          // Url
41
    std::string_view Integrity;    // LockedDep, Url, Integrity
42
  };
43
44
  /// Returns true if Input is a label: <first-fragment> ( '-' <fragment> )*.
45
  static bool isKebabString(std::string_view Input) noexcept;
46
47
  /// Parses Name into this object, which stays Invalid on failure.
48
  Expect<void> parse(std::string_view Name) noexcept;
49
50
43.4k
  Kind getKind() const noexcept { return NameKind; }
51
22.0k
  std::string_view getOriginalName() const noexcept { return OriName; }
52
  /// The name without its annotation tag; empty when the name carries none.
53
49
  std::string_view getNoTagName() const noexcept { return NoTagName; }
54
4
  const Detail &getDetail() const noexcept { return NameDetail; }
55
  /// The `versionsuffix` attribute: canonversion plus Suffix must be a semver.
56
  Expect<void> checkVersionSuffix(std::string_view Suffix) const noexcept;
57
58
private:
59
  // Cursor primitives, all consuming from Rest.
60
  bool tryRead(std::string_view Prefix) noexcept;
61
  bool readUntil(char Delim, std::string_view &Output) noexcept;
62
  std::string_view readLabelChars() noexcept;
63
64
  // One member per production, consuming the rest after its leading tag.
65
  Expect<void> parsePlainName() noexcept;
66
  Expect<void> parseUnlockedDep() noexcept;
67
  Expect<void> parseLockedDep() noexcept;
68
  Expect<void> parseUrlName() noexcept;
69
  Expect<void> parseHashName() noexcept;
70
  Expect<void> parseInterfaceName() noexcept;
71
  Expect<void> parsePkgPath(std::string_view StopChars) noexcept;
72
  Expect<std::string_view> parseIntegrityBody() noexcept;
73
  Expect<std::string_view> parseIntegritySuffix() noexcept;
74
75
  // Grammar checks over a substring; the semver scanners stay unlogged.
76
  Expect<void> checkWordsLabel(std::string_view Label,
77
                               std::string_view What) const noexcept;
78
  Expect<void> checkVersionRange(std::string_view Body) const noexcept;
79
  bool isCanonVersion(std::string_view V) const noexcept;
80
  Expect<void> scanSemver(std::string_view V) const noexcept;
81
  Expect<void> scanSemverIdentifiers(std::string_view Idents,
82
                                     bool CheckLeadingZeros) const noexcept;
83
  Expect<void> checkIntegrityMetadata(std::string_view Input) const noexcept;
84
85
  std::string_view OriName;
86
  std::string_view NoTagName;
87
  std::string_view Rest;
88
  Kind NameKind = Kind::Invalid;
89
  Detail NameDetail;
90
};
91
92
} // namespace Component
93
} // namespace Validator
94
} // namespace WasmEdge