On 29/05/18(Tue) 22:29, David Bern wrote:
> Sorry for the spamming.
> After some research and finding that my fix for issue nr: 2 (
> hid_usage_in_page() )
> will break the functionality inside /usr.bin/usbhidaction/usbhidaction.c
> https://goo.gl/1cWFtR (link to usbhidaction.c)
> 
> I now change my patch to only include a fix for issue nr: 1
> More details is described in the previous mail

Are you sure the name always contain an underscore?  Can't it be
"Button:Button42" ?

You're passing the string directly to sscanf(3), is that safe?

Don't you want to parse only unsigned numbers?  Or is it possible to
have "Button:Button_-3" ?

> 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     29 May 2018 19:45:25 -0000
> @@ -265,8 +265,9 @@ int
>  hid_parse_usage_in_page(const char *name)
>  {
>         const char *sep;
> +       const char *usage_sep;
>         unsigned int l;
> -       int k, j;
> +       int k, j, us, parsed_usage;
> 
>         sep = strchr(name, ':');
>         if (sep == NULL)
> @@ -278,9 +279,19 @@ 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) {
> +                       usage_sep = strchr(sep, '_');
> +                       if (usage_sep == NULL)
> +                               return -1;
> +                       if (sscanf(usage_sep, "_%d", &parsed_usage))
> +                               return (pages[k].usage << 16) |
> +                                   parsed_usage;
> +               }
>                 if (strcmp(pages[k].page_contents[j].name, sep) == 0)
>                         return (pages[k].usage << 16) |
>                             pages[k].page_contents[j].usage;
> +       }
>         return -1;
>  }
> 
> 
> comments? ok?
> 
> 2018-05-28 13:01 GMT+02:00 David Bern <david.ml.b...@gmail.com>:
> 
> > I was suggested off list to give an explanation on what the patch does.
> >
> > So please, tell me if I need to clarify more, or make further changes to
> > the code.
> >
> > The patch tries to fix two things.
> > 1. Changes in hid_parse_usage_in_page() fixes problems in parsing usages
> > defined as:  *       Button %d
> >
> > hid_parse_usage_in_page():
> > Previously - With input "Button:Button_1" returns -1
> > Now - With input "Button:Button_1" returns 589825
> >
> > In the scenario of parsing Button:Button_1 we will not find a usage name
> > matching that string. For example Button:Button_1 is defined as
> > Button %d in the table.
> >
> > We are still able to calculate the proper usage number in the same way we
> > are
> > able to calculate the proper usage name in hid_usage_in_page().
> >
> > The first step is to identify if usage name is shortened. If it is,
> > usage will hold a value of -1. Then I try to locate a separator char in
> > the name as "_".
> > If a separator char is found I use it to read the value as "_%d" to get
> > the
> > corresponding usage number
> >
> > >+               us = pages[k].page_contents[j].usage;
> > >+               if (us == -1) {
> > >+                       usage_sep = strchr(sep, '_');
> > >+                       if (usage_sep == NULL)
> > >+                               return -1;
> > >+                       if (sscanf(usage_sep, "_%d", &parsed_usage))
> > >+                               return (pages[k].usage << 16) |
> > >+                                               parsed_usage;
> >
> >
> > 2. The text-string that is returned by hid_usage_in_page() misses page
> > information.
> > So the changes made in hid_usage_in_page() is to make it the inverse of
> > hid_parse_usage_in_page()
> >
> > In details what the code previously did and now does.
> >
> > hid_usage_in_page():
> > Previously - With input 589825 returns Button_1
> > Now - With input 589825 returns Button:Button_1
> >
> >
> > The change just adds a pages[k].name to the string, a format that
> > hid_parse_usage_in_page() expects it to have.
> > I make formatting in two steps when us == -1 which it is when usage is
> > shortened
> > as for example: *       Button %d.
> >
> > >+                       snprintf(fmt, sizeof fmt,
> > >+                           "%%s:%s", pages[k].page_contents[j].name);
> > >+                       snprintf(b, sizeof b, fmt, pages[k].name, i);
> >
> > The first step is to create a format string that will result in something
> > like
> >  "%s:Button_%d".
> > The last step I use the fmt-string to create a complete string that will
> > result in
> > "Button:Button_1"
> >
> >
> >
> >
> > 2018-05-24 18:44 GMT+02:00 David Bern <david.ml.b...@gmail.com>:
> >
> >> While I was waiting for comments and feedback I came up with some
> >> improvements.
> >> The "logic" is still the same, but the execution is hopefully more sane.
> >>
> >> 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     24 May 2018 16:37:54 -0000
> >> @@ -224,6 +224,7 @@ hid_usage_in_page(unsigned int u)
> >>  {
> >>         int i = HID_USAGE(u), j, k, us;
> >>         int page = HID_PAGE(u);
> >> +       char fmt[100];
> >>         static char b[100];
> >>
> >>         for (k = 0; k < npages; k++)
> >> @@ -234,12 +235,16 @@ hid_usage_in_page(unsigned int u)
> >>         for (j = 0; j < pages[k].pagesize; j++) {
> >>                 us = pages[k].page_contents[j].usage;
> >>                 if (us == -1) {
> >> -                       snprintf(b, sizeof b,
> >> -                           pages[k].page_contents[j].name, i);
> >> +                       snprintf(fmt, sizeof fmt,
> >> +                           "%%s:%s", pages[k].page_contents[j].name);
> >> +                       snprintf(b, sizeof b, fmt, pages[k].name, i);
> >> +                       return b;
> >> +               }
> >> +               if (us == i) {
> >> +                       snprintf(b, sizeof b, "%s:%s", pages[k].name,
> >> +                           pages[k].page_contents[j].name);
> >>                         return b;
> >>                 }
> >> -               if (us == i)
> >> -                       return pages[k].page_contents[j].name;
> >>         }
> >>   bad:
> >>         snprintf(b, sizeof b, "0x%04x", i);
> >> @@ -265,8 +270,9 @@ int
> >>  hid_parse_usage_in_page(const char *name)
> >>  {
> >>         const char *sep;
> >> +       const char *usage_sep;
> >>         unsigned int l;
> >> -       int k, j;
> >> +       int k, j, us, parsed_usage;
> >>
> >>         sep = strchr(name, ':');
> >>         if (sep == NULL)
> >> @@ -278,9 +284,19 @@ 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) {
> >> +                       usage_sep = strchr(sep, '_');
> >> +                       if (usage_sep == NULL)
> >> +                               return -1;
> >> +                       if (sscanf(usage_sep, "_%d", &parsed_usage))
> >> +                               return (pages[k].usage << 16) |
> >> +                                               parsed_usage;
> >> +               }
> >>                 if (strcmp(pages[k].page_contents[j].name, sep) == 0)
> >>                         return (pages[k].usage << 16) |
> >>                             pages[k].page_contents[j].usage;
> >> +       }
> >>         return -1;
> >>  }
> >>
> >>
> >>
> >> 2018-05-21 23:12 GMT+02:00 David Bern <david.ml.b...@gmail.com>:
> >>
> >>> First diff "solves" point 1 & 2. Second diff is on the parts of the
> >>> manual that does not match the usbhid.h
> >>>
> >>> 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     21 May 2018 21:06:24 -0000
> >>> @@ -224,6 +224,7 @@ hid_usage_in_page(unsigned int u)
> >>>  {
> >>>         int i = HID_USAGE(u), j, k, us;
> >>>         int page = HID_PAGE(u);
> >>> +       char usage_name[100];
> >>>         static char b[100];
> >>>
> >>>         for (k = 0; k < npages; k++)
> >>> @@ -234,12 +235,18 @@ hid_usage_in_page(unsigned int u)
> >>>         for (j = 0; j < pages[k].pagesize; j++) {
> >>>                 us = pages[k].page_contents[j].usage;
> >>>                 if (us == -1) {
> >>> -                       snprintf(b, sizeof b,
> >>> +                       snprintf(usage_name, sizeof usage_name,
> >>>                             pages[k].page_contents[j].name, i);
> >>> +                       snprintf(b, sizeof b,
> >>> +                           "%s:%s", pages[k].name, usage_name);
> >>> +                       return b;
> >>> +               }
> >>> +               if (us == i) {
> >>> +                       snprintf(b, sizeof b,
> >>> +                           "%s:%s", pages[k].name,
> >>> +                           pages[k].page_contents[j].name);
> >>>                         return b;
> >>>                 }
> >>> -               if (us == i)
> >>> -                       return pages[k].page_contents[j].name;
> >>>         }
> >>>   bad:
> >>>         snprintf(b, sizeof b, "0x%04x", i);
> >>> @@ -265,8 +272,9 @@ int
> >>>  hid_parse_usage_in_page(const char *name)
> >>>  {
> >>>         const char *sep;
> >>> +       const char *usage_sep;
> >>>         unsigned int l;
> >>> -       int k, j;
> >>> +       int k, j, us, parsed_usage;
> >>>
> >>>         sep = strchr(name, ':');
> >>>         if (sep == NULL)
> >>> @@ -277,10 +285,20 @@ hid_parse_usage_in_page(const char *name
> >>>                         goto found;
> >>>         return -1;
> >>>   found:
> >>> +       usage_sep = strchr(sep, '_');
> >>>         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) {
> >>> +                       if (usage_sep == NULL)
> >>> +                               return -1;
> >>> +                       if (sscanf(usage_sep, "_%d", &parsed_usage))
> >>> +                               return (pages[k].usage << 16 |
> >>> +                                               parsed_usage);
> >>> +               }
> >>>                 if (strcmp(pages[k].page_contents[j].name, sep) == 0)
> >>>                         return (pages[k].usage << 16) |
> >>>                             pages[k].page_contents[j].usage;
> >>> +       }
> >>>         return -1;
> >>>  }
> >>>
> >>> Index: usbhid.3
> >>> ===================================================================
> >>> RCS file: /cvs/src/lib/libusbhid/usbhid.3,v
> >>> retrieving revision 1.17
> >>> diff -u -p -r1.17 usbhid.3
> >>> --- usbhid.3    13 May 2014 14:05:02 -0000      1.17
> >>> +++ usbhid.3    21 May 2018 21:02:21 -0000
> >>> @@ -65,22 +65,22 @@
> >>>  .Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int id"
> >>>  .Ft int
> >>>  .Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k"
> >>> "hid_item_t *h" "int id"
> >>> -.Ft char *
> >>> +.Ft const char *
> >>>  .Fn hid_usage_page "int i"
> >>> -.Ft char *
> >>> +.Ft const char *
> >>>  .Fn hid_usage_in_page "u_int u"
> >>>  .Ft int
> >>>  .Fn hid_parse_usage_page "const char *"
> >>> -.Ft char *
> >>> +.Ft int
> >>>  .Fn hid_parse_usage_in_page "const char *"
> >>>  .Ft void
> >>>  .Fn hid_init "char *file"
> >>>  .Ft int
> >>>  .Fn hid_start "char *file"
> >>> -.Ft int
> >>> +.Ft int32_t
> >>>  .Fn hid_get_data "void *data" "hid_item_t *h"
> >>>  .Ft void
> >>> -.Fn hid_set_data "void *data" "hid_item_t *h" "u_int data"
> >>> +.Fn hid_set_data "void *data" "hid_item_t *h" "int32_t data"
> >>>  .Sh DESCRIPTION
> >>>  The
> >>>  .Nm
> >>>
> >>>
> >>>
> >>> 2018-05-21 12:07 GMT+02:00 Martin Pieuchot <m...@openbsd.org>:
> >>>
> >>>> On 18/05/18(Fri) 10:01, David Bern wrote:
> >>>> > Hello!
> >>>> >
> >>>> > Have been using libusbhid and discovered a couple of discrepancies in
> >>>> > the man-page (libusbhid.3) and the source of usage.c
> >>>> >
> >>>> > Some are just factual misses, but I also got (what I think is) 2
> >>>> errors.
> >>>> > I will try to explain them;
> >>>> >
> >>>> > 1. (This is the I think is an error but not sure). The man-page tells
> >>>> me
> >>>> > that hid_usage_in_page and hid_parse_usage_in_page are each
> >>>> > others inverse.
> >>>> > If I haven't misunderstood the practical meaning of inverse in this
> >>>> > case then this should be true:
> >>>> > x == hid_parse_usage_in_page(hid_usage_in_page(x)).
> >>>> >
> >>>> > My observation:
> >>>> > The main reason to why this isnt true, is that hid_usage_in_page()
> >>>> > returns the data of pages[k].page_contents[j].name
> >>>> > while hid_parse_usage_in_page() expects the data to
> >>>> > contain "%s:%s", pages[k].name, pages[k].page_contents[j].name
> >>>> >
> >>>> > The reason I ask instead of just posting working code is this:
> >>>> > Am I misunderstanding the manual? In that case, the solution I want
> >>>> > to send in is a change in that sentence
> >>>> > Or Is the manual correct and the behavior of hid_usage_in_page()
> >>>> wrong,
> >>>> > is this something I can correct without breaking other systems?
> >>>> >
> >>>> >
> >>>> > 2. The second error I found is located in hid_parse_usage_in_page().
> >>>> > It is unable to parse values found in page Button.
> >>>> >
> >>>> > My observation:
> >>>> > usage.c is using a standard table named usb_hid_pages. In that table
> >>>> > we got a page called Buttons.
> >>>> > the usages in that page is shortened to "*  Button %d".
> >>>> > I believe this is the cause of why hid_parse_usage_in_page() is
> >>>> getting
> >>>> > the pagesize "wrong" and therefor unable to parse any button in the
> >>>> > button page. I guess this is the case with other similar cases as
> >>>> well.
> >>>> >
> >>>> > my conclusion is that it would be possible to handle similar cases in
> >>>> a
> >>>> > similar way as it is handled in hid_usage_in_page().
> >>>> >
> >>>> >
> >>>> > As this is my first "issue" I would love to get as much feedback as
> >>>> > possible so I can work on delivering a desirable and usable patch in
> >>>> > my first try.
> >>>>
> >>>> Just send a diff, then we'll look at it 8)
> >>>>
> >>>
> >>>
> >>
> >

Reply via email to