Consider the following snippet within php_url_decode_ex() at ext/standard/url.c, called from PHPs urldecode() function:
According to the C11 specification, isxdigit()'s (and all other ctype.h functions') only argument is of type int, and any value passed to it must be representable by unsigned char, i.e. 0-255.
§7.4:
The header declares several functions useful for classifying and mapping characters. In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.
On platforms where plain char is signed (which is most), passing a char with a value <0 to int (or casting to int explicitly as in this case) will lead to signed integer extension, leading to a negative int value. Instead, the char value should be cast to unsigned char, so that no sign extension occurs.
Most platforms account for this common mistake. However, on NetBSD passing negative values to isxdigit() lead to an out-of-bounds read, leading to a segfault.
urldecode("%\x80");