#include <iostream>
using namespace std;
/**
* @brief Defines a passkey for type T.
*/
template <typename T>
class PassKey
{
private:
// befriend T so that only T can create a PassKey object
friend T;
// make default constructor private so that only T can access it
PassKey() {}
// noncopyable, non-assignable so that key can not be re-used
PassKey(const PassKey&) = delete;
PassKey& operator=(const PassKey&) = delete;
};
struct B;
struct A
{
void doSomething(PassKey<B>) const
{}
};
struct B
{
void callDoSomething(const A& a) const
{
a.doSomething({});
}
};
int main() {
A a;
B b;
b.callDoSomething(a);
int FraudKey=0;
a.doSomething(reinterpret_cast<PassKey<B>&>(FraudKey));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLyoqCiogQGJyaWVmIERlZmluZXMgYSBwYXNza2V5IGZvciB0eXBlIFQuCiovCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyBQYXNzS2V5CnsKcHJpdmF0ZToKICAgIC8vIGJlZnJpZW5kIFQgc28gdGhhdCBvbmx5IFQgY2FuIGNyZWF0ZSBhIFBhc3NLZXkgb2JqZWN0CiAgICBmcmllbmQgVDsKCiAgICAvLyBtYWtlIGRlZmF1bHQgY29uc3RydWN0b3IgcHJpdmF0ZSBzbyB0aGF0IG9ubHkgVCBjYW4gYWNjZXNzIGl0CiAgICBQYXNzS2V5KCkge30KCiAgICAvLyBub25jb3B5YWJsZSwgbm9uLWFzc2lnbmFibGUgc28gdGhhdCBrZXkgY2FuIG5vdCBiZSByZS11c2VkCiAgICBQYXNzS2V5KGNvbnN0IFBhc3NLZXkmKSA9IGRlbGV0ZTsKICAgIFBhc3NLZXkmIG9wZXJhdG9yPShjb25zdCBQYXNzS2V5JikgPSBkZWxldGU7Cn07CgpzdHJ1Y3QgQjsKCnN0cnVjdCBBCnsKCXZvaWQgZG9Tb21ldGhpbmcoUGFzc0tleTxCPikgY29uc3QKCXt9Cn07CgpzdHJ1Y3QgQgp7Cgl2b2lkIGNhbGxEb1NvbWV0aGluZyhjb25zdCBBJiBhKSBjb25zdAoJewoJCWEuZG9Tb21ldGhpbmcoe30pOwoJfQp9OwoKCgppbnQgbWFpbigpIHsKCUEgYTsKCUIgYjsKCWIuY2FsbERvU29tZXRoaW5nKGEpOwoJaW50IEZyYXVkS2V5PTA7CglhLmRvU29tZXRoaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8UGFzc0tleTxCPiY+KEZyYXVkS2V5KSk7CglyZXR1cm4gMDsKfQ==