my $scalar = qq|"\\uD800"|;
my $decoded = JSON::PP->new->allow_nonref->decode($scalar);
Fails as expected with missing low surrogate character in surrogate pair, at character offset 8 (before "(end of string)") at ...
my $scalar = qq|"\x{D800}"|;
my $decoded = JSON::PP->new->allow_nonref->decode($scalar);
No error is produced and the resulting string has invalid Unicode.
This is a particularly a problem with ->utf8 is specified as, I'd expect only valid unicode to be decoded. However I think there's merit to handling the escaped and non-escaped codepoints the same regardless of whether UTF-8 decoding is done.
The same issue exists with JSON::XS and I just emailed Marc Lehmann.