Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a bunch of sanity checks #696

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

Megamouse
Copy link
Contributor

Some of these changes are meant to fix a couple of warnings while reading the code.
I also noticed that there were almost no sanity checks in the code, which may lead to lots of segfaults in user code.

  • Win: Do not call CloseHandle in hid_open_path if device_handle is null
  • Win: return errors if malloc calls fail
  • Add missing NULL checks to many parameters

libusb/hid.c Outdated Show resolved Hide resolved
libusb/hid.c Outdated Show resolved Hide resolved
libusb/hid.c Outdated Show resolved Hide resolved
libusb/hid.c Outdated Show resolved Hide resolved
linux/hid.c Outdated Show resolved Hide resolved
@@ -318,11 +324,17 @@ static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR

static void register_winapi_error(hid_device *dev, const WCHAR *op)
{
if (!dev)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functions like this are used only internally
is it even possible accidentally pass an invalid dev here? I'm pretty sure if the user passes an invalid or NULL dev into any of the hid_* functions - there woud be an undefined behavior (crash) way before we get here in most places...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, I didn't discriminate when I added these.
In my opinion there shouldn't be any function without sanity checks.
It's not unthinkable that this was possible before I added the other checks after all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion there shouldn't be any function without sanity checks.

That is actually debatable. Most of the checks in this PR are actually do more harm then help.
See my other comment below.

linux/hid.c Outdated Show resolved Hide resolved
@Megamouse
Copy link
Contributor Author

I think I made all the necessary changes.

@mcuee mcuee added macOS Related to macOS backend hidraw Related to Linux/hidraw backend libusb Related to libusb backend Windows Related to Windows backend labels Sep 26, 2024
libusb/hid.c Outdated
@@ -546,8 +558,10 @@ static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_devic
get_usage(hid_report_descriptor, res, &page, &usage);
}

cur_dev->usage_page = page;
cur_dev->usage = usage;
if (cur_dev) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

early return here as well - it doesn't make sense to call this function with NULL cur_dev at all

windows/hid.c Outdated Show resolved Hide resolved
linux/hid.c Outdated
Comment on lines 1386 to 1409
if (!dev)
return -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all public API (specifically functions that accept hid_device * as first argument):

  • do not make sens to call with non-valid dev
  • should register an error string in case if anything goes wrong, so the user could use hid_error to check what went wrong in case if -1 is returned

I do not support having this checks for all public API functions (marked with HID_API_CALL/HID_API_EXPORT_CALL).
We always assume that the dev should be valid, and that is up to the user to make sure it is. (It is fairly easy to implement in other languages that wrap this library w/o any additional runtime checks by using e.g. class invariant).
The only exception is hid_close function - similar to free it should gracefully accept NULL-device.

All other functions the accept hid_device * as an argument called from public API function should use the same assumption, that the dev is valid and doesn't require extra checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that most of these functions already have sanity checks including hid_error for other parameters, I kept the checks and added report_global_error calls.

Comment on lines +1621 to +1630
if (!dev) {
register_global_error(L"Device is NULL");
return -1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is 100% not a supported scenario and should not be handled explicitly in such way
pieces like this create too much "noise/distraction" in the code that actually makes the overall implementation worse than better

please revert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you'd rather have a hard crash on this than an error that the user can actually catch...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me rephrase that (and that is not only my opinion, but rather shared experience of many developers/projects I've seen):
if I as a user messed up some implementation - I'd rather get a crash immediately (and have a chance to fix it immediatelly), that a silent error (often hidden due to lack of error-handling code) which is missed and then the real problem (the one that affects some business scenarios on your application) hits later when something slightly changed in a different part of my application.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can remove it then. Although I would probably have to double check if there isn't an unguarded call to this.
I can make a separate PR with the obvious changes that don't need discussion (like the malloc ptr checks).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make a separate PR with the obvious changes that don't need discussion (like the malloc ptr checks).

Great idea, lets start with that.

@Youw
Copy link
Member

Youw commented Oct 1, 2024

NOTE: in #698 I've added some of those

@Megamouse Megamouse force-pushed the master branch 4 times, most recently from df576f8 to df2d4d0 Compare October 3, 2024 22:13
@Megamouse
Copy link
Contributor Author

If you tell me what to keep and what to remove I can adjust this soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hidraw Related to Linux/hidraw backend libusb Related to libusb backend macOS Related to macOS backend Windows Related to Windows backend
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants