Cleanup handling of non-standard functions in lwIP

- itoa
- strnicmp, stricmp/strcasecmp
- strnstr
Related to patch #9115: httpd.c: strcasecmp for GCC and stricmp for Windows
This commit is contained in:
Dirk Ziegelmeier 2016-09-28 21:52:11 +02:00
parent f8d19e28de
commit 1f68b32485
8 changed files with 146 additions and 199 deletions

View File

@ -337,82 +337,6 @@ char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each ext
static struct http_state *http_connections;
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
#if LWIP_HTTPD_STRNSTR_PRIVATE
/** Like strstr but does not need 'buffer' to be NULL-terminated */
static char*
strnstr(const char* buffer, const char* token, size_t n)
{
const char* p;
int tokenlen = (int)strlen(token);
if (tokenlen == 0) {
return (char *)(size_t)buffer;
}
for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) {
if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {
return (char *)(size_t)p;
}
}
return NULL;
}
#endif /* LWIP_HTTPD_STRNSTR_PRIVATE */
#if LWIP_HTTPD_STRICMP_PRIVATE
static int
stricmp(const char* str1, const char* str2)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (c1 != 0);
return 0;
}
#endif /* LWIP_HTTPD_STRICMP_PRIVATE */
#if LWIP_HTTPD_ITOA_PRIVATE && LWIP_HTTPD_DYNAMIC_HEADERS
static void
httpd_itoa(int value, char* result)
{
const int base = 10;
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
} while(value);
/* Apply negative sign */
if (tmp_value < 0) {
*ptr++ = '-';
}
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
}
#endif
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
static void
http_kill_oldest_connection(u8_t ssi_required)
@ -964,7 +888,7 @@ get_http_headers(struct http_state *hs, const char *uri)
/* Now determine the content type and add the relevant header for that. */
for (content_type = 0; content_type < NUM_HTTP_HEADERS; content_type++) {
/* Have we found a matching extension? */
if(!stricmp(g_psHTTPHeaders[content_type].extension, ext)) {
if(!lwip_stricmp(g_psHTTPHeaders[content_type].extension, ext)) {
break;
}
}
@ -1012,7 +936,7 @@ get_http_headers(struct http_state *hs, const char *uri)
}
if (add_content_len) {
size_t len;
LWIP_HTTPD_ITOA(hs->hdr_content_len, (size_t)LWIP_HTTPD_MAX_CONTENT_LEN_SIZE,
lwip_itoa(hs->hdr_content_len, (size_t)LWIP_HTTPD_MAX_CONTENT_LEN_SIZE,
hs->handle->len);
len = strlen(hs->hdr_content_len);
if (len <= LWIP_HTTPD_MAX_CONTENT_LEN_SIZE - LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) {
@ -1802,16 +1726,16 @@ http_post_request(struct pbuf *inp, struct http_state *hs,
{
err_t err;
/* search for end-of-header (first double-CRLF) */
char* crlfcrlf = strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data));
char* crlfcrlf = lwip_strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data));
if (crlfcrlf != NULL) {
/* search for "Content-Length: " */
#define HTTP_HDR_CONTENT_LEN "Content-Length: "
#define HTTP_HDR_CONTENT_LEN_LEN 16
#define HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN 10
char *scontent_len = strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1));
char *scontent_len = lwip_strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1));
if (scontent_len != NULL) {
char *scontent_len_end = strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN);
char *scontent_len_end = lwip_strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN);
if (scontent_len_end != NULL) {
int content_len;
char *content_len_num = scontent_len + HTTP_HDR_CONTENT_LEN_LEN;
@ -2020,7 +1944,7 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb)
/* received enough data for minimal request? */
if (data_len >= MIN_REQ_LEN) {
/* wait for CRLF before parsing anything */
crlf = strnstr(data, CRLF, data_len);
crlf = lwip_strnstr(data, CRLF, data_len);
if (crlf != NULL) {
#if LWIP_HTTPD_SUPPORT_POST
int is_post = 0;
@ -2052,11 +1976,11 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb)
}
/* if we come here, method is OK, parse URI */
left_len = (u16_t)(data_len - ((sp1 +1) - data));
sp2 = strnstr(sp1 + 1, " ", left_len);
sp2 = lwip_strnstr(sp1 + 1, " ", left_len);
#if LWIP_HTTPD_SUPPORT_V09
if (sp2 == NULL) {
/* HTTP 0.9: respond with correct protocol version */
sp2 = strnstr(sp1 + 1, CRLF, left_len);
sp2 = lwip_strnstr(sp1 + 1, CRLF, left_len);
is_09 = 1;
#if LWIP_HTTPD_SUPPORT_POST
if (is_post) {
@ -2069,13 +1993,13 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb)
uri_len = (u16_t)(sp2 - (sp1 + 1));
if ((sp2 != 0) && (sp2 > sp1)) {
/* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */
if (strnstr(data, CRLF CRLF, data_len) != NULL) {
if (lwip_strnstr(data, CRLF CRLF, data_len) != NULL) {
char *uri = sp1 + 1;
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
/* This is HTTP/1.0 compatible: for strict 1.1, a connection
would always be persistent unless "close" was specified. */
if (!is_09 && (strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) ||
strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) {
if (!is_09 && (lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) ||
lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) {
hs->keepalive = 1;
} else {
hs->keepalive = 0;
@ -2259,7 +2183,7 @@ http_find_file(struct http_state *hs, const char *uri, int is_09)
}
tag_check = 0;
for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) {
if (!stricmp(ext, g_pcSSIExtensions[loop])) {
if (!lwip_stricmp(ext, g_pcSSIExtensions[loop])) {
tag_check = 1;
break;
}
@ -2334,7 +2258,7 @@ http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const cha
if (is_09 && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) {
/* HTTP/0.9 responses are sent without HTTP header,
search for the end of the header. */
char *file_start = strnstr(hs->file, CRLF CRLF, hs->left);
char *file_start = lwip_strnstr(hs->file, CRLF CRLF, hs->left);
if (file_start != NULL) {
size_t diff = file_start + 4 - hs->file;
hs->file += diff;

View File

@ -265,42 +265,6 @@ struct mdns_answer {
u16_t rd_offset;
};
#ifndef LWIP_MDNS_STRNCASECMP
#define LWIP_MDNS_STRNCASECMP(str1, str2, len) mdns_strncasecmp(str1, str2, len)
/**
* A small but sufficient implementation for case insensitive strncmp.
* This can be defined to e.g. strnicmp for windows or strncasecmp for linux.
*/
static int
mdns_strncasecmp(const char* str1, const char* str2, size_t len)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (len-- && c1 != 0);
return 0;
}
#endif /* LWIP_MDNS_STRNCASECMP */
/**
* Add a label part to a domain
* @param domain The domain to add a label to
@ -460,7 +424,7 @@ mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b)
len = *ptra;
ptra++;
ptrb++;
res = LWIP_MDNS_STRNCASECMP((char *) ptra, (char *) ptrb, len);
res = lwip_strnicmp((char *) ptra, (char *) ptrb, len);
if (res != 0) {
return 0;
}

View File

@ -46,6 +46,7 @@
#if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/udp.h"
#include "lwip/netif.h"
@ -270,7 +271,7 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
/* decode the NetBIOS name */
netbiosns_name_decode((char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
/* if the packet is for us */
if (NETBIOS_STRCMP(netbios_name, NETBIOS_LOCAL_NAME) == 0) {
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
struct pbuf *q;
struct netbios_resp *resp;

View File

@ -102,4 +102,110 @@ lwip_ntohl(u32_t n)
return lwip_htonl(n);
}
#ifndef lwip_strnstr
/** Like strstr but does not need 'buffer' to be NULL-terminated */
char*
lwip_strnstr(const char* buffer, const char* token, size_t n)
{
const char* p;
int tokenlen = (int)strlen(token);
if (tokenlen == 0) {
return (char *)(size_t)buffer;
}
for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) {
if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {
return (char *)(size_t)p;
}
}
return NULL;
}
#endif
#ifndef lwip_stricmp
int
lwip_stricmp(const char* str1, const char* str2)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (c1 != 0);
return 0;
}
#endif
#ifndef lwip_strnicmp
int
lwip_strnicmp(const char* str1, const char* str2, size_t len)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (len-- && c1 != 0);
return 0;
}
#endif
#ifndef lwip_itoa
void
lwip_itoa(int value, char* result)
{
const int base = 10;
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
} while(value);
/* Apply negative sign */
if (tmp_value < 0) {
*ptr++ = '-';
}
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
}
#endif
#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */

View File

@ -80,6 +80,7 @@
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/udp.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
@ -271,40 +272,6 @@ static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
#ifndef LWIP_DNS_STRICMP
#define LWIP_DNS_STRICMP(str1, str2) dns_stricmp(str1, str2)
/**
* A small but sufficient implementation for case insensitive strcmp.
* This can be defined to e.g. stricmp for windows or strcasecmp for linux. */
static int
dns_stricmp(const char* str1, const char* str2)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (c1 != 0);
return 0;
}
#endif /* LWIP_DNS_STRICMP */
/**
* Initialize the resolver: set up the UDP pcb and configure the default server
* (if DNS_SERVER_ADDRESS is set).
@ -441,7 +408,7 @@ dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
struct local_hostlist_entry *entry = local_hostlist_dynamic;
while (entry != NULL) {
if ((LWIP_DNS_STRICMP(entry->name, hostname) == 0) &&
if ((lwip_stricmp(entry->name, hostname) == 0) &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) {
if (addr) {
ip_addr_copy(*addr, entry->addr);
@ -453,7 +420,7 @@ dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_
#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
size_t i;
for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) {
if ((LWIP_DNS_STRICMP(local_hostlist_static[i].name, hostname) == 0) &&
if ((lwip_stricmp(local_hostlist_static[i].name, hostname) == 0) &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) {
if (addr) {
ip_addr_copy(*addr, local_hostlist_static[i].addr);
@ -483,7 +450,7 @@ dns_local_removehost(const char *hostname, const ip_addr_t *addr)
struct local_hostlist_entry *entry = local_hostlist_dynamic;
struct local_hostlist_entry *last_entry = NULL;
while (entry != NULL) {
if (((hostname == NULL) || !LWIP_DNS_STRICMP(entry->name, hostname)) &&
if (((hostname == NULL) || !lwip_stricmp(entry->name, hostname)) &&
((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) {
struct local_hostlist_entry *free_entry;
if (last_entry != NULL) {
@ -572,7 +539,7 @@ dns_lookup(const char *name, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addr
/* Walk through name list, return entry if found. If not, return NULL. */
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
if ((dns_table[i].state == DNS_STATE_DONE) &&
(LWIP_DNS_STRICMP(name, dns_table[i].name) == 0) &&
(lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0) &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, dns_table[i].ipaddr)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr));
@ -1243,7 +1210,7 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
/* check for duplicate entries */
for (i = 0; i < DNS_TABLE_SIZE; i++) {
if ((dns_table[i].state == DNS_STATE_ASKING) &&
(LWIP_DNS_STRICMP(name, dns_table[i].name) == 0)) {
(lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0)) {
#if LWIP_IPV4 && LWIP_IPV6
if (dns_table[i].reqaddrtype != dns_addrtype) {
/* requested address types don't match

View File

@ -161,28 +161,6 @@
#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF
#endif
/** Set this to 1 on platforms where strnstr is not available */
#if !defined LWIP_HTTPD_STRNSTR_PRIVATE || defined __DOXYGEN__
#define LWIP_HTTPD_STRNSTR_PRIVATE 1
#endif
/** Set this to 1 on platforms where stricmp is not available */
#if !defined LWIP_HTTPD_STRICMP_PRIVATE || defined __DOXYGEN__
#define LWIP_HTTPD_STRICMP_PRIVATE 0
#endif
/** Define this to a smaller function if you have itoa() at hand... */
#if !defined LWIP_HTTPD_ITOA || defined __DOXYGEN__
#if !defined LWIP_HTTPD_ITOA_PRIVATE || defined __DOXYGEN__
#define LWIP_HTTPD_ITOA_PRIVATE 1
#endif
#if LWIP_HTTPD_ITOA_PRIVATE
#define LWIP_HTTPD_ITOA(buffer, bufsize, number) httpd_itoa(number, buffer)
#else
#define LWIP_HTTPD_ITOA(buffer, bufsize, number) snprintf(buffer, bufsize, "%d", number)
#endif
#endif
/** Set this to one to show error pages when parsing a request fails instead
of simply closing the connection. */
#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__

View File

@ -40,16 +40,6 @@
* @{
*/
/** Since there's no standard function for case-insensitive string comparision,
* we need another define here:
* define this to stricmp() for windows or strcasecmp() for linux.
* If not defined, comparision is case sensitive and the provided hostname must be
* uppercase.
*/
#if !defined NETBIOS_STRCMP || defined __DOXYGEN__
#define NETBIOS_STRCMP(str1, str2) strcmp(str1, str2)
#endif
/** NetBIOS name of lwip device
* This must be uppercase until NETBIOS_STRCMP() is defined to a string
* comparision function that is case insensitive.

View File

@ -133,9 +133,26 @@ u32_t lwip_ntohl(u32_t x);
#endif /* BYTE_ORDER == BIG_ENDIAN */
/* Functions that are not available as standard implementations.
* In lwipopts.h, you can #define these to implementations available on
* your platform to save some code bytes if you use these functions
* in your application, too.
*/
#ifndef lwip_itoa
void lwip_itoa(int value, char* result);
#endif
#ifndef lwip_strnicmp
int lwip_strnicmp(const char* str1, const char* str2, size_t len);
#endif
#ifndef lwip_stricmp
int lwip_stricmp(const char* str1, const char* str2);
#endif
#ifndef lwip_strnstr
char* lwip_strnstr(const char* buffer, const char* token, size_t n);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_DEF_H */