socket_row_relocation_test.cpp 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <cassert>
  2. #include <cstdlib>
  3. #include <fstream>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include "../Sunrise/src/client/hooks/network/investment/socket_row_relocation.h"
  8. namespace r = sunrise::client::hooks::network::investment::relocation;
  9. int main(int argc, char** argv) {
  10. assert(argc == 2);
  11. std::array<r::Row, 71> original{};
  12. std::ifstream input(argv[1], std::ios::binary);
  13. std::string hex, line;
  14. while (input >> line)
  15. hex += line;
  16. assert(hex.size() == sizeof(original) * 2);
  17. auto* bytes = reinterpret_cast<unsigned char*>(original.data());
  18. for (std::size_t i = 0; i < sizeof(original); ++i) {
  19. bytes[i] = static_cast<unsigned char>(std::stoul(hex.substr(i * 2, 2), nullptr, 16));
  20. }
  21. auto target = [](const r::Row& row) {
  22. auto id = r::get<std::uint32_t>(row.bytes.data());
  23. return id == 492 || id == 494 || id == 495 || id == 496;
  24. };
  25. std::vector<r::Row> general, legs, moved;
  26. for (std::size_t i = 0; i < original.size(); ++i) {
  27. assert(r::valid(original[i]));
  28. if (i < 19)
  29. (target(original[i]) ? moved : general).push_back(original[i]);
  30. else
  31. legs.push_back(original[i]);
  32. }
  33. legs.insert(legs.begin() + 1, moved.begin(), moved.end());
  34. assert(general.size() == 15 && legs.size() == 56 && moved.size() == 4);
  35. assert(legs[0].bytes == original[19].bytes);
  36. for (std::size_t i = 1; i < 5; ++i)
  37. assert(target(legs[i]));
  38. for (std::size_t i = 5; i < legs.size(); ++i) {
  39. assert(legs[i].bytes == original[19 + i - 4].bytes);
  40. }
  41. unsigned conditions = 0;
  42. for (auto& rows : {general, legs}) {
  43. std::vector<std::byte> blob(r::capacity(rows.size()));
  44. assert(r::build(rows, blob) && r::verify(rows, blob));
  45. auto relocated = blob;
  46. assert(r::verify(rows, relocated)); // actual allocation address changes
  47. for (std::size_t i = 0; i < rows.size(); ++i) {
  48. if (r::get<std::uint64_t>(rows[i].bytes.data() + 8) == 0) continue;
  49. ++conditions;
  50. auto shallow = blob;
  51. std::memcpy(shallow.data() + 24 + i * 32 + 16, rows[i].bytes.data() + 16, 8);
  52. assert(!r::verify(rows, shallow));
  53. auto corrupt = blob;
  54. auto at = 24 + i * 32;
  55. auto header = at + 16 + r::get<std::int64_t>(corrupt.data() + at + 16);
  56. corrupt[header + 20] ^= std::byte{1};
  57. assert(!r::verify(rows, corrupt));
  58. }
  59. assert(!r::build(rows, std::span(blob.data(), 32)));
  60. auto invalid = rows;
  61. r::put(invalid[0].bytes.data() + 8, std::uint64_t{2});
  62. assert(!r::build(invalid, blob));
  63. invalid = rows;
  64. invalid[1] = invalid[0];
  65. assert(!r::build(invalid, blob));
  66. assert(!r::verify(rows, std::span<const std::byte>(blob.data() + 1, blob.size() - 1)));
  67. }
  68. assert(conditions == 57);
  69. // Regression: substituting Enhanced's condition must fail comparison to target originals.
  70. auto wrong = legs;
  71. for (std::size_t i = 1; i < 5; ++i)
  72. wrong[i].condition = original[20].condition;
  73. std::vector<std::byte> blob(r::capacity(56));
  74. assert(r::build(wrong, blob));
  75. assert(!r::verify(legs, blob));
  76. std::cout << "PASS: 71 rows, 57 conditions; relocation, shallow-copy rejection, own-condition "
  77. "identity, malformed shape, duplicate, capacity and alignment checks\n";
  78. }