From 5b39feb362d8aecbb89a0d9a8613a4f5253a37bc Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Thu, 21 Feb 2013 17:36:55 -0800 Subject: [PATCH 1/2] Reduced characters that get encoded to just the illegal set --- .../implementation/AtomReaderWriter.java | 44 ++++++------- .../table/TableServiceIntegrationTest.java | 64 +++++++++++++++++-- 2 files changed, 79 insertions(+), 29 deletions(-) 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..71bc58d48fe47 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,78 @@ 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") + ; + + 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().getProperty("test3").getValue(); + assertEquals("%", actualTest3); + + assertNotNull(result.getEntity().getProperty("test4")); + String actualTest4 = (String) result.getEntity().getProperty("test4").getValue(); + assertEquals("\uaaaa", actualTest4); + + assertNotNull(result.getEntity().getProperty("test5")); + String actualTest5 = (String) result.getEntity().getProperty("test5").getValue(); + assertEquals("\ub2e2", actualTest5); + + assertNotNull(result.getEntity().getProperty("test6")); + String actualTest6 = (String) result.getEntity().getProperty("test6").getValue(); + assertEquals(" \ub2e2", actualTest6); + + assertNotNull(result.getEntity().getProperty("test7")); + String actualTest7 = (String) result.getEntity().getProperty("test7").getValue(); + assertEquals("ok \ub2e2", actualTest7); + + } + + @Test public void updateEntityWorks() throws Exception { System.out.println("updateEntityWorks()"); From 3f7bf110d98526a5aa6a329c6a790d27e8893e3a Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Fri, 22 Feb 2013 13:53:48 -0800 Subject: [PATCH 2/2] Added surrogate pair character to test --- .../services/table/TableServiceIntegrationTest.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) 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 71bc58d48fe47..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 @@ -409,6 +409,7 @@ public void insertEntityEscapeCharactersRoundTripsFromService() throws Exception .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); @@ -427,25 +428,27 @@ public void insertEntityEscapeCharactersRoundTripsFromService() throws Exception assertEquals("", actualTest2); assertNotNull(result.getEntity().getProperty("test3")); - String actualTest3 = (String) result.getEntity().getProperty("test3").getValue(); + String actualTest3 = (String) result.getEntity().getPropertyValue("test3"); assertEquals("%", actualTest3); assertNotNull(result.getEntity().getProperty("test4")); - String actualTest4 = (String) result.getEntity().getProperty("test4").getValue(); + String actualTest4 = (String) result.getEntity().getPropertyValue("test4"); assertEquals("\uaaaa", actualTest4); assertNotNull(result.getEntity().getProperty("test5")); - String actualTest5 = (String) result.getEntity().getProperty("test5").getValue(); + String actualTest5 = (String) result.getEntity().getPropertyValue("test5"); assertEquals("\ub2e2", actualTest5); assertNotNull(result.getEntity().getProperty("test6")); - String actualTest6 = (String) result.getEntity().getProperty("test6").getValue(); + String actualTest6 = (String) result.getEntity().getPropertyValue("test6"); assertEquals(" \ub2e2", actualTest6); assertNotNull(result.getEntity().getProperty("test7")); - String actualTest7 = (String) result.getEntity().getProperty("test7").getValue(); + String actualTest7 = (String) result.getEntity().getPropertyValue("test7"); assertEquals("ok \ub2e2", actualTest7); + String actualTest8 = (String)entity.getPropertyValue("test8"); + assertEquals("�", actualTest8); }