Patrick Sodre, I haven't managed to get an isolated test case where the BufferUnderflow gets triggered. I can trigger it reliably given a full file, but when isolating the line where the exception occurs, it seems to work.
That being said, I believe I found an issue with the patches submitted so far. If you have malformed input where one character is a high surrogate, but the next character is not the complementing lower surrogate, you get a case where we have two characters in the buffer that are not part of a surrogate pair. This seems to work, except that the patches "past" the the second character. Therefore, an error occurring between the first and second getChar() won't recover from the correct position.
It also appears that this problem is further complicated if you choose to ignore malformed input (although, I'm still testing the edge cases here).