mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Merge branch 'mc-4.6'
* mc-4.6: 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 Signed-off-by: Patrick Winnertz <winnie@debian.org>
This commit is contained in:
commit
41f06e42b1
@ -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>
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
@ -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>
|
||||||
|
89
mhl/string.h
89
mhl/string.h
@ -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 */
|
||||||
|
12
mhl/types.h
12
mhl/types.h
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user