Skip to content

Update the rcutils_find* APIs to return SIZE_MAX on invalid arguments.#74

Merged
clalancette merged 6 commits intomasterfrom
find-size-max
Nov 27, 2017
Merged

Update the rcutils_find* APIs to return SIZE_MAX on invalid arguments.#74
clalancette merged 6 commits intomasterfrom
find-size-max

Conversation

@clalancette
Copy link
Copy Markdown
Contributor

Signed-off-by: Chris Lalancette clalancette@openrobotics.org

fixes #58

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
@clalancette clalancette added in progress Actively being worked on (Kanban column) in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Nov 21, 2017
Copy link
Copy Markdown
Member

@dhood dhood left a comment

Choose a reason for hiding this comment

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

there's inconsistency when the string is valid but empty. In most cases string_length is returned if the delimiter is not found, but in the case of "" as the input string, SIZE_MAX is being returned when the delimiter is not found. from #58 it sounds like SIZE_MAX should be returned in all cases

src/find.c Outdated
{
if (!str) {
return 0;
if (!str || strlen(str) == 0) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this change makes sense for findn or find_lastn below because it accepts strings that aren't null terminated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah, you are definitely right about that. That should be a check if string_length == 0. I'll fix that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: please use 0 == string_length when updating

@dhood
Copy link
Copy Markdown
Member

dhood commented Nov 21, 2017

btw if we update to return SIZE_MAX whenever the delimiter is not found, usage such as

size_t chars_to_start_delim = rcutils_find(str + i, token_start_delimiter);
will have to be updated

@mikaelarguedas
Copy link
Copy Markdown
Member

mikaelarguedas commented Nov 21, 2017

Dismissing my review, and +1ing both @dhood's review about non-null terminated strings.

btw if we update to return SIZE_MAX whenever the delimiter is not found, usage such as

It looks to me that this returns SIZE_MAX only if the provided string is invalid. It will return the length of the string if it's not found so this code doesn't need to be updated.

But it raises the question of "Should it return SIZE_MAX in both the case where the input string is invalid and the one where the deimiter is not found?"

Covered by previous review

@clalancette
Copy link
Copy Markdown
Contributor Author

there's inconsistency when the string is valid but empty. In most cases string_length is returned if the delimiter is not found, but in the case of "" as the input string, SIZE_MAX is being returned when the delimiter is not found. from #58 it sounds like SIZE_MAX should be returned in all cases

That was sort of intentional; I was trying to make it so that you could determine whether the inputs were valid (SIZE_MAX if not), and whether you found the delimiter (offset of the delimiter, or length of entire string if not). Now that you mention it, though, an "empty" string could be considered a special case of "can't find delimiter". I'll take another look and see what happens if we change to returning SIZE_MAX for can't find delimiter, in all cases.

btw if we update to return SIZE_MAX whenever the delimiter is not found, usage such as

rcutils/src/logging.c

Line 473 in 77a7e9e
size_t chars_to_start_delim = rcutils_find(str + i, token_start_delimiter);
will have to be updated

So I actually did audit these callers. I opted not to make any changes in both of those cases in src/logging.c, mostly because the case where it returns SIZE_MAX is handled already for both of them. In particular, in both cases there is an if statement dealing with where the size is larger than what is left, and they both do the "correct" thing in that case. Maybe I should add a comment in those places; what do you think?

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
In particular, have it go looking from the end, not the
beginning, which will cause it to get out early once it has
found something.  Note that we have to have a separate check
for the 0th element, since we can't do a <= 0 inside of the
for loop with an unsigned variable.

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
@clalancette
Copy link
Copy Markdown
Contributor Author

It looks like it is reasonable to use SIZE_MAX for all cases of "not found", so I've changed to that. Let me know what you think.

size_t ret0 = test_findn("", '/', 0, 0);
LOG((size_t)0, ret0);
size_t ret0 = test_findn("", '/', 0, SIZE_MAX);
LOG((size_t)SIZE_MAX, ret0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the size_t casts are unnecessary here and below now yeah?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, for the SIZE_MAX checks, that's probably right. I'll make that fix and submit a CI just to be sure.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wasn't aware of this but judging from the warnings on OS X SIZE_MAX may not fit into size_t.. this probably means we'll need to reconsider the return type of the find functions if we want to take this approach

Copy link
Copy Markdown
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 aware of this but judging from the warnings on OS X SIZE_MAX may not fit into size_t.. this probably means we'll need to reconsider the return type of the find functions if we want to take this approach

Arg, that is annoying. I'll do a little more investigating to see what I can find here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see what is going on. The warning that clang is throwing is very misleading. On x86_64 macOS, size_t is a long unsigned int, which is 64-bit unsigned. SIZE_MAX is an unsigned long long, which is also 64-bit unsigned. The problem is that the LOG statement is using %zu to print out the values, and an unsigned long long is not technically a size_t, even though they are compatible. The solution is to make sure we still cast SIZE_MAX to a size_t before passing it to LOG (like what was there before). I'll fix that, and put a comment in there for the next hapless soul who tries to remove it.

@dhood
Copy link
Copy Markdown
Member

dhood commented Nov 21, 2017

In particular, in both cases there is an if statement dealing with where the size is larger than what is left, and they both do the "correct" thing in that case.

Yep you're right (I think I'd remembered they'd have issues if we returned -1 when it was originally suggested, but they are indeed good as is)

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
@clalancette
Copy link
Copy Markdown
Contributor Author

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Otherwise, macOS complains.

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
@clalancette
Copy link
Copy Markdown
Contributor Author

Another try on CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@clalancette
Copy link
Copy Markdown
Contributor Author

Thanks everyone for the reviews. I'm going to merge this now.

@clalancette clalancette merged commit 094f384 into master Nov 27, 2017
@clalancette clalancette deleted the find-size-max branch November 27, 2017 17:39
@clalancette clalancette removed the in review Waiting for review (Kanban column) label Nov 27, 2017
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.

find() and find_last() functions return ambiguous value

4 participants