device property: Fix reading pset strings using array access functions
authorSakari Ailus <sakari.ailus@linux.intel.com>
Tue, 28 Mar 2017 12:22:18 +0000 (15:22 +0300)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 28 Mar 2017 22:00:30 +0000 (00:00 +0200)
The length field value of non-array string properties is the length of the
string itself. Non-array string properties thus require specific handling.
Fix this.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/property.c

index c69bde8..166cfdb 100644 (file)
@@ -147,14 +147,36 @@ static int pset_prop_read_string_array(struct property_set *pset,
                                       const char *propname,
                                       const char **strings, size_t nval)
 {
+       const struct property_entry *prop;
        const void *pointer;
-       size_t length = nval * sizeof(*strings);
+       size_t array_len, length;
+
+       /* Find out the array length. */
+       prop = pset_prop_get(pset, propname);
+       if (!prop)
+               return -EINVAL;
+
+       if (!prop->is_array)
+               /* The array length for a non-array string property is 1. */
+               array_len = 1;
+       else
+               /* Find the length of an array. */
+               array_len = pset_prop_count_elems_of_size(pset, propname,
+                                                         sizeof(const char *));
+
+       /* Return how many there are if strings is NULL. */
+       if (!strings)
+               return array_len;
+
+       array_len = min(nval, array_len);
+       length = array_len * sizeof(*strings);
 
        pointer = pset_prop_find(pset, propname, length);
        if (IS_ERR(pointer))
                return PTR_ERR(pointer);
 
        memcpy(strings, pointer, length);
+
        return 0;
 }
 
@@ -555,12 +577,8 @@ static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
                return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
                                           val, nval);
        else if (is_pset_node(fwnode))
-               return val ?
-                       pset_prop_read_string_array(to_pset_node(fwnode),
-                                                   propname, val, nval) :
-                       pset_prop_count_elems_of_size(to_pset_node(fwnode),
-                                                     propname,
-                                                     sizeof(const char *));
+               return pset_prop_read_string_array(to_pset_node(fwnode),
+                                                  propname, val, nval);
        return -ENXIO;
 }