> From: openssl-users [mailto:openssl-users-boun...@openssl.org] On Behalf Of
> Dennis Clarke
> Sent: Thursday, January 17, 2019 18:23
>
> "crypto/objects/o_names.c", line 114: error: undefined symbol: strcasecmp
> "crypto/objects/o_names.c", line 114: warning: improper pointer/integer
> combination: op "="
> "crypto/objects/o_names.c", line 151: warning: implicit function
> declaration: strcasecmp

Note the issue here is an undefined symbol, which consequently has an implicit 
definition as an int with external linkage and static duration. So we're 
talking about a header problem, not a library problem.

> So would love to hear someones thoughts on why strcasecmp suddenly went
> missing?

Well...

strcasecmp is a heresy. The C specification (ISO 9899) does not include 
strcasecmp, and reserves all identifiers with external linkage beginning with 
"str" for the library.

The *correct* way to do case-insensitive string comparisons in C is to write 
your own using the ctype.h functions (though it's tricky to get this right, due 
to the signed-char Undefined Behavior problem), with a name that doesn't 
infringe on a reserved part of the namespace. Or use a library which provides 
the same.

Unfortunately, strcasecmp was invented before C was standardized (as part of 
the BSD 4.something implementation, maybe?), and consequently gained too much 
traction to ever go away. Then it was standardized by XPG4, just to make things 
more difficult. And thus it's part of the Single UNIX Specification, even 
though the SUS has language about not conflicting with ISO 9899. Everyone just 
looks the other way and whistles quietly to themselves when they come across it.

*Consequently*, under Open Group Base Specifications Issue 7 (the latest 
version of SUS), to get a definition for strcasecmp you have to include 
<strings.h>. Note the second "s". <string.h> is the ISO C header for things 
like strcmp; <strings.h> is the SUS header for strcasecmp and other 
look-like-standard-C-but-aren't string functions. There's no way anyone would 
ever confuse the two.

Normally, the Solaris headers (at least for 10.2, which is what I'm logged into 
at the moment) include string.h in strings.h and vice versa, to hide this 
abomination from the eyes of the innocent. But those inclusions are wrapped in 
all manner of ifdeffery which I am not about to try to untangle.

Now, we see in the output you included in your note that you are getting 
strings.h in o_names.c. So that should be OK, yes?

But of course the declaration of strcasecmp in strings.h is itself ifdeffed. To 
get it, _XPG4_2 must be defined, and __EXTENSIONS__ must NOT be defined.

My guess is you're falling foul of one of those two conditions, when you 
compile in strict mode.

The simplest fix would be to whack a declaration of strcasecmp into the source 
file itself, but that's inelegant and hard to maintain - presumably you'd 
rather do something through the OpenSSL configure process. As for that, well... 
the only thing that comes to mind is something like:

1. Add -Dstrcasecmp=cmpstrci to the compiler flags
2. Add -lcmpstrci to the link flags
3. Create a little libcmpstrci.a (no need for it to be a shared object) with a 
case-insensitive string comparison function named cmpstrci. It can use 
strcasecmp if it must, or you can implement your own.

Or the problem might be something else, of course, but the fact that strings.h 
does appear in the output but strcasecmp isn't declared does suggest the 
conditional-compilation in strings.h is to blame.

--
Michael Wojcik
Distinguished Engineer, Micro Focus


-- 
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

Reply via email to