Interfaces to limit string sizes
Paulo Roberto <[email protected]>
| Newsgroups | gmane.linux.drivers.gammu |
|---|---|
| Message-ID | <CA+96iqdWyff2ktJ+pUgJY0Nh9N6wm+9YdtJArbXvcFd2cPARiA@mail.gmail.com> |
Hello, I've been using LibGammu in some projects, it's a great project. But I noticed that dealing with strings could be a lot error prone and if not careful you could have some security issues. I say this because of the use of static string variables and the assumption of correctness in the buffer size. To solve it in my projects I implemented some new interfaces for the functions that I use. Mainly in coding.c and api.c. The new functions do the same of the old ones, but add the control of limit buffers size. I was not sure about how to name the new functions, so I added a '_s' in the name of the old functions. Example: CopyUnicodeString => CopyUnicodeString_s I'm sending a little patch with these changes. If you approve the modification, I would be glad to add equivalent functions for the rest of the API when it requires. Thanks for this software and I look forward to hearing from you. Best Regards. ------------------------------------------------------------------------------ Transform Data into Opportunity. Accelerate data analysis in your applications with Intel Data Analytics Acceleration Library. Click to learn more. http://pubads.g.doubleclick.net/gampad/clk?id=278785351&iu=/4140 _______________________________________________ Gammu-users mailing list - https://lists.sourceforge.net/lists/listinfo/gammu-users
gammu.patch
(text/x-patch, 8.5 KB)
From 64d6cd8326a1c69f0b2ada13d5008e3233863812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Roberto=20Brand=C3=A3o?= <[email protected]> Date: Mon, 21 Mar 2016 18:33:28 -0300 Subject: [PATCH] Implemented some interfaces to manipulate string limiting size. Implemented some equivalent functions to manipulate strings without using fix size strings and static variables. It turn those functions also reentrant. --- include/gammu-info.h | 27 ++++++++++ include/gammu-unicode.h | 10 ++++ libgammu/api.c | 32 ++++++++++++ libgammu/misc/coding/coding.c | 115 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) diff --git a/include/gammu-info.h b/include/gammu-info.h index f6a27a7..412f6c5 100644 --- a/include/gammu-info.h +++ b/include/gammu-info.h @@ -19,6 +19,7 @@ extern "C" { #include <gammu-types.h> #include <gammu-error.h> #include <gammu-limits.h> +#include <stddef.h> /** * Find network name from given network code. @@ -815,6 +816,19 @@ gboolean GSM_AddPhoneFeature(GSM_PhoneModel * model, GSM_Feature feature); GSM_Error GSM_GetManufacturer(GSM_StateMachine * s, char *value); /** + * Reads manufacturer from phone. + * + * \param s State machine pointer. + * \param value Pointer where to store manufacturer name + * \param vsize Size of buffer pointed by parameter value + * + * \return Error code. + * + * \ingroup Info + */ +GSM_Error GSM_GetManufacturer_s(GSM_StateMachine *s, char *value, size_t vsize ); + +/** * Reads model from phone. * * \param s State machine pointer. @@ -827,6 +841,19 @@ GSM_Error GSM_GetManufacturer(GSM_StateMachine * s, char *value); GSM_Error GSM_GetModel(GSM_StateMachine * s, char *value); /** + * Reads model from phone. + * + * \param s State machine pointer. + * \param value Pointer where to store model name + * \param vsize Size of buffer pointed by parameter value + * + * \return Error code. + * + * \ingroup Info + */ +GSM_Error GSM_GetModel_s(GSM_StateMachine *s, char *value, size_t vsize); + +/** * Reads model info from state machine. * * \param s State machine pointer. diff --git a/include/gammu-unicode.h b/include/gammu-unicode.h index 5aa5fae..381f236 100644 --- a/include/gammu-unicode.h +++ b/include/gammu-unicode.h @@ -40,6 +40,8 @@ size_t UnicodeLength(const unsigned char *str); */ char *DecodeUnicodeString(const unsigned char *src); +char *DecodeUnicodeString_s (const unsigned char *src, char *dest, size_t dsize); + /** * Converts string to console charset. * @@ -49,6 +51,8 @@ char *DecodeUnicodeString(const unsigned char *src); */ char *DecodeUnicodeConsole(const unsigned char *src); +char *DecodeUnicodeConsole_s(const unsigned char *src, char *dest, size_t dsize); + /** * Converts string from unicode to local charset. * @@ -56,6 +60,8 @@ char *DecodeUnicodeConsole(const unsigned char *src); */ void DecodeUnicode(const unsigned char *src, char *dest); +void DecodeUnicode_s (const unsigned char *src, char *dest, size_t dsize); + /** * Encodes string from local charset to unicode. * @@ -63,6 +69,8 @@ void DecodeUnicode(const unsigned char *src, char *dest); */ void EncodeUnicode(unsigned char *dest, const char *src, int len); +void EncodeUnicode_s (unsigned char *dest, const char *src, size_t dsize, size_t len); + /** * Decodes unicode file data with byte order mark (BOM). * @@ -77,6 +85,8 @@ void ReadUnicodeFile(unsigned char *Dest, const unsigned char *Source); */ void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source); +void CopyUnicodeString_s(unsigned char *Dest, const unsigned char *Source, size_t dsize); + /** * Encodes string to UTF-8 quoted printable. * diff --git a/libgammu/api.c b/libgammu/api.c index 6b501fd..227e6bc 100644 --- a/libgammu/api.c +++ b/libgammu/api.c @@ -77,6 +77,22 @@ GSM_Error GSM_GetManufacturer(GSM_StateMachine *s, char *value) PRINT_LOG_ERROR(err); return err; } + +GSM_Error GSM_GetManufacturer_s(GSM_StateMachine *s, char *value, size_t vsize ) +{ + GSM_Error err; + + CHECK_PHONE_CONNECTION(); + + s->Phone.Data.Manufacturer[0] = '\0'; + err = s->Phone.Functions->GetManufacturer(s); + if (value != NULL) { + snprintf(value, vsize, "%s", s->Phone.Data.Manufacturer); + } + + PRINT_LOG_ERROR(err); + return err; +} /** * Reads model from phone. */ @@ -95,6 +111,22 @@ GSM_Error GSM_GetModel(GSM_StateMachine *s, char *value) PRINT_LOG_ERROR(err); return err; } + +GSM_Error GSM_GetModel_s(GSM_StateMachine *s, char *value, size_t vsize) +{ + GSM_Error err; + + CHECK_PHONE_CONNECTION(); + + s->Phone.Data.Model[0] = '\0'; + err = s->Phone.Functions->GetModel(s); + if (value != NULL) { + snprintf(value, vsize, "%s", s->Phone.Data.Model); + } + + PRINT_LOG_ERROR(err); + return err; +} /** * Reads firmware information from phone. */ diff --git a/libgammu/misc/coding/coding.c b/libgammu/misc/coding/coding.c index e1b3a25..802129d 100644 --- a/libgammu/misc/coding/coding.c +++ b/libgammu/misc/coding/coding.c @@ -241,6 +241,30 @@ void DecodeUnicode (const unsigned char *src, char *dest) dest[o]=0; } +void DecodeUnicode_s (const unsigned char *src, char *dest, size_t dsize) +{ + int i=0,o=0; + wchar_t value, second; + + if(dsize == 0 ) + return; + + while ( --dsize != 0 && (src[(i<<1)+1]!=0x00 || src[i<<1]!=0x00)) { + value = (src[i<<1] << 8 ) + src[(i<<1) + 1]; + /* Decode UTF-16 */ + if (value >= 0xD800 && value <= 0xDBFF) { + second = (src[(i + 1)<<1] << 8) + src[((i + 1)<< 1) + 1]; + if (second >= 0xDC00 && second <= 0xDFFF) { + i++; + value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + } + } + o += DecodeWithUnicodeAlphabet(value, (unsigned char *) dest + o); + i++; + } + dest[o]=0; +} + /* Decode Unicode string and return as function result */ char *DecodeUnicodeString (const unsigned char *src) { @@ -250,6 +274,15 @@ char *DecodeUnicodeString (const unsigned char *src) return dest; } +/* Decode Unicode string and return as function result parameter dest */ +char *DecodeUnicodeString_s (const unsigned char *src, char *dest, size_t dsize) +{ + if(dest == NULL || dsize == 0) + return NULL; + DecodeUnicode_s(src, dest, dsize); + return dest; +} + /* Decode Unicode string to UTF8 or other console charset * and return as function result */ @@ -278,6 +311,29 @@ char *DecodeUnicodeConsole(const unsigned char *src) return dest; } +char *DecodeUnicodeConsole_s(const unsigned char *src, char *dest, size_t dsize) +{ + if (GSM_global_debug.coding[0] != 0) { + if (!strcmp(GSM_global_debug.coding,"utf8")) { + EncodeUTF8(dest, src); + } else { +#ifdef WIN32 + setlocale(LC_ALL, GSM_global_debug.coding); +#endif + DecodeUnicode_s(src,dest, dsize); + } + } else { +#ifdef WIN32 + setlocale(LC_ALL, ".OCP"); +#endif + DecodeUnicode_s(src,dest, dsize); +#ifdef WIN32 + setlocale(LC_ALL, ".ACP"); +#endif + } + return dest; +} + /* Encode string to Unicode. Len is number of input chars */ void DecodeISO88591 (unsigned char *dest, const char *src, int len) { @@ -312,6 +368,31 @@ void EncodeUnicode (unsigned char *dest, const char *src, int len) dest[(o_len*2)+1] = 0; } +/* Encode string to Unicode. dsize is size of buffer dest */ +void EncodeUnicode_s (unsigned char *dest, const char *src, size_t dsize, size_t len) +{ + size_t i_len=0; + wchar_t wc; + + if(dest == NULL || src == NULL || dsize < 2) + return; + + if(dsize %2) + dsize--; + + if(len == 0) + len = strlen(src); + + while((dsize-=2) != 0 && i_len < len) + { + i_len += EncodeWithUnicodeAlphabet((const unsigned char *)&src[i_len], &wc); + *dest++ = (wc >> 8) & 0xff; + *dest++ = wc & 0xff; + } + *dest++ = '\0'; + *dest = '\0'; +} + unsigned char EncodeWithBCDAlphabet(int value) { div_t division; @@ -1202,6 +1283,40 @@ void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source) Dest[j+1] = 0; } +void CopyUnicodeString_s(unsigned char *Dest, const unsigned char *Source, size_t dsize) +{ + size_t nleft = dsize; + + /* No need to copy if both are on same address */ + if (Dest == Source) return; + + if(nleft != 0) + { + if(nleft == 1) + { + *Dest='\0'; + return; + } + if(nleft %2) + nleft--; + while ((nleft-=2) != 0) + { + if((*Dest++= *Source++) == 0) + { + if((*Dest++ = *Source++) == 0) + break; + } + else + *Dest++ = *Source++; + } + } + if(nleft == 0) + { + *Dest++ = '\0'; + *Dest = '\0'; + } +} + /* Changes minor/major order in Unicode string */ void ReverseUnicodeString(unsigned char *String) { -- 2.7.0