On 02/07/18(Mon) 23:08, David Bern wrote:
> > Is it necessary to parse these examples? Or maybe we can live with
> > your strtonum() fix for now.
> I can live with that.
>
> > I don't know. So unless somebody else gives us some input I'd suggest
> > we move forward with your safe diff even if it doesn't fix all the
> > cases.
> >
> > If it fixes your use case it is already an improvement.
>
> I have attached a strtonum() fix.
> To give a short summary on how it works.
> In us == -1 cases, I locate the '%'-symbol stored page_contents[j].name
> to calculate length. The length is then used to compare the function
> input "name" with page_contents[j].name.
>
> If name match, I then use "len" to position "name" to the
> strtonum-function and use the return value to calculate the usage
> number.
>
> For people who want to test this patch;
> hid_start()
> snprintf(usage, sizeof(usage), "%s:%s",
> hid_usage_page(HID_PAGE(test_val)),
> hid_usage_in_page(test_val));
> test_val == hid_parse_usage_in_page(usage)
>
> As mentioned earlier the usage = (16 << 16) | 0xA (16 Unicode) and
> higher will fail, but 0 to 9 succeeds.
>
> If wanted I can send the code I used to test this.
It would be great if you could turn that into a regression test to put
in /usr/src/regress/lib/libusbhid/nameofyourtest :)
> Index: usage.c
> ===================================================================
> RCS file: /cvs/src/lib/libusbhid/usage.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 usage.c
> --- usage.c 8 Oct 2014 04:49:36 -0000 1.16
> +++ usage.c 2 Jul 2018 19:51:13 -0000
> @@ -264,9 +264,9 @@ hid_parse_usage_page(const char *name)
> int
> hid_parse_usage_in_page(const char *name)
> {
> - const char *sep;
> + const char *sep, *fmtsep, *errstr, *fmtname;
> unsigned int l;
> - int k, j;
> + int k, j, us, pu, len;
>
> sep = strchr(name, ':');
> if (sep == NULL)
> @@ -278,9 +278,21 @@ hid_parse_usage_in_page(const char *name
> return -1;
> found:
> sep++;
> - for (j = 0; j < pages[k].pagesize; j++)
> + for (j = 0; j < pages[k].pagesize; j++) {
> + us = pages[k].page_contents[j].usage;
> + if (us == -1) {
> + fmtname = pages[k].page_contents[j].name;
> + fmtsep = strchr(fmtname, '%');
> + len = fmtsep - fmtname;
> + if (fmtsep != NULL && strncmp(sep, fmtname, len) == 0) {
> + pu = strtonum(sep + len, 0x1, 0xFFFF, &errstr);
> + if (errstr == NULL)
> + return (pages[k].usage << 16) | pu;
> + }
> + }
> if (strcmp(pages[k].page_contents[j].name, sep) == 0)
> return (pages[k].usage << 16) |
> pages[k].page_contents[j].usage;
> + }
> return -1;
> }