if (!dp)
return -1;
- while (1) {
+ if (buf && size)
+ memset(buf, 0, size);
+
+ while (limit) {
if (limit >= 0 && (limit < 4 || efidp_node_size(dp) > limit)) {
if (off)
return off;
off += format(buf, size, off, ",");
break;
}
- return off;
+ return off + 1;
default:
off += format(buf, size, off, "Path(%d,%d,", dp->type,
dp->subtype);
size -= sizeof(*opt);
if (size < opt->file_path_list_length)
return -1;
+ size -= opt->file_path_list_length;
+ /* "size" as the limit means sz will be size or less in all cases; no
+ * need to test it. if it /is/ size, there's no optional data. */
sz = ucs2size(opt->description, size);
- if (sz >= size) // since there's no room for a file path...
- return -1;
p = (uint8_t *)(opt->description) + sz;
size -= sz;
- if (!efidp_is_valid((const_efidp)p, size))
+ if (!efidp_is_valid((const_efidp)p, opt->file_path_list_length))
return -1;
sz = efidp_size((const_efidp)p);
- p += sz;
- size -= sz;
+ if (sz != opt->file_path_list_length)
+ return -1;
return size;
}
efi_loadopt_path(efi_load_option *opt, ssize_t limit)
{
char *p = (char *)opt;
- size_t l;
- ssize_t desc_limit;
+ size_t sz;
+ size_t left;
efidp dp;
- l = (size_t)limit;
- if (l <= offsetof(efi_load_option, description))
+ left = (size_t)limit;
+ if (left <= offsetof(efi_load_option, description))
+ return NULL;
+ left -= offsetof(efi_load_option, description);
+ p += offsetof(efi_load_option, description);
+
+ sz = ucs2size(opt->description, left);
+ if (sz >= left) // since there's no room for a file path...
+ return NULL;
+ p += sz;
+ left -= sz;
+
+ if (left < opt->file_path_list_length)
return NULL;
- desc_limit = limit - offsetof(efi_load_option, description);
- dp = (efidp)(p + sizeof (opt->attributes)
- + sizeof (opt->file_path_list_length)
- + ucs2size(opt->description, desc_limit));
- limit -= (unsigned long)dp - (unsigned long)opt;
- if (!efidp_is_valid(dp, limit))
+ dp = (efidp)p;
+ if (!efidp_is_valid(dp, opt->file_path_list_length))
return NULL;
return dp;
}