Continue changing STRING length from int8_t to uint8_t.
authorEdouard Tisserant <edouard@beremiz.fr>
Mon, 22 Apr 2024 12:11:51 +0200
changeset 1104 0bc1f5a4f975
parent 1100 f7cc4f6ce756
child 1105 8128cad6a6e3
Continue changing STRING length from int8_t to uint8_t.

This fix segmentation faults caused by overflow when converting from string to numeric types.
lib/C/iec_std_lib.h
--- a/lib/C/iec_std_lib.h	Fri Apr 05 12:05:28 2024 +0200
+++ b/lib/C/iec_std_lib.h	Mon Apr 22 12:11:51 2024 +0200
@@ -470,7 +470,10 @@
     __strlen_t l;
     unsigned int shift = 0;
 
-    if(IN->body[0]=='2' && IN->body[1]=='#'){
+    if(IN->len < 1){
+        /* empty string */
+        return 0;
+    }else if(IN->len > 1 && IN->body[0]=='2' && IN->body[1]=='#'){
         /* 2#0101_1010_1011_1111 */
         for(l = IN->len - 1; l >= 2 && shift < 64; l--)
         {
@@ -480,7 +483,7 @@
                 shift += 1;
             }
         }
-    }else if(IN->body[0]=='8' && IN->body[1]=='#'){
+    }else if(IN->len > 1 && IN->body[0]=='8' && IN->body[1]=='#'){
         /* 8#1234_5665_4321 */
         for(l = IN->len - 1; l >= 2 && shift < 64; l--)
         {
@@ -490,7 +493,7 @@
                 shift += 3;
             }
         }
-    }else if(IN->body[0]=='1' && IN->body[1]=='6' && IN->body[2]=='#'){
+    }else if(IN->len > 2 && IN->body[0]=='1' && IN->body[1]=='6' && IN->body[2]=='#'){
         /* 16#1234_5678_9abc_DEFG */
         for(l = IN->len - 1; l >= 3 && shift < 64; l--)
         {
@@ -509,9 +512,9 @@
     }else{
         /* -123456789 */
         LINT fac = IN->body[0] == '-' ? -1 : 1;
-        for(l = IN->len - 1; l >= 0 && shift < 20; l--)
+        for(l = IN->len; l > 0 && shift < 20; l--)
         {
-            char c = IN->body[l];
+            char c = IN->body[l-1];
             if( c >= '0' && c <= '9'){
                 res += ( c - '0') * fac;
                 fac *= 10;
@@ -533,7 +536,7 @@
     __strlen_t l;
     l = IN.len;
     /* search the dot */
-    while(--l > 0 && IN.body[l] != '.');
+    while(l > 0 && IN.body[--l] != '.');
     if(l != 0){
         return atof((const char *)&IN.body);
     }else{
@@ -571,7 +574,7 @@
     /* Quick hack : only transform seconds */
     /* search the dot */
     l = IN.len;
-    while(--l > 0 && IN.body[l] != '.');
+    while(l > 0 && IN.body[--l] != '.');
     if(l != 0){
         LREAL IN_val = atof((const char *)&IN.body);
         return  (TIME){(long)IN_val, (long)(IN_val - (LINT)IN_val)*1000000000};