• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PredatorCZ / RevilLib / 152

28 Sep 2024 09:20PM UTC coverage: 11.245% (-0.001%) from 11.246%
152

push

github

PredatorCZ
make_arc add sloppy hash detection

757 of 6732 relevant lines covered (11.24%)

6715.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.64
/src/hashreg.cpp
1
#include "revil/hashreg.hpp"
2
#include "database.hpp"
3
#include "spike/reflect/detail/reflector_class.hpp"
4
#include "spike/reflect/detail/reflector_enum.hpp"
5
#include <stdexcept>
6

7
extern "C" const revil::Header REDB;
8

9
using namespace revil;
10

11
REFLECT(ENUMERATION(Platform), ENUM_MEMBER(Auto), ENUM_MEMBER(Win32),
1✔
12
        ENUM_MEMBER(N3DS), ENUM_MEMBER(PS3), ENUM_MEMBER(X360),
13
        ENUM_MEMBER(CAFE), ENUM_MEMBER(NSW), ENUM_MEMBER(PS4),
14
        ENUM_MEMBER(Android), ENUM_MEMBER(IOS), ENUM_MEMBER(Win64));
15

16
namespace revil {
17

18
std::string_view GetExtension(uint32 hash, std::string_view title,
×
19
                              Platform platform_) {
20
  const uint8 platform = uint8(platform_) & PLATFORM_MASK;
×
21

22
  if (!title.empty()) {
×
23
    auto oKey = LowerBound(title, REDB.titles);
×
24

25
    if (oKey != REDB.titles.end() && std::string_view(oKey->name) == title) {
×
26
      for (auto &fx : oKey->data->fixups) {
×
27
        if (fx.platform == platform) {
×
28
          const ResourceClass *fClasses = fx.classes.operator->();
29

30
          for (size_t i = 0; i < fx.numItems; i++) {
×
31
            if (fClasses[i].hash == hash) {
×
32
              return fClasses[i].extension;
33
            }
34
          }
35
        }
36
      }
37
    }
38
  }
39

40
  auto foundClass = LowerBound(hash, REDB.resourceClasses[platform]);
×
41

42
  if (foundClass != REDB.resourceClasses[platform].end() &&
×
43
      foundClass->hash == hash) {
×
44
    return foundClass->extension;
45
  }
46

47
  foundClass = LowerBound(hash, REDB.resourceClasses[0]);
48

49
  if (foundClass != REDB.resourceClasses[0].end() && foundClass->hash == hash) {
×
50
    return foundClass->extension;
51
  }
52

53
  return {};
×
54
}
55

56
std::string_view GetClassName(uint32 hash) {
×
57
  auto foundResClass = LowerBound(hash, REDB.resourceClasses[0]);
58

59
  if (foundResClass != REDB.resourceClasses[0].end() &&
×
60
      foundResClass->hash == hash) {
×
61
    return foundResClass->name;
62
  }
63

64
  auto foundClass = LowerBound(hash, REDB.classes);
65

66
  if (foundClass != REDB.classes.end() && foundClass->hash == hash) {
×
67
    return foundClass->name;
68
  }
69

70
  return {};
×
71
}
72

73
void GetTitles(TitleCallback cb) {
×
74
  for (auto &p : REDB.titles) {
×
75
    cb(p.name);
×
76
  }
77
}
78

79
/* Lookup order:
80
  extCommon map
81
  if platform not auto lookup class from ext<platform> map
82
*/
83
std::span<const uint32> GetHash(std::string_view extension,
×
84
                                std::string_view title, Platform platform) {
85
  auto supp = GetTitleSupport(title, platform);
×
86

87
  auto hashes =
88
      ClassesFromExtension(REDB, extension, supp->arc.flags & DbArc_Version1);
×
89

90
  if (hashes.size() > 0) {
×
91
    return hashes;
×
92
  }
93

94
  // for backward compatibility, some extensions might have numerical (hashed)
95
  // extension (not found in main registry) if the extension has been added
96
  // later, just find it by hash and verify it in inverted registry
97
  auto cvted = strtoul(extension.data(), nullptr, 16);
×
98

99
  if (cvted < 0x10000) {
×
100
    return {};
×
101
  }
102

103
  auto extTranslated = GetExtension(cvted, title, platform);
×
104

105
  if (extTranslated.empty()) {
×
106
    return {};
×
107
  }
108

109
  return GetHash(extTranslated, title, platform);
×
110
}
111

112
Platforms GetPlatformSupport(std::string_view title) {
×
113
  auto found = LowerBound(title, REDB.titles);
×
114

115
  if (found == REDB.titles.end() || found->name != title) {
×
116
    throw std::runtime_error("Coundn't find title.");
×
117
  }
118

119
  static const auto refl = GetReflectedEnum<Platform>();
120

121
  Platforms flags;
×
122

123
  for (uint32 i = 1; i < NUM_PLATFORMS; i++) {
×
124
    if (auto plat = found->data->support.operator->()[i - 1].operator->(); plat) {
×
125
      flags.emplace_back(Platform(refl->values[i]));
×
126
    }
127
  }
128

129
  return flags;
×
130
}
131

132
const TitleSupport *GetTitleSupport(std::string_view title, Platform platform) {
×
133
  auto found = LowerBound(title, REDB.titles);
×
134

135
  if (found == REDB.titles.end() || found->name != title) {
×
136
    throw std::runtime_error("Coundn't find title.");
×
137
  }
138

139
  if (platform == Platform::Auto) {
×
140
    platform = Platform::Win32;
141
  }
142

143
  auto platforms = found->data->support.operator->();
144

145
  auto foundSec = platforms[(uint8(platform) & PLATFORM_MASK) - 1].operator->();
×
146

147
  if (!foundSec && platform != Platform::Win32) {
×
148
    foundSec =
149
        platforms[(uint8(Platform::Win32) & PLATFORM_MASK) - 1].operator->();
150
  }
151

152
  if (!foundSec) {
×
153
    static const auto refl = GetReflectedEnum<Platform>();
154
    const bool inputPlatformBE = IsPlatformBigEndian(platform);
155

156
    for (uint32 i = 1; i < refl->numMembers; i++) {
×
157
      if (IsPlatformBigEndian(Platform(refl->values[i])) == inputPlatformBE &&
×
158
          platforms[i - 1].varPtr) {
×
159
        if (foundSec) {
×
160
          throw std::runtime_error(
×
161
              "Ambiguous title support found from fallback.");
×
162
        }
163

164
        foundSec = platforms[i - 1].operator->();
165
      }
166
    }
167
  }
168

169
  if (!foundSec) {
×
170
    throw std::runtime_error("Title support is null.");
×
171
  }
172

173
  return foundSec;
×
174
}
175

176
} // namespace revil
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc