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

Fix strto* usage by setting errno before-hand and interpreting EINVAL properly #4598

Closed
wants to merge 3 commits into from

Conversation

kevans91
Copy link
Contributor

For glibc, the previous usage of these things all worked. As pointed out in #4597, these are not POSIXly correct invocations. (See the first two comments for a description of the problem and further diagnosis)

Further examination after issue #4597 revealed that not all invocations were incorrect; some were assumed to be on numeric strings and thus didn't check errno, while others were properly setting errno beforehand. This PR adds more errno resets and fixes the two instances of not accepting EINVAL that existed in the cmdline parsing.

I wrote a small Coccinelle patch (available here [1]) to find some of these, while others I found by hand. My Coccinelle skills suck, though, so I ended up with some false positives that I had to correct.

[1] https://people.freebsd.org/~kevans/freerdp-strto.cocci

EINVAL may be returned when a conversion cannot be performed. We should still go
on to try and validate the value as a string-option, if it's one of those kinds
of options.
@freerdp-bot
Copy link

Can one of the admins verify this patch?

Copy link
Member

@akallabeth akallabeth left a comment

Choose a reason for hiding this comment

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

I see the error, but having variables declared mid code will break older compilers

@akallabeth akallabeth added this to the 2.0.0 milestone Apr 27, 2018
…ng errno

Leave the declarations behind at the beginning of scope so we can reset errno
just before calling the strto* functions without breaking older compilers.
@kevans91
Copy link
Contributor Author

@akallabeth Thanks! I've corrected all instances of mid-scope declaration, I believe.

type = strtol(arg->Value, &pEnd, 10);

if (errno != 0)
if ((errno != 0) && (errno != EINVAL))
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems simpler to check against known string values first and use number conversion as a fallback. That way EINVAL doesn't need to be excluded, so something like "invalid" won't be treated as "none".

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 wasn't aiming to make any functional changes here- just to make it work with a more POSIX-compliant (in this regard) libc.

I can make this change if you'd like, though- the original submitter of the previously mentioned issue had a patch that also validated type before it was later passed to a function in case it failed both numeric parsing and wasn't one of the present values, but I had intentionally left that out as I considered it ESCOPE for the moment.

unsigned long val = strtoul(&p[1], NULL, 0);
unsigned long val;
errno = 0;
val = strtoul(&p[1], NULL, 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest to introduce wrapper around strtoul() instead, something like:
BOOL parse_ulong(const char* str, unsigned long* result);
That way errno handling can be kept in one place.

@@ -659,6 +659,7 @@ get_elf_hwcap_from_proc_cpuinfo(const char* cpuinfo, int cpuinfo_len)

if (cpuArch)
{
errno = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

No one is checking "errno" after "strtol" here.

@@ -454,6 +454,7 @@ static BOOL http_response_parse_header_status_line(HttpResponse* response, char*
if ((errno != 0) || (val < 0) || (val > INT16_MAX))
return FALSE;

errno = 0;
response->StatusCode = strtol(status_code, NULL, 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

It should be "response->StatusCode = val;" instead, "status_code" was already parsed into "val" on line 452.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I didn't apply any thought to whether the context made any sense- this was kind of a low priority for me as we're preparing for an upcoming release over in our world. =) ETIME, as it goes. =(

Copy link
Member

Choose a reason for hiding this comment

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

Oh, missed that one, thx for pointing that out @p-pautov

Copy link
Member

@akallabeth akallabeth left a comment

Choose a reason for hiding this comment

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

LGTM

@akallabeth
Copy link
Member

@freerdp-bot test

@freerdp-bot
Copy link

Refer to this link for build results (access rights to CI server needed):
https://ci.freerdp.com//job/PullRequestTester/2851/

@@ -454,6 +454,7 @@ static BOOL http_response_parse_header_status_line(HttpResponse* response, char*
if ((errno != 0) || (val < 0) || (val > INT16_MAX))
return FALSE;

errno = 0;
response->StatusCode = strtol(status_code, NULL, 0);
Copy link
Member

Choose a reason for hiding this comment

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

Oh, missed that one, thx for pointing that out @p-pautov

@akallabeth
Copy link
Member

@kevans91 Thank you for your contribution, I've created #4610 to simplify your changes.
We do not want to reset errno unnecessarily (that might hide issues in the library)

@akallabeth akallabeth closed this May 2, 2018
@akallabeth akallabeth removed this from the 2.0.0 milestone May 2, 2018
@kevans91 kevans91 deleted the strtofix branch May 2, 2018 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants