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:

  1. All nodes are heap allocated (or next is nullptr)
  2. No sharing between separated lists
  3. 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.