Merge branch '241_buffer_overflow' into mc-4.6

* 241_buffer_overflow:
  Resolve some issues in mhl Rollang Illig pointed us to:
  Added enhancements from Sergei which he attached to #241.
  Call va_end after the iteration as we need to free the list again.
  Fixing a theoretical buffer overflow which was reported by Roland Illig

Conflicts:
	mhl/types.h

Signed-off-by: Patrick Winnertz <winnie@debian.org>
This commit is contained in:
Patrick Winnertz 2009-02-04 12:42:58 +01:00
commit c83e1995e4
6 changed files with 66 additions and 57 deletions

View File

@ -1,5 +1,5 @@
#ifndef __MHL_ENV_H #ifndef MHL_ENV_H
#define __MHL_ENV_H #define MHL_ENV_H
#include <mhl/string.h> #include <mhl/string.h>

View File

@ -1,5 +1,5 @@
#ifndef __MHL_SHELL_ESCAPE_H #ifndef MHL_ESCAPE_H
#define __MHL_SHELL_ESCAPE_H #define MHL_ESCAPE_H
/* Micro helper library: shell escaping functions */ /* Micro helper library: shell escaping functions */
@ -63,7 +63,7 @@ static inline SHELL_ESCAPED_STR mhl_shell_escape_dup(const char* src)
/** Unescape paths or other strings for e.g the internal cd /** Unescape paths or other strings for e.g the internal cd
shell-unescape within a given buffer (writing to it!) shell-unescape within a given buffer (writing to it!)
/params const char * in /params const char * src
string for unescaping string for unescaping
/returns /returns
return unescaped string return unescaped string
@ -112,7 +112,7 @@ static inline char* mhl_shell_unescape_buf(char* text)
case '`': case '`':
case '"': case '"':
case ';': case ';':
case '\0': /* end of line! malformed escape string */ case '\0': /* end of string! malformed escape string */
goto out; goto out;
default: default:
(*writeptr) = c; writeptr++; break; (*writeptr) = c; writeptr++; break;

View File

@ -1,5 +1,5 @@
#ifndef __MHL_MEM #ifndef MHL_MEMORY_H
#define __MHL_MEM #define MHL_MEMORY_H
#include <memory.h> #include <memory.h>
#include <stdlib.h> #include <stdlib.h>
@ -17,7 +17,7 @@ static inline void mhl_mem_free(void* ptr)
} }
/* free an ptr and NULL it */ /* free an ptr and NULL it */
#define MHL_PTR_FREE(ptr) do { mhl_mem_free(ptr); (ptr) = NULL; } while (0); #define MHL_PTR_FREE(ptr) do { mhl_mem_free(ptr); (ptr) = NULL; } while (0)
/* allocate a chunk on stack - automatically free'd on function exit */ /* allocate a chunk on stack - automatically free'd on function exit */
#define mhl_stack_alloc(sz) (alloca(sz)) #define mhl_stack_alloc(sz) (alloca(sz))

View File

@ -1,5 +1,5 @@
#ifndef __MHL_STRHASH_H #ifndef MHL_STRHASH_H
#define __MHL_STRHASH_H #define MHL_STRHASH_H
#include <hash.h> #include <hash.h>
#include <mhl/memory.h> #include <mhl/memory.h>

View File

@ -1,5 +1,5 @@
#ifndef __MHL_STRING_H #ifndef MHL_STRING_H
#define __MHL_STRING_H #define MHL_STRING_H
#include <ctype.h> #include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
@ -10,6 +10,9 @@
#define mhl_str_ndup(str,len) ((str ? strndup(str,len) : strdup(""))) #define mhl_str_ndup(str,len) ((str ? strndup(str,len) : strdup("")))
#define mhl_str_len(str) ((str ? strlen(str) : 0)) #define mhl_str_len(str) ((str ? strlen(str) : 0))
#define ISSPACE(c) isspace((unsigned char)(c))
#define TOUPPER(c) toupper((unsigned char)(c))
static inline char * mhl_str_dup_range(const char * s_start, const char * s_bound) static inline char * mhl_str_dup_range(const char * s_start, const char * s_bound)
{ {
return mhl_str_ndup(s_start, s_bound - s_start); return mhl_str_ndup(s_start, s_bound - s_start);
@ -20,26 +23,26 @@ static inline char* mhl_str_trim(char* str)
if (!str) return NULL; /* NULL string ?! bail out. */ if (!str) return NULL; /* NULL string ?! bail out. */
/* find the first non-space */ /* find the first non-space */
char* start; for (start=str; ((*str) && (!isspace(*str))); str++); char* start; for (start=str; ((*str) && (!ISSPACE(*str))); str++);
/* only spaces ? */ /* only spaces ? */
if (!(*str)) { *str = 0; return str; } if (!(*str)) { *str = 0; return str; }
/* get the size (cannot be empty - catched above) */ /* get the size (cannot be empty - caught above) */
size_t _sz = strlen(str); size_t _sz = strlen(str);
/* find the proper end */ /* find the proper end */
char* end; char* end;
for (end=(str+_sz-1); ((end>str) && (isspace(*end))); end--); for (end=(str+_sz-1); ((end>str) && (ISSPACE(*end))); end--);
end[1] = 0; /* terminate, just to be sure */ end[1] = 0; /* terminate, just to be sure */
/* if we have no leading spaces, just trucate */ /* if we have no leading spaces, just trucate */
if (start==str) { end++; *end = 0; return str; } if (start==str) { end++; *end = 0; return str; }
/* if it' only one char, dont need memmove for that */ /* if it's only one char, dont need memmove for that */
if (start==end) { str[0]=*start; str[1]=0; return str; } if (start==end) { str[0]=*start; str[1]=0; return str; }
/* by here we have a (non-empty) region between start end end */ /* by here we have a (non-empty) region between start and end */
memmove(str,start,(end-start+1)); memmove(str,start,(end-start+1));
return str; return str;
} }
@ -48,58 +51,55 @@ static inline void mhl_str_toupper(char* str)
{ {
if (str) if (str)
for (;*str;str++) for (;*str;str++)
*str = toupper(*str); *str = TOUPPER(*str);
} }
#define __STR_CONCAT_MAX 32 /* note: we use ((char*)(1)) as terminator - NULL is a valid argument ! */
static const char * mhl_s_c_sep__ = (const char *)1;
/* _NEVER_ call this function directly ! */ /* _NEVER_ call this function directly ! */
static inline char* __mhl_str_concat_hlp(const char* base, ...) static inline char* mhl_str_concat_hlp__(const char* va_start_dummy, ...)
{ {
static const char* arg_ptr[__STR_CONCAT_MAX]; char * result;
static size_t arg_sz[__STR_CONCAT_MAX]; size_t result_len = 0;
int count = 0; char * p;
size_t totalsize = 0; const char * chunk;
if (base)
{
arg_ptr[0] = base;
arg_sz[0] = totalsize = strlen(base);
count = 1;
}
va_list args; va_list args;
va_start(args,base); va_start(args,va_start_dummy);
char* a; while ((chunk = va_arg(args, const char*)) != mhl_s_c_sep__)
/* note: we use ((char*)(1)) as terminator - NULL is a valid argument ! */
while ((a = va_arg(args, char*))!=(char*)1)
{ {
if (a) if (chunk)
{ {
arg_ptr[count] = a; result_len += strlen (chunk);
arg_sz[count] = strlen(a);
totalsize += arg_sz[count];
count++;
} }
} }
va_end(args);
if (!count) if (result_len == 0)
return mhl_str_dup(""); return mhl_str_dup("");
/* now as we know how much to copy, allocate the buffer */ /* now as we know how much to copy, allocate the buffer + '\0'*/
char* buffer = (char*)mhl_mem_alloc_u(totalsize+2); result = (char*)mhl_mem_alloc_u (result_len + 1);
char* current = buffer;
int x=0;
for (x=0; x<count; x++)
{
memcpy(current, arg_ptr[x], arg_sz[x]);
current += arg_sz[x];
}
*current = 0; p = result;
return buffer;
va_start(args,va_start_dummy);
while ((chunk = va_arg(args, const char*)) != mhl_s_c_sep__)
{
if (chunk)
{
size_t chunk_len = strlen (chunk);
memcpy (p, chunk, chunk_len);
p += chunk_len;
}
}
va_end(args);
*p = '\0';
return result;
} }
#define mhl_str_concat(...) (__mhl_str_concat_hlp(__VA_ARGS__, (char*)(1))) #define mhl_str_concat(...) (mhl_str_concat_hlp__(mhl_s_c_sep__, __VA_ARGS__, mhl_s_c_sep__))
static inline char* mhl_str_reverse(char* ptr) static inline char* mhl_str_reverse(char* ptr)
{ {
@ -130,6 +130,7 @@ static inline char * mhl_strmove(char * dest, const char * src)
{ {
size_t n = strlen (src) + 1; /* + '\0' */ size_t n = strlen (src) + 1; /* + '\0' */
/* strictly speaking, this invokes undefined behavior as soon as dest and src are pointers into different objects. */
assert (dest<=src); assert (dest<=src);
return memmove(dest, src, n); return memmove(dest, src, n);
@ -168,4 +169,4 @@ static inline char* mhl_str_dir_plus_file(const char* dirname, const char* filen
return buffer; return buffer;
} }
#endif /* __MHL_STRING_H */ #endif /* MHL_STRING_H */

View File

@ -4,7 +4,15 @@
*/ */
#ifndef __MHL_TYPES_H #ifndef MHL_TYPES_H
#define __MHL_TYPES_H #define MHL_TYPES_H
#if !defined(__bool_true_false_are_defined) && !defined(false) && !defined(true) && !defined(bool)
typedef enum
{
false = 0,
true = 1
} bool;
#endif
#endif #endif