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

Negative test cases for patricia_set<>::prefix_match()? #1

Open
amdei opened this issue Mar 15, 2024 · 3 comments
Open

Negative test cases for patricia_set<>::prefix_match()? #1

amdei opened this issue Mar 15, 2024 · 3 comments

Comments

@amdei
Copy link

amdei commented Mar 15, 2024

If in tests/ip_prefix.cxx I add db.lookup("ff01:db8:1000::43")
it returns ::1/128
what not seem to be correct.

E.g. db.lookup() always returns "something", even though it shouldn't.

Would it be possible to provide example of how to check, if some IP address is NOT in IP prefix database?
May be something like contains() method in class prefix_set?

@mavam
Copy link

mavam commented Mar 20, 2024

I can reproduce this issue as well.

@mavam
Copy link

mavam commented Mar 20, 2024

Here's minimal example to to reproduce:

namespace {

struct sliced_byte {
  std::byte byte{0xFF};
  size_t bits{8};
};

auto slice = [](auto byte, size_t bits) {
  return sliced_byte{static_cast<std::byte>(byte), bits};
};

struct sliced_byte_keymaker {
  template <class U>
  struct rebind {
    using other = sliced_byte_keymaker;
  };

  auto operator()(sliced_byte x) -> sk::patricia_key {
    return {std::span<const std::byte>{&x.byte, 1}, x.bits};
  }
};

} // namespace

TEST(ensure no false positives during prefix match) {
  auto xs = sk::patricia_map<sliced_byte, int8_t, sliced_byte_keymaker>{};
  xs[slice(0xff, 4)] = 42;
  CHECK_EQUAL(xs.prefix_match(slice(0xff, 1)), xs.end());
  CHECK_EQUAL(xs.prefix_match(slice(0xff, 2)), xs.end());
  CHECK_EQUAL(xs.prefix_match(slice(0xff, 3)), xs.end());
  CHECK_NOT_EQUAL(xs.prefix_match(slice(0xff, 4)), xs.end()); // fails: exact match
  CHECK_NOT_EQUAL(xs.prefix_match(slice(0xff, 5)), xs.end()); // fails: prefix match
  CHECK_NOT_EQUAL(xs.prefix_match(slice(0xff, 6)), xs.end()); // fails: prefix match
  CHECK_NOT_EQUAL(xs.prefix_match(slice(0xff, 7)), xs.end()); // fails: prefix match
  CHECK_NOT_EQUAL(xs.prefix_match(slice(0xff, 8)), xs.end()); // fails: prefix match
}

@mavam
Copy link

mavam commented Mar 20, 2024

I'm seeing some non-deterministic behavior. When I instrument the library with extra logging, all of a sudden these tests pass.

I have a hunch: the node has a patricia_key as member function, which is effectively a span plus bit length. If the original object the span points to no longer exists, wouldn't the accessed memory be invalid? Or is there some copying taking place?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants