Add validation to resource type/interface addition
authorErich Keane <erich.keane@intel.com>
Wed, 16 Sep 2015 21:33:19 +0000 (14:33 -0700)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Sat, 19 Sep 2015 12:27:16 +0000 (12:27 +0000)
The functions that add resource type/interfaces to the resources were
not correctly validating them to the RFC.  This commit adds validation
to these such that RFC6690 is enforced, and gives the developer
immediate/early warning of invalid values.

Change-Id: If04f72c1aa69ec2f9fbc83d849a503c2ee86f502
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2605
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
resource/csdk/stack/src/ocstack.c
resource/unittests/OCResourceResponseTest.cpp

index 474da86..53beb1c 100644 (file)
@@ -2865,7 +2865,6 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
 {
 
     OCResource *pointer = NULL;
-    char *str = NULL;
     OCStackResult result = OC_STACK_ERROR;
 
     OC_LOG(INFO, TAG, "Entering OCCreateResource");
@@ -2929,13 +2928,12 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
     insertResource(pointer);
 
     // Set the uri
-    str = OICStrdup(uri);
-    if (!str)
+    pointer->uri = OICStrdup(uri);
+    if (!pointer->uri)
     {
         result = OC_STACK_NO_MEMORY;
         goto exit;
     }
-    pointer->uri = str;
 
     // Set properties.  Set OC_ACTIVE
     pointer->resourceProperties = (OCResourceProperty) (resourceProperties
@@ -2985,7 +2983,6 @@ exit:
     {
         // Deep delete of resource and other dynamic elements that it contains
         deleteResource(pointer);
-        OICFree(str);
     }
     return result;
 }
@@ -3097,6 +3094,29 @@ OCStackResult OCUnBindResource(
     return OC_STACK_ERROR;
 }
 
+// Precondition is that the parameter has been checked to not equal NULL.
+static bool ValidateResourceTypeInterface(const char *resourceItemName)
+{
+    if (resourceItemName[0] < 'a' || resourceItemName[0] > 'z')
+    {
+        return false;
+    }
+
+    size_t index = 1;
+    while (resourceItemName[index] != '\0')
+    {
+        if (resourceItemName[index] != '.' &&
+                resourceItemName[index] != '-' &&
+                (resourceItemName[index] < 'a' || resourceItemName[index] > 'z') &&
+                (resourceItemName[index] < '0' || resourceItemName[index] > '9'))
+        {
+            return false;
+        }
+        ++index;
+    }
+
+    return true;
+}
 OCStackResult BindResourceTypeToResource(OCResource* resource,
                                             const char *resourceTypeName)
 {
@@ -3106,6 +3126,12 @@ OCStackResult BindResourceTypeToResource(OCResource* resource,
 
     VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
 
+    if (!ValidateResourceTypeInterface(resourceTypeName))
+    {
+        OC_LOG(ERROR, TAG, "resource type illegal (see RFC 6690)");
+        return OC_STACK_INVALID_PARAM;
+    }
+
     pointer = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
     if (!pointer)
     {
@@ -3143,6 +3169,12 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource,
 
     VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
 
+    if (!ValidateResourceTypeInterface(resourceInterfaceName))
+    {
+        OC_LOG(ERROR, TAG, "resource /interface illegal (see RFC 6690)");
+        return OC_STACK_INVALID_PARAM;
+    }
+
     OC_LOG_V(INFO, TAG, "Binding %s interface to %s", resourceInterfaceName, resource->uri);
 
     pointer = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
index 3ea5826..3b9e711 100644 (file)
@@ -118,13 +118,13 @@ namespace OCResourceResponseTest
         OCResourceResponse response;
         OCResourceHandle resHandle;
 
-        std::string resourceURI = "/a/light1";
+        std::string resourceURI = "/a/light2";
         std::string resourceTypeName = "core.light";
         std::string resourceInterface = DEFAULT_INTERFACE;
         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
 
-        EXPECT_EQ(OC_STACK_OK, OCCreateResource(&resHandle, resourceURI.c_str(),
-                resourceTypeName.c_str(), resourceInterface.c_str(), nullptr, nullptr,
+        EXPECT_EQ(OC_STACK_OK, OCCreateResource(&resHandle, resourceTypeName.c_str(),
+                resourceInterface.c_str(), resourceURI.c_str(), nullptr, nullptr,
                 resourceProperty));
         EXPECT_EQ(NULL, response.getResourceHandle());
         EXPECT_NO_THROW(response.setResourceHandle(resHandle));