summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/fdtdec.c2
-rw-r--r--lib/libfdt/fdt_ro.c104
2 files changed, 65 insertions, 41 deletions
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 4defb902b8..adc9975c36 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1014,7 +1014,7 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
{
int index;
- index = fdt_find_string(fdt, node, prop_names, name);
+ index = fdt_stringlist_search(fdt, node, prop_names, name);
if (index < 0)
return index;
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index 005f26736f..e38aaa4ccf 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -538,80 +538,104 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
return 0;
}
-int fdt_count_strings(const void *fdt, int node, const char *property)
+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
{
- int length, i, count = 0;
- const char *list;
+ const char *list, *end;
+ int length, count = 0;
- list = fdt_getprop(fdt, node, property, &length);
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
if (!list)
- return length;
+ return -length;
+
+ end = list + length;
+
+ while (list < end) {
+ length = strnlen(list, end - list) + 1;
- for (i = 0; i < length; i++) {
- int len = strlen(list);
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end)
+ return -FDT_ERR_BADVALUE;
- list += len + 1;
- i += len;
+ list += length;
count++;
}
return count;
}
-int fdt_find_string(const void *fdt, int node, const char *property,
- const char *string)
+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
+ const char *string)
{
+ int length, len, idx = 0;
const char *list, *end;
- int len, index = 0;
- list = fdt_getprop(fdt, node, property, &len);
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
if (!list)
- return len;
+ return -length;
- end = list + len;
- len = strlen(string);
+ len = strlen(string) + 1;
+ end = list + length;
while (list < end) {
- int l = strlen(list);
+ length = strnlen(list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end)
+ return -FDT_ERR_BADVALUE;
- if (l == len && memcmp(list, string, len) == 0)
- return index;
+ if (length == len && memcmp(list, string, length) == 0)
+ return idx;
- list += l + 1;
- index++;
+ list += length;
+ idx++;
}
return -FDT_ERR_NOTFOUND;
}
-int fdt_get_string_index(const void *fdt, int node, const char *property,
- int index, const char **output)
+const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
+ const char *property, int idx,
+ int *lenp)
{
- const char *list;
- int length, i;
+ const char *list, *end;
+ int length;
+
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
+ if (!list) {
+ if (lenp)
+ *lenp = length;
- list = fdt_getprop(fdt, node, property, &length);
+ return NULL;
+ }
- for (i = 0; i < length; i++) {
- int len = strlen(list);
+ end = list + length;
- if (index == 0) {
- *output = list;
- return 0;
+ while (list < end) {
+ length = strnlen(list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end) {
+ if (lenp)
+ *lenp = -FDT_ERR_BADVALUE;
+
+ return NULL;
+ }
+
+ if (idx == 0) {
+ if (lenp)
+ *lenp = length - 1;
+
+ return list;
}
- list += len + 1;
- i += len;
- index--;
+ list += length;
+ idx--;
}
- return -FDT_ERR_NOTFOUND;
-}
+ if (lenp)
+ *lenp = -FDT_ERR_NOTFOUND;
-int fdt_get_string(const void *fdt, int node, const char *property,
- const char **output)
-{
- return fdt_get_string_index(fdt, node, property, 0, output);
+ return NULL;
}
int fdt_node_check_compatible(const void *fdt, int nodeoffset,