DEADSOFTWARE

fix possible traps while HostLang initialization
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Sun, 16 Jun 2019 11:27:00 +0000 (14:27 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Sun, 16 Jun 2019 11:27:00 +0000 (14:27 +0300)
src/posix/generic/Host/Mod/Lang.cp

index c3b60a2b1a4b169740001bb83ac3f95d792f7bd0..4a2b3f79f0dbc7e03bfb9eb853cda1a040461355 100644 (file)
@@ -6,6 +6,8 @@ MODULE HostLang;
   CONST
     maxLen = 32;
 
+    default = "ASCII";
+
     (* modes *)
     replace* = 0; pep383x* = 1; pep383* = 2;
 
@@ -110,7 +112,7 @@ MODULE HostLang;
   END HostToString;
 
   PROCEDURE Init;
-    VAR p: POINTER TO ARRAY [untagged] OF SHORTCHAR; i, j: INTEGER; enc: ARRAY 32 OF SHORTCHAR;
+    VAR p: POINTER TO ARRAY [untagged] OF SHORTCHAR; i, j: INTEGER; enc: ARRAY maxLen OF SHORTCHAR;
   BEGIN
     invalid := S.VAL(iconv.iconv_t, -1);
     p := locale.setlocale(locale.LC_ALL, "");
@@ -120,41 +122,58 @@ MODULE HostLang;
         p := ""
       END
     END;
-    i := 0; j := 0;
-    WHILE (p[i] # 0X) & (p[i] # "_") & (p[i] # ".") DO
-      lang[j] := p[i];
-      INC(i); INC(j)
-    END;
-    lang[j] := 0X;
-    IF p[i] = "_" THEN
-      INC(i); j := 0;
-      WHILE (p[i] # 0X) & (p[i] # ".") DO
-        country[j] := p[i];
+
+    IF (p$ = "") OR (p$ = "C") OR (p$ = "POSIX") THEN
+      lang := ""; country := ""; enc := ""
+    ELSE
+      (* parse lang *)
+      i := 0; j := 0;
+      WHILE (j < maxLen - 1) & (p[i] # 0X) & (p[i] # "_") & (p[i] # ".") DO
+        lang[j] := p[i];
         INC(i); INC(j)
       END;
-      country[j] := 0X
-    END;
-    enc := "ASCII";
-    IF p[i] = "." THEN
-      INC(i); j := 0;
-      WHILE p[i] # 0X DO
-        enc[j] := p[i];
-        INC(i); INC(j)
+      lang[j] := 0X;
+      IF j >= maxLen - 1 THEN
+        WHILE (p[i] # 0X) & (p[i] # "_") & (p[i] # ".") DO INC(i) END;
+        lang := ""
       END;
-      enc[j] := 0X
-    END;
-    IF (lang = "C") OR (lang = "POSIX") THEN
-      lang := ""
+      (* parse country *)
+      IF p[i] = "_" THEN
+        INC(i); j := 0;
+        WHILE (j < maxLen - 1) & (p[i] # 0X) & (p[i] # ".") DO
+          country[j] := p[i];
+          INC(i); INC(j)
+        END;
+        country[j] := 0X;
+        IF j >= maxLen - 1 THEN
+          WHILE (p[i] # 0X) & (p[i] # ".") DO INC(i) END;
+          country := ""
+        END
+      END;
+      (* parse encoding *)
+      IF p[i] = "." THEN
+        INC(i); j := 0;
+        WHILE (j < maxLen - 1) & (p[i] # 0X) DO
+          enc[j] := p[i];
+          INC(i); INC(j)
+        END;
+        enc[j] := 0X;
+        IF j >= maxLen - 1 THEN
+          enc := ""
+        END
+      END
     END;
+
     sc2c := invalid; c2sc := invalid;
     IF Kernel.littleEndian THEN sc2c := iconv.iconv_open("UCS-2LE", enc)
     ELSE sc2c := iconv.iconv_open("UCS-2BE", enc)
     END;
-    IF sc2c = invalid THEN enc := "ASCII";
+    IF sc2c = invalid THEN
+      enc := default;
       IF Kernel.littleEndian THEN sc2c := iconv.iconv_open("UCS-2LE", enc)
       ELSE sc2c := iconv.iconv_open("UCS-2BE", enc)
       END;
-      ASSERT(c2sc # invalid, 100) (* ascii to ucs2 not supported? *)
+      ASSERT(sc2c # invalid, 100) (* ascii to ucs2 not supported? *)
     END;
     IF Kernel.littleEndian THEN c2sc := iconv.iconv_open(enc, "UCS-2LE")
     ELSE c2sc := iconv.iconv_open(enc, "UCS-2BE");