Representation Exposure
Representation exposure is unintentional external access to the underlying representation of an object.
The examples showcased in Forgery and Tampering arise from a common problem: Representation exposure.
Every ADT has a representation in memory somehow. For example, linked lists are implemented via a series of nodes
If the client gains access to the memory, we call that Representation Exposure. Client can use this knowledge to do things we don’t expect.
We have expectations / rules for all linked lists:
- All nodes are heap allocated (or next is nullptr)
- No sharing between separated lists
- No cycles in our list
Clients should not need to uphold these invariants, its our responsibility.
Solution: Encapsulation. We provide public methods for the client to interact with our List.
// list.h
class List {
struct Node; // forward declaration of a private, nested, class.
Node* head = nullptr; // front of our list
public:
List(); // creates empty list;
~List();
void push(const string& s);
string& ith(int i);
}
// list.cc
struct List::Node {
// same as before
...
}
List::List() {}
List::~List() { delete head; }
void List::push(const string& s) {
head = new Node {s, head};
}
string& List::ith(int i) {
Node* cur = head;
for (int x=0;x<i;++x) {
cur = cur->next;
return cur->data;
}
}
This solves our representation exposure problem. Client has no knowledge of Nodes, no access to internal memory representation, no tampering / forgery allowed.