Skip to content

Comments

fix test_strn_ne handling of differing lengths#29390

Closed
TharakaUJ wants to merge 1 commit intoopenssl:masterfrom
TharakaUJ:master
Closed

fix test_strn_ne handling of differing lengths#29390
TharakaUJ wants to merge 1 commit intoopenssl:masterfrom
TharakaUJ:master

Conversation

@TharakaUJ
Copy link

test_strn_ne() incorrectly reported equality when the comparison lengths differed. Treat differing n values as not equal, matching the intended semantics.

CLA: trivial

Fixes #23386

@slontis
Copy link
Member

slontis commented Dec 14, 2025

I would expect some test case(s) in test/test.c showing expected behaviour.

@paulidale
Copy link
Contributor

The fix is more complicated. The strings could be short and still equal as per strncmp(3). E.g. strncmp("abc", "abc", 10).

A better fix is:

if ((s1 == NULL) ^ (s2 == NULL))
    return 1;
if (s1 == NULL) {
    test_fail_string_message(NULL, file, line, "string", st1, st2, "!=", NULL, 0, NULL, 0);
    return 0;
}

if (strncmp(s1, s2, n1 > n2 ? n2 : n1) == 0) {
    test_fail_string_message(NULL, file, line, "string", st1, st2, "!=",
                             s1, OPENSSL_strnlen(s1, n1),
                             s2, OPENSSL_strnlen(s2, n2));
    return 0;
}
return 1;

Still, I think that this test is broken. Two lengths just doesn't make any sense. There should only be one length passed in being the length to be passed to strncmp.

The _ne version is not currently used and the _eq is only called in one place where the lengths differ (test_text in test/endecode_test.c).

My suggestion would be to make both functions only take one length argument and to fix the one caller.

@TharakaUJ
Copy link
Author

TharakaUJ commented Dec 15, 2025

I’ve added some test cases to cover the edge scenarios discussed.

I didn’t change test_strn_eq because in its only usage context, it seems to behave as expected. I fixed test_strn_ne as requested, and I believe it is now correct.

I also realized that test_strn_ne will fail a test if the two strings are equal up to the shorter length, even if they differ later. I think that makes sense: from the test function’s point of view, the behavior beyond the shorter length is undefined, so failing in that case is acceptable.

I also noticed that test_strn_eq != !test_strn_ne currently. If needed, I can update test_strn_eq so that it is fully consistent with test_strn_ne. Let me know if you want me to do that and how you would like the test case results to behave.

Also thank you for the support!

@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Dec 15, 2025
Update test_strn_ne() to compare strings only up to the shorter length
when the provided length parameters differ. The test now correctly fails
when the strings differ within that range.
Tests covering edge cases are added.

CLA: trivial
@@ -320,7 +320,7 @@ int test_strn_ne(const char *file, int line, const char *st1, const char *st2,
{
if ((s1 == NULL) ^ (s2 == NULL))
return 1;
if (n1 != n2 || s1 == NULL || strncmp(s1, s2, n1) == 0) {
if (s1 == NULL || strncmp(s1, s2, n1 > n2 ? n2 : n1) == 0) {
Copy link
Contributor

@jogme jogme Jan 13, 2026

Choose a reason for hiding this comment

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

I'm still not convinced this is a useful change. When the two lengths are not equal, then the strings are not equal. Do you have a specific use case for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

For strncmp(3) this isn't necessarily true. IMO, this was a poorly chosen API. It should either have had a single length parameter or three (one each for the buffer sizes and a third for the comparison length).

I suggest that, instead of trying to fix this, the API be redesigned with more reasonable arguments. The two length comparisons are only used in two places and then on the _eq falvour is called. I.e. drop TEST_strn2_ne since it's unused. This solves the problematic case complete. We could also drop TEST_strn_ne which is also unused and then remove this function entirely. If we don't drop TEST_strn_ne, we should change this function to only accept a single length argument.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant it for the n1 != n2 but yes, I agree

@paulidale paulidale mentioned this pull request Jan 13, 2026
2 tasks
@paulidale
Copy link
Contributor

I've done an alternative in #29627 that solves this problem by dropping the second length argument.

@paulidale
Copy link
Contributor

Given that the alternative PR has the required approvals, I'm going to close this one.
Despite this, thanks for the submission. It provoked some interesting discussions.

@paulidale paulidale closed this Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity: fips change The pull request changes FIPS provider sources

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug in test_strn_ne

4 participants