diff --git a/lib/fort.c b/lib/fort.c index 9cff195..57c916f 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -173,7 +173,10 @@ enum request_geom_type { struct conv_context { char *buf_origin; - char *buf; + union { + char *buf; + wchar_t *wbuf; + }; size_t raw_avail; struct fort_context *cntx; enum str_buf_type b_type; @@ -1722,6 +1725,9 @@ size_t string_buffer_width_capacity(const string_buffer_t *buffer); FT_INTERNAL void *buffer_get_data(string_buffer_t *buffer); +FT_INTERNAL +int buffer_check_align(string_buffer_t *buffer); + FT_INTERNAL int buffer_printf(string_buffer_t *buffer, size_t buffer_row, conv_context_t *cntx, size_t cod_width, const char *content_style_tag, const char *reset_content_style_tag); @@ -3012,7 +3018,7 @@ static const char *empty_str_arr[] = {"", (const char *)L"", ""}; static -const char *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) +const void *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) { assert(table); @@ -3038,6 +3044,8 @@ const char *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) return NULL; } } + if (!buffer_check_align(table->conv_buffer)) + return NULL; char *buffer = (char *)buffer_get_data(table->conv_buffer); size_t cols = 0; @@ -3657,7 +3665,7 @@ int print_n_strings(conv_context_t *cntx, size_t n, const char *str) return snprint_n_strings(cntx, n, str); #ifdef FT_HAVE_WCHAR case W_CHAR_BUF: - cod_w = wsnprint_n_string((wchar_t *)cntx->buf, cntx->raw_avail, n, str); + cod_w = wsnprint_n_string(cntx->wbuf, cntx->raw_avail, n, str); if (cod_w < 0) return cod_w; raw_written = sizeof(wchar_t) * cod_w; @@ -3709,7 +3717,10 @@ int ft_nwprint(conv_context_t *cntx, const wchar_t *str, size_t strlen) memcpy(cntx->buf, str, raw_len); cntx->buf += raw_len; cntx->raw_avail -= raw_len; - *(wchar_t *)cntx->buf = L'\0'; /* Do we need this ? */ + + /* Do we need this ? */ + wchar_t end_of_string = L'\0'; + memcpy(cntx->buf, &end_of_string, sizeof(wchar_t)); return strlen; } #endif /* FT_HAVE_WCHAR */ @@ -6364,6 +6375,30 @@ void *buffer_get_data(string_buffer_t *buffer) return buffer->str.data; } +FT_INTERNAL +int buffer_check_align(string_buffer_t *buffer) +{ + assert(buffer); + assert(buffer->str.data); + void *p = buffer->str.data; + + switch (buffer->type) { + case CHAR_BUF: + return 1; +#ifdef FT_HAVE_WCHAR + case W_CHAR_BUF: + return (((unsigned long)p) & (sizeof(wchar_t) - 1)) == 0; +#endif +#ifdef FT_HAVE_UTF8 + case UTF8_BUF: + return 1; +#endif + default: + assert(0); + return 0; + } +} + /******************************************************** End of file "string_buffer.c" ********************************************************/ diff --git a/src/fort_impl.c b/src/fort_impl.c index 5b418e2..1aa2ab3 100644 --- a/src/fort_impl.c +++ b/src/fort_impl.c @@ -601,7 +601,7 @@ static const char *empty_str_arr[] = {"", (const char *)L"", ""}; static -const char *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) +const void *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) { assert(table); @@ -627,6 +627,8 @@ const char *ft_to_string_impl(const ft_table_t *table, enum str_buf_type b_type) return NULL; } } + if (!buffer_check_align(table->conv_buffer)) + return NULL; char *buffer = (char *)buffer_get_data(table->conv_buffer); size_t cols = 0; diff --git a/src/fort_utils.c b/src/fort_utils.c index 68862bd..e0e6a4f 100644 --- a/src/fort_utils.c +++ b/src/fort_utils.c @@ -255,7 +255,7 @@ int print_n_strings(conv_context_t *cntx, size_t n, const char *str) return snprint_n_strings(cntx, n, str); #ifdef FT_HAVE_WCHAR case W_CHAR_BUF: - cod_w = wsnprint_n_string((wchar_t *)cntx->buf, cntx->raw_avail, n, str); + cod_w = wsnprint_n_string(cntx->wbuf, cntx->raw_avail, n, str); if (cod_w < 0) return cod_w; raw_written = sizeof(wchar_t) * cod_w; @@ -307,7 +307,10 @@ int ft_nwprint(conv_context_t *cntx, const wchar_t *str, size_t strlen) memcpy(cntx->buf, str, raw_len); cntx->buf += raw_len; cntx->raw_avail -= raw_len; - *(wchar_t *)cntx->buf = L'\0'; /* Do we need this ? */ + + /* Do we need this ? */ + wchar_t end_of_string = L'\0'; + memcpy(cntx->buf, &end_of_string, sizeof(wchar_t)); return strlen; } #endif /* FT_HAVE_WCHAR */ diff --git a/src/fort_utils.h b/src/fort_utils.h index a21b613..554c70e 100644 --- a/src/fort_utils.h +++ b/src/fort_utils.h @@ -136,7 +136,10 @@ enum request_geom_type { struct conv_context { char *buf_origin; - char *buf; + union { + char *buf; + wchar_t *wbuf; + }; size_t raw_avail; struct fort_context *cntx; enum str_buf_type b_type; diff --git a/src/string_buffer.c b/src/string_buffer.c index 86570da..df6faee 100644 --- a/src/string_buffer.c +++ b/src/string_buffer.c @@ -631,3 +631,27 @@ void *buffer_get_data(string_buffer_t *buffer) assert(buffer); return buffer->str.data; } + +FT_INTERNAL +int buffer_check_align(string_buffer_t *buffer) +{ + assert(buffer); + assert(buffer->str.data); + void *p = buffer->str.data; + + switch (buffer->type) { + case CHAR_BUF: + return 1; +#ifdef FT_HAVE_WCHAR + case W_CHAR_BUF: + return (((unsigned long)p) & (sizeof(wchar_t) - 1)) == 0; +#endif +#ifdef FT_HAVE_UTF8 + case UTF8_BUF: + return 1; +#endif + default: + assert(0); + return 0; + } +} diff --git a/src/string_buffer.h b/src/string_buffer.h index b55887b..232abb0 100644 --- a/src/string_buffer.h +++ b/src/string_buffer.h @@ -66,6 +66,9 @@ size_t string_buffer_width_capacity(const string_buffer_t *buffer); FT_INTERNAL void *buffer_get_data(string_buffer_t *buffer); +FT_INTERNAL +int buffer_check_align(string_buffer_t *buffer); + FT_INTERNAL int buffer_printf(string_buffer_t *buffer, size_t buffer_row, conv_context_t *cntx, size_t cod_width, const char *content_style_tag, const char *reset_content_style_tag);