From 0023fce38d3bd6ee0e9b6ff8708fee1195057846 Mon Sep 17 00:00:00 2001 From: Barry Pollard Date: Sun, 22 Sep 2019 21:17:12 +0100 Subject: [PATCH] http: lowercase headernames for HTTP/2 and HTTP/3 Closes #4401 Fixes #4400 --- lib/strcase.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++ lib/strcase.h | 2 ++ 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/lib/strcase.c b/lib/strcase.c index 24bcca932..098cec7a8 100644 --- a/lib/strcase.c +++ b/lib/strcase.c @@ -93,6 +93,75 @@ char Curl_raw_toupper(char in) return in; } + +/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because + its behavior is altered by the current locale. */ +char Curl_raw_tolower(char in) +{ +#if !defined(CURL_DOES_CONVERSIONS) + if(in >= 'A' && in <= 'Z') + return (char)('a' + in - 'A'); +#else + switch(in) { + case 'A': + return 'a'; + case 'B': + return 'b'; + case 'C': + return 'c'; + case 'D': + return 'd'; + case 'E': + return 'e'; + case 'F': + return 'f'; + case 'G': + return 'g'; + case 'H': + return 'h'; + case 'I': + return 'i'; + case 'J': + return 'j'; + case 'K': + return 'k'; + case 'L': + return 'l'; + case 'M': + return 'm'; + case 'N': + return 'n'; + case 'O': + return 'o'; + case 'P': + return 'p'; + case 'Q': + return 'q'; + case 'R': + return 'r'; + case 'S': + return 's'; + case 'T': + return 't'; + case 'U': + return 'u'; + case 'V': + return 'v'; + case 'W': + return 'w'; + case 'X': + return 'X'; + case 'Y': + return 'y'; + case 'Z': + return 'z'; + } +#endif + + return in; +} + + /* * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is * meant to be locale independent and only compare strings we know are safe @@ -234,6 +303,21 @@ void Curl_strntoupper(char *dest, const char *src, size_t n) } while(*src++ && --n); } +/* Copy a lower case version of the string from src to dest. The + * strings may overlap. No more than n characters of the string are copied + * (including any NUL) and the destination string will NOT be + * NUL-terminated if that limit is reached. + */ +void Curl_strntolower(char *dest, const char *src, size_t n) +{ + if(n < 1) + return; + + do { + *dest++ = Curl_raw_tolower(*src); + } while(*src++ && --n); +} + /* Compare case-sensitive NUL-terminated strings, taking care of possible * null pointers. Return true if arguments match. */ diff --git a/lib/strcase.h b/lib/strcase.h index 6fee3840e..2f07a74c9 100644 --- a/lib/strcase.h +++ b/lib/strcase.h @@ -40,12 +40,14 @@ int Curl_safe_strcasecompare(const char *first, const char *second); int Curl_strncasecompare(const char *first, const char *second, size_t max); char Curl_raw_toupper(char in); +char Curl_raw_tolower(char in); /* checkprefix() is a shorter version of the above, used when the first argument is zero-byte terminated */ #define checkprefix(a,b) curl_strnequal(a,b,strlen(a)) void Curl_strntoupper(char *dest, const char *src, size_t n); +void Curl_strntolower(char *dest, const char *src, size_t n); bool Curl_safecmp(char *a, char *b); int Curl_timestrcmp(const char *first, const char *second); -- 2.43.0