Problema di codifica Java 8 UTF-8 (java bug?)

Esiste un’incoerenza durante la creazione di una stringa con codifica UTF-8.

Esegui questo codice:

public static void encodingIssue() throws IOException { byte[] array = new byte[3]; array[0] = (byte) -19; array[1] = (byte) -69; array[2] = (byte) -100; String str = new String(array, "UTF-8"); for (char c : str.toCharArray()) { System.out.println((int) c); } } 

Su Java 1.8.0_20 (e versioni precedenti) abbiamo il risultato

 65533 

Su Java 1.7 e 1.6 abbiamo il risultato corretto:

 57052 

Hai riscontrato questo errore? C’è una soluzione per questo?

Questa incongruenza si manifesta anche per Shift_JIS, JIS_X0212-1990, x-IBM300, x-IBM834, x-IBM942, x-IBM942C, x-JIS0208, ma ovviamente UTF-8 è il più urgente.

È una proprietà della codifica ” Modified UTF-8 ” per memorizzare coppie di surrogati (o anche caratteri non appaiati di tale intervallo) come singoli caratteri. Ed è un errore se un decodificatore che dichiara di utilizzare lo standard UTF-8 usa ” Modified UTF-8 “. Questo sembra essere stato risolto con Java 8.

È ansible leggere in modo affidabile tali dati utilizzando un metodo specificato per utilizzare ” Modified UTF-8 “:

 ByteBuffer bb=ByteBuffer.allocate(array.length+2); bb.putShort((short)array.length).put(array); ByteArrayInputStream bis=new ByteArrayInputStream(bb.array()); DataInputStream dis=new DataInputStream(bis); String str=dis.readUTF(); 

Il valore ricevuto in Java 1.6 / 1.7 è U + DEDC (un surrogato basso).

Da RFC 3629 :

La definizione di UTF-8 proibisce la codifica dei numeri di caratteri tra U + D800 e U + DFFF, che sono riservati per l’uso con il modulo di codifica UTF-16 (come coppie di surrogati) e non rappresentano direttamente i caratteri.

… testo eliso …

Le implementazioni dell’algoritmo di decodifica di cui sopra DEVONO proteggere contro la decodifica di sequenze non valide. Ad esempio, un’implementazione ingenua può decodificare la sequenza UT0-8 di UTF-8 nel carattere U + 0000, o la coppia surrogata ED A1 8C ED BE B4 in U + 233B4. La decodifica di sequenze non valide può avere conseguenze sulla sicurezza o causare altri problemi.

Java 8 lo decodifica in U + FFFD ( SOSTITUZIONE CARATTERE ). Sembra un bug corretto in Java 8.

Questo è un surrogato, giusto? Non sono un esperto Unicode, ma non penso che abbia un significato da solo. Java 8 modificato per supportare Unicode 6.2. Forse è più severo su questo. 65533 è il carattere di sostituzione 0xFFFD standard, che significa “non rappresentabile”. Esiste un caso reale in cui è necessario interpretarlo come una stringa? perché sembra che Unicode stia dicendo che non ha più senso come personaggio.