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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.