The problem is in GuardedMemory::print_on where the incoming data from the programmer may be invalid and so invalidates the guard, but the code treats that data as if it could be correct and then dereferences the user_data. We have in the code:
u_char udata = *get_user_ptr();
where get_user_ptr is defined as:
return _base_addr + sizeof(GuardHeader);
but there is no guarantee the address can be dereferenced.
We could perhaps make this more robust. Though I should point out that the intent here is to check for accidental corruption of the char* returned by e.g. GetStringChars. If you pass a random address which you claim is such a char* then even creating the GuardedMemory wrapper is unspecified-behaviour (UB) and we could hit a memory fault at any point during the validation process, not just during `print_on`.
u_char udata = *get_user_ptr();
where get_user_ptr is defined as:
return _base_addr + sizeof(GuardHeader);
but there is no guarantee the address can be dereferenced.
We could perhaps make this more robust. Though I should point out that the intent here is to check for accidental corruption of the char* returned by e.g. GetStringChars. If you pass a random address which you claim is such a char* then even creating the GuardedMemory wrapper is unspecified-behaviour (UB) and we could hit a memory fault at any point during the validation process, not just during `print_on`.