# HG changeset patch # User chegar # Date 1299833834 0 # Node ID 5bcd5ec71e278622677e9e5c8a65cb59801e39ee # Parent 4403ce77f30632fa981c037e65d5864c9563bdf8 7026346: URLConnection.guessContentTypeFromStream does not support UTF-8 and UTF-32 xml streams with BOM Reviewed-by: alanb Contributed-by: Charles Lee diff -r 4403ce77f306 -r 5bcd5ec71e27 jdk/src/share/classes/java/net/URLConnection.java --- a/jdk/src/share/classes/java/net/URLConnection.java Fri Mar 11 08:47:10 2011 +0000 +++ b/jdk/src/share/classes/java/net/URLConnection.java Fri Mar 11 08:57:14 2011 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1422,7 +1422,7 @@ if (!is.markSupported()) return null; - is.mark(12); + is.mark(16); int c1 = is.read(); int c2 = is.read(); int c3 = is.read(); @@ -1434,6 +1434,11 @@ int c9 = is.read(); int c10 = is.read(); int c11 = is.read(); + int c12 = is.read(); + int c13 = is.read(); + int c14 = is.read(); + int c15 = is.read(); + int c16 = is.read(); is.reset(); if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) { @@ -1461,6 +1466,13 @@ } } + // big and little (identical) endian UTF-8 encodings, with BOM + if (c1 == 0xef && c2 == 0xbb && c3 == 0xbf) { + if (c4 == '<' && c5 == '?' && c6 == 'x') { + return "application/xml"; + } + } + // big and little endian UTF-16 encodings, with byte order mark if (c1 == 0xfe && c2 == 0xff) { if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' && @@ -1476,6 +1488,23 @@ } } + // big and little endian UTF-32 encodings, with BOM + if (c1 == 0x00 && c2 == 0x00 && c3 == 0xfe && c4 == 0xff) { + if (c5 == 0 && c6 == 0 && c7 == 0 && c8 == '<' && + c9 == 0 && c10 == 0 && c11 == 0 && c12 == '?' && + c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') { + return "application/xml"; + } + } + + if (c1 == 0xff && c2 == 0xfe && c3 == 0x00 && c4 == 0x00) { + if (c5 == '<' && c6 == 0 && c7 == 0 && c8 == 0 && + c9 == '?' && c10 == 0 && c11 == 0 && c12 == 0 && + c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) { + return "application/xml"; + } + } + if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') { return "image/gif"; } diff -r 4403ce77f306 -r 5bcd5ec71e27 jdk/test/java/net/URLConnection/GetXmlContentType.java --- a/jdk/test/java/net/URLConnection/GetXmlContentType.java Fri Mar 11 08:47:10 2011 +0000 +++ b/jdk/test/java/net/URLConnection/GetXmlContentType.java Fri Mar 11 08:57:14 2011 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /* * @test - * @bug 4160195 - * @summary Check for correct detection of XML content type + * @bug 4160195 7026346 + * @summary Check for correct detection of XML content type, including BOM streams */ import java.io.*; @@ -34,6 +34,8 @@ public class GetXmlContentType { static final String XML_MIME_TYPE = "application/xml"; + static final String XML_HEADER = " 0) + throw new RuntimeException ( + "Test failed; passed = " + passed + ", failed = " + failed); + } + + static void contentTypeFromFile() throws Exception { // POSITIVE tests: good data --> good result - // - for (int i = 0; i < goodFiles.length; i++) { - String result = getUrlContentType (goodFiles [i]); + + for (String goodFile : goodFiles) { + String result = getUrlContentType(goodFile); - if (!XML_MIME_TYPE.equals (result)) { - System.out.println ("Wrong MIME type: " - + goodFiles [i] - + " --> " + result - ); - sawError = true; + if (!XML_MIME_TYPE.equals(result)) { + System.out.println("Wrong MIME type: " + goodFile + " --> " + result); + failed++; + } else { + passed++; } } - // // NEGATIVE tests: bad data --> correct diagnostic - // - for (int i = 0; i < badFiles.length; i++) { - String result = getUrlContentType (badFiles [i]); + for (String badFile : badFiles) { + String result = getUrlContentType(badFile); + + if (XML_MIME_TYPE.equals(result)) { + System.out.println("Wrong MIME type: " + badFile + " --> " + result); + failed++; + } else { + passed++; + } + } + } + + static String getUrlContentType(String name) throws IOException { + File file = new File(System.getProperty("test.src", "."), "xml"); + URL u = new URL("file:" + + file.getCanonicalPath() + + file.separator + + name); + URLConnection conn = u.openConnection(); + + return conn.getContentType(); + } - if (XML_MIME_TYPE.equals (result)) { - System.out.println ("Wrong MIME type: " - + badFiles [i] - + " --> " + result - ); - sawError = true; - } + static void contentTypeFromBOMStream() throws Exception { + final String[] encodings = new String[] + {"UTF-8", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE"}; + for (String encoding : encodings) { + try (InputStream is = new ByteArrayInputStream(toBOMBytes(encoding))) { + String mime = URLConnection.guessContentTypeFromStream(is); + if ( !XML_MIME_TYPE.equals(mime) ) { + System.out.println("Wrong MIME type: " + encoding + " --> " + mime); + failed++; + } else { + passed++; + } + } + } + } + + static byte[] toBOMBytes(String encoding) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + switch (encoding) { + case "UTF-8" : + bos.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }); + break; + case "UTF-16BE" : + bos.write(new byte[] { (byte) 0xFE, (byte) 0xFF }); + break; + case "UTF-16LE" : + bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE }); + break; + case "UTF-32BE" : + bos.write(new byte[] { (byte) 0x00, (byte) 0x00, + (byte) 0xFE, (byte) 0xFF }); + break; + case "UTF-32LE" : + bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE, + (byte) 0x00, (byte) 0x00 }); } - if (sawError) - throw new Exception ( - "GetXmlContentType Test failed; see diagnostics."); + bos.write(XML_HEADER.getBytes(encoding)); + return bos.toByteArray(); } - - static String getUrlContentType (String name) throws IOException { - File file = new File(System.getProperty("test.src", "."), "xml"); - URL u = new URL ("file:" - + file.getCanonicalPath() - + file.separator - + name); - URLConnection conn = u.openConnection (); - - return conn.getContentType (); - } - }