diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/AtomReaderWriter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/AtomReaderWriter.java index 01fbab3a870f4..385818125538a 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/AtomReaderWriter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/implementation/AtomReaderWriter.java @@ -1,11 +1,11 @@ /** * Copyright Microsoft Corporation - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -84,8 +84,7 @@ public void write(XMLStreamWriter writer) throws XMLStreamException { if (value != null) { writer.writeCharacters(value); - } - else { + } else { writer.writeAttribute("m:null", "true"); } @@ -108,8 +107,7 @@ public List parseTableEntries(InputStream stream) { // Process "entry" elements only if (isStartElement(xmlr, "entry")) { result.add(parseTableEntry(xmlr)); - } - else { + } else { nextSignificant(xmlr); } } @@ -118,8 +116,7 @@ public List parseTableEntries(InputStream stream) { expect(xmlr, XMLStreamConstants.END_DOCUMENT); return result; - } - catch (XMLStreamException e) { + } catch (XMLStreamException e) { throw new RuntimeException(e); } } @@ -133,8 +130,7 @@ public TableEntry parseTableEntry(InputStream stream) { expect(xmlr, XMLStreamConstants.END_DOCUMENT); return result; - } - catch (XMLStreamException e) { + } catch (XMLStreamException e) { throw new RuntimeException(e); } } @@ -151,8 +147,7 @@ public List parseEntityEntries(InputStream stream) { // Process "entry" elements only if (isStartElement(xmlr, "entry")) { result.add(parseEntityEntry(xmlr)); - } - else { + } else { nextSignificant(xmlr); } } @@ -161,8 +156,7 @@ public List parseEntityEntries(InputStream stream) { expect(xmlr, XMLStreamConstants.END_DOCUMENT); return result; - } - catch (XMLStreamException e) { + } catch (XMLStreamException e) { throw new RuntimeException(e); } } @@ -176,8 +170,7 @@ public Entity parseEntityEntry(InputStream stream) { expect(xmlr, XMLStreamConstants.END_DOCUMENT); return result; - } - catch (XMLStreamException e) { + } catch (XMLStreamException e) { throw new RuntimeException(e); } } @@ -227,8 +220,7 @@ private InputStream generateEntry(PropertiesWriter propertiesWriter) { writer.close(); return new ByteArrayInputStream(stream.toByteArray()); - } - catch (XMLStreamException e) { + } catch (XMLStreamException e) { throw new RuntimeException(e); } } @@ -243,8 +235,7 @@ private TableEntry parseTableEntry(XMLStreamReader xmlr) throws XMLStreamExcepti Map properties = parseEntryProperties(xmlr); result.setName((String) properties.get("TableName").getValue()); - } - else { + } else { nextSignificant(xmlr); } } @@ -263,8 +254,7 @@ private Entity parseEntityEntry(XMLStreamReader xmlr) throws XMLStreamException while (!isEndElement(xmlr, "entry")) { if (isStartElement(xmlr, "properties")) { result.setProperties(parseEntryProperties(xmlr)); - } - else { + } else { nextSignificant(xmlr); } } @@ -336,12 +326,11 @@ private void expect(XMLStreamReader xmlr, int eventType, String localName) throw private String encodeNumericCharacterReference(String value) { if (value == null) { return null; - } - else { + } else { char[] charArray = value.toCharArray(); StringBuffer stringBuffer = new StringBuffer(); for (int index = 0; index < charArray.length; index++) { - if (charArray[index] < 0x20 || charArray[index] > 0x7f) + if (isIllegalChar(charArray[index])) stringBuffer.append("&#x").append(Integer.toHexString(charArray[index])).append(";"); else stringBuffer.append(charArray[index]); @@ -349,4 +338,9 @@ private String encodeNumericCharacterReference(String value) { return stringBuffer.toString(); } } + + private boolean isIllegalChar(char c) { + return !(c == 9 || c == 0xA || c == 0xD || (c >= 0x20 && c < 0xD800) || + (c >= 0xE000 && c < 0xFFFE) || (c >= 0x10000 && c < 0x110000)); + } } diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java index bef37b00a2733..cf834576ac4ae 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java @@ -377,22 +377,81 @@ public void insertEntityEscapeCharactersWorks() throws Exception { assertNotNull(result.getEntity().getProperty("test4")); String actualTest4 = (String) result.getEntity().getProperty("test4").getValue(); - assertEquals("ꪪ", actualTest4); + assertEquals("\uaaaa", actualTest4); assertNotNull(result.getEntity().getProperty("test5")); String actualTest5 = (String) result.getEntity().getProperty("test5").getValue(); - assertEquals("닢", actualTest5); + assertEquals("\ub2e2", actualTest5); assertNotNull(result.getEntity().getProperty("test6")); String actualTest6 = (String) result.getEntity().getProperty("test6").getValue(); - assertEquals(" 닢", actualTest6); + assertEquals(" \ub2e2", actualTest6); assertNotNull(result.getEntity().getProperty("test7")); String actualTest7 = (String) result.getEntity().getProperty("test7").getValue(); - assertEquals("ok 닢", actualTest7); + assertEquals("ok \ub2e2", actualTest7); } + @Test + public void insertEntityEscapeCharactersRoundTripsFromService() throws Exception { + // Arrange + Configuration config = createConfiguration(); + TableContract service = TableService.create(config); + + String partition = "001"; + String row = "insertEntityEscapeCharactersRoundTripsFromService"; + Entity insertedEntity = new Entity().setPartitionKey(partition).setRowKey(row) + .setProperty("test", EdmType.STRING, "\u0005") + .setProperty("test2", EdmType.STRING, "\u0011") + .setProperty("test3", EdmType.STRING, "\u0025") + .setProperty("test4", EdmType.STRING, "\uaaaa") + .setProperty("test5", EdmType.STRING, "\ub2e2") + .setProperty("test6", EdmType.STRING, " \ub2e2") + .setProperty("test7", EdmType.STRING, "ok \ub2e2") + .setProperty("test8", EdmType.STRING, "\uD840"); + ; + + service.insertEntity(TEST_TABLE_2, insertedEntity); + + GetEntityResult result = service.getEntity(TEST_TABLE_2, "001", "insertEntityEscapeCharactersRoundTripsFromService"); + assertNotNull(result); + + Entity entity = result.getEntity(); + + assertNotNull(entity.getProperty("test")); + String actualTest1 = (String) entity.getPropertyValue("test"); + assertEquals("", actualTest1); + + assertNotNull(result.getEntity().getProperty("test2")); + String actualTest2 = (String) result.getEntity().getPropertyValue("test2"); + assertEquals("", actualTest2); + + assertNotNull(result.getEntity().getProperty("test3")); + String actualTest3 = (String) result.getEntity().getPropertyValue("test3"); + assertEquals("%", actualTest3); + + assertNotNull(result.getEntity().getProperty("test4")); + String actualTest4 = (String) result.getEntity().getPropertyValue("test4"); + assertEquals("\uaaaa", actualTest4); + + assertNotNull(result.getEntity().getProperty("test5")); + String actualTest5 = (String) result.getEntity().getPropertyValue("test5"); + assertEquals("\ub2e2", actualTest5); + + assertNotNull(result.getEntity().getProperty("test6")); + String actualTest6 = (String) result.getEntity().getPropertyValue("test6"); + assertEquals(" \ub2e2", actualTest6); + + assertNotNull(result.getEntity().getProperty("test7")); + String actualTest7 = (String) result.getEntity().getPropertyValue("test7"); + assertEquals("ok \ub2e2", actualTest7); + + String actualTest8 = (String)entity.getPropertyValue("test8"); + assertEquals("�", actualTest8); + } + + @Test public void updateEntityWorks() throws Exception { System.out.println("updateEntityWorks()");