You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2019/10/01 16:56:29 UTC

[sling-org-apache-sling-servlets-post] branch master updated: SLING-8755 : Exception when empty value with a type hint other than string is posted

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-post.git


The following commit(s) were added to refs/heads/master by this push:
     new abc49e2  SLING-8755 : Exception when empty value with a type hint other than string is posted
abc49e2 is described below

commit abc49e2a5eb326fe6b421ce21a4bc6d9f8d44b38
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Oct 1 18:56:02 2019 +0200

    SLING-8755 : Exception when empty value with a type hint other than string is posted
---
 pom.xml                                            |   6 +
 .../impl/helper/SlingPropertyValueHandler.java     |   8 +-
 .../SlingPropertyValueHandlerAutotypeTest.java     |   4 +-
 .../impl/helper/SlingPropertyValueHandlerTest.java | 141 +++++++++++++++++++++
 4 files changed, 156 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 9e3b3fe..c484334 100644
--- a/pom.xml
+++ b/pom.xml
@@ -198,6 +198,12 @@
             <version>1.4</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java b/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
index 11a77a0..0ff1365 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
@@ -211,7 +211,11 @@ public class SlingPropertyValueHandler {
 
         // RequestProperty#getStringValues already takes care of the configs ignoreBlanks, defaultValues etc.
         // and provides values as null, new String[0] etc. accordingly.
-        if (values == null) {
+        final int type = getType(parent, prop);
+
+        if (values == null
+                || (values.length == 1 && values[0].length() == 0 && type != PropertyType.STRING
+                        && type != PropertyType.UNDEFINED)) {
             // if no value is present, just remove the existing property (if any)
             removeProperty(parent, prop);
 
@@ -229,7 +233,6 @@ public class SlingPropertyValueHandler {
             }
 
             final boolean multiValue = isMultiValue(parent, prop, values);
-            final int type = getType(parent, prop);
 
             if (multiValue) {
                 // converting single into multi value props requires deleting it first
@@ -383,6 +386,7 @@ public class SlingPropertyValueHandler {
                     changes.add(Modification.onDeleted(removePath));
                 }
             } else {
+                parent.valueMap.put(prop.getName(), "");
                 changes.add(Modification.onModified(parent.resource.getPath() + '/' + prop.getName()));
             }
         }
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java b/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java
index 0860747..ec8a14f 100644
--- a/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java
+++ b/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerAutotypeTest.java
@@ -17,15 +17,17 @@
 package org.apache.sling.servlets.post.impl.helper;
 
 import static org.junit.Assert.assertEquals;
+
 import org.junit.Test;
 
 /** Verify the AutoType values of property names for which
  *  we automatically set values.
  */
 public class SlingPropertyValueHandlerAutotypeTest {
+
     private void assertAlias(String propertyNameA) {
         final String propertyNameB = "jcr:" + propertyNameA;
-                
+
         assertEquals("Expecting same AutotType for " + propertyNameA + " and " + propertyNameB,
                 SlingPropertyValueHandler.getAutoType(propertyNameA),
                 SlingPropertyValueHandler.getAutoType(propertyNameB)
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerTest.java b/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerTest.java
new file mode 100644
index 0000000..3689438
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandlerTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.servlets.post.impl.helper;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.wrappers.ModifiableValueMapDecorator;
+import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.ModificationType;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class SlingPropertyValueHandlerTest {
+
+    @Test
+    public void testEmptyPropertyValueWithTypeLong() throws Exception {
+        final List<Modification> mods = new ArrayList<Modification>();
+        final JCRSupport support = new JCRSupport();
+
+        final SlingPropertyValueHandler handler = new SlingPropertyValueHandler(new DateParser(), support, mods);
+
+        final Session jcrSession = Mockito.mock(Session.class);
+
+        final ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+        Mockito.when(resolver.adaptTo(Session.class)).thenReturn(jcrSession);
+
+        final Node node = Mockito.mock(Node.class);
+        final Property jcrProp = Mockito.mock(Property.class);
+        Mockito.when(node.getProperty("property")).thenReturn(jcrProp);
+        final PropertyDefinition jcrPropDef = Mockito.mock(PropertyDefinition.class);
+        Mockito.when(jcrProp.getDefinition()).thenReturn(jcrPropDef);
+        Mockito.when(jcrPropDef.isMandatory()).thenReturn(false);
+        // throw exception for previous behaviour
+        Mockito.when(node.setProperty("property", "", 3)).thenThrow(new RepositoryException());
+
+        final Resource rsrc = Mockito.mock(Resource.class);
+        final ModifiableValueMap valueMap = new ModifiableValueMapDecorator(new HashMap<String, Object>());
+        valueMap.put("property", 7L);
+
+        Mockito.when(rsrc.getPath()).thenReturn("/content");
+        Mockito.when(rsrc.getName()).thenReturn("content");
+        Mockito.when(rsrc.adaptTo(Node.class)).thenReturn(node);
+        Mockito.when(rsrc.adaptTo(ModifiableValueMap.class)).thenReturn(valueMap);
+        Mockito.when(rsrc.getResourceResolver()).thenReturn(resolver);
+
+        final RequestParameter req = Mockito.mock(RequestParameter.class);
+        Mockito.when(req.isFormField()).thenReturn(true);
+        Mockito.when(req.getName()).thenReturn("property");
+        Mockito.when(req.getString()).thenReturn("");
+
+        final RequestProperty prop = new RequestProperty("/content/property");
+        prop.setTypeHintValue("Long");
+        prop.setValues(new RequestParameter[] { req });
+
+        handler.setProperty(rsrc, prop);
+
+        // value map should be empty, one change: delete
+        assertTrue(valueMap.isEmpty());
+        assertEquals(1, mods.size());
+        assertEquals(ModificationType.DELETE, mods.get(0).getType());
+        assertEquals("/content/property", mods.get(0).getSource());
+    }
+
+    @Test
+    public void testEmptyPropertyValueWithoutType() throws Exception {
+        final List<Modification> mods = new ArrayList<Modification>();
+        final JCRSupport support = new JCRSupport();
+
+        final SlingPropertyValueHandler handler = new SlingPropertyValueHandler(new DateParser(), support, mods);
+
+        final Session jcrSession = Mockito.mock(Session.class);
+
+        final ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+        Mockito.when(resolver.adaptTo(Session.class)).thenReturn(jcrSession);
+
+        final Node node = Mockito.mock(Node.class);
+        final Property jcrProp = Mockito.mock(Property.class);
+        Mockito.when(node.getProperty("property")).thenReturn(jcrProp);
+        final PropertyDefinition jcrPropDef = Mockito.mock(PropertyDefinition.class);
+        Mockito.when(jcrProp.getDefinition()).thenReturn(jcrPropDef);
+        Mockito.when(jcrPropDef.isMandatory()).thenReturn(false);
+        // throw exception for previous behaviour
+        Mockito.when(node.setProperty("property", "", 3)).thenThrow(new RepositoryException());
+
+        final Resource rsrc = Mockito.mock(Resource.class);
+        final ModifiableValueMap valueMap = new ModifiableValueMapDecorator(new HashMap<String, Object>());
+        valueMap.put("property", "hello");
+
+        Mockito.when(rsrc.getPath()).thenReturn("/content");
+        Mockito.when(rsrc.getName()).thenReturn("content");
+        Mockito.when(rsrc.adaptTo(Node.class)).thenReturn(node);
+        Mockito.when(rsrc.adaptTo(ModifiableValueMap.class)).thenReturn(valueMap);
+        Mockito.when(rsrc.getResourceResolver()).thenReturn(resolver);
+
+        final RequestParameter req = Mockito.mock(RequestParameter.class);
+        Mockito.when(req.isFormField()).thenReturn(true);
+        Mockito.when(req.getName()).thenReturn("property");
+        Mockito.when(req.getString()).thenReturn("");
+
+        final RequestProperty prop = new RequestProperty("/content/property");
+        prop.setValues(new RequestParameter[] { req });
+
+        handler.setProperty(rsrc, prop);
+
+        // value map should be empty, one change: delete
+        assertEquals(1, valueMap.size());
+        assertEquals("", valueMap.get("property"));
+        assertEquals(1, mods.size());
+        assertEquals(ModificationType.MODIFY, mods.get(0).getType());
+        assertEquals("/content/property", mods.get(0).getSource());
+    }
+}