diff options
Diffstat (limited to 'lib/libfdt/fdt_ro.c')
-rw-r--r-- | lib/libfdt/fdt_ro.c | 104 |
1 files changed, 64 insertions, 40 deletions
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, |