Browse Source

pastojs: errors on illegal char const

mattias 1 year ago
parent
commit
c7db379a4f
2 changed files with 74 additions and 48 deletions
  1. 2 0
      packages/fcl-passrc/src/pasresolveeval.pas
  2. 72 48
      packages/pastojs/src/fppas2js.pp

+ 2 - 0
packages/fcl-passrc/src/pasresolveeval.pas

@@ -217,6 +217,7 @@ const
   nAwaitWithoutPromise = 3144;
   nSymbolCannotBeExportedFromALibrary = 3145;
   nForLoopControlVarMustBeSimpleLocalVar = 3146;
+  nIllegalCharConst = 3147;
 
   // using same IDs as FPC
   nVirtualMethodXHasLowerVisibility = 3250; // was 3050
@@ -374,6 +375,7 @@ resourcestring
   sAwaitWithoutPromise = 'Await without promise';
   sSymbolCannotBeExportedFromALibrary = 'The symbol cannot be exported from a library';
   sForLoopControlVarMustBeSimpleLocalVar = 'For loop control variable must be simple local variable';
+  sIllegalCharConst = 'Illegal char constant';
 
 type
   { TResolveData - base class for data stored in TPasElement.CustomData }

+ 72 - 48
packages/pastojs/src/fppas2js.pp

@@ -6750,8 +6750,65 @@ function TPas2JSResolver.ExtractPasStringLiteral(El: TPasElement;
     Note that invalid UTF-8 sequences are checked by the scanner
 }
 var
-  p, StartP, i, l: integer;
+  p, StartP, l: integer;
+
+  procedure Err(id: TMaxPrecInt);
+  begin
+    RaiseMsg(id,nIllegalCharConst,sIllegalCharConst,[],El);
+  end;
+
+  function ReadNumber: integer;
+  var
+    c: AnsiChar;
+  begin
+    Result:=0;
+    inc(p);
+    if p>l then
+      Err(20170207155121);
+    if S[p]='$' then
+      begin
+      // #$hexnumber
+      inc(p);
+      StartP:=p;
+      while p<=l do
+        begin
+        c:=S[p];
+        case c of
+        '0'..'9': Result:=Result*16+ord(c)-ord('0');
+        'a'..'f': Result:=Result*16+ord(c)-ord('a')+10;
+        'A'..'F': Result:=Result*16+ord(c)-ord('A')+10;
+        else break;
+        end;
+        if Result>$10ffff then
+          RaiseNotYetImplemented(20170207164657,El,'maximum codepoint is $10ffff');
+        inc(p);
+        end;
+      if p=StartP then
+        Err(20170207164956);
+      end
+    else
+      begin
+      // #decimalnumber
+      StartP:=p;
+      while p<=l do
+        begin
+        c:=S[p];
+        case c of
+        '0'..'9': Result:=Result*10+ord(c)-ord('0');
+        else break;
+        end;
+        if Result>$10ffff then
+          Err(20170207171140);
+        inc(p);
+        end;
+      if p=StartP then
+        Err(20170207171148);
+      end;
+  end;
+
+var
   c: AnsiChar;
+  i, j: Integer;
 begin
   Result:='';
   {$IFDEF VerbosePas2JS}
@@ -6769,7 +6826,7 @@ begin
       StartP:=p;
       repeat
         if p>l then
-          RaiseInternalError(20170207155120);
+          Err(20170207155120);
         c:=S[p];
         case c of
         '''':
@@ -6793,69 +6850,36 @@ begin
       end;
     '#':
       begin
-      // word sequence
-      inc(p);
-      if p>l then
-        RaiseInternalError(20170207155121);
-      if S[p]='$' then
+      // number
+      i:=ReadNumber;
+      if (i>=$D800) and (i<=$DFFF) and (p<l) and (S[p]='#') then
         begin
-        // #$hexnumber
-        inc(p);
-        StartP:=p;
-        i:=0;
-        while p<=l do
-          begin
-          c:=S[p];
-          case c of
-          '0'..'9': i:=i*16+ord(c)-ord('0');
-          'a'..'f': i:=i*16+ord(c)-ord('a')+10;
-          'A'..'F': i:=i*16+ord(c)-ord('A')+10;
-          else break;
-          end;
-          if i>$10ffff then
-            RaiseNotYetImplemented(20170207164657,El,'maximum codepoint is $10ffff');
-          inc(p);
-          end;
-        if p=StartP then
-          RaiseInternalError(20170207164956);
+        // surrogate
+        j:=ReadNumber;
+        if (j>=$DC00) and (j<$DFFF) then
+          Result:=Result+CodePointToJSString((i and $3FF) shl 10 + (j and $3ff) + $10000)
+        else
+          Err(20231017120034);
         end
       else
-        begin
-        // #decimalnumber
-        StartP:=p;
-        i:=0;
-        while p<=l do
-          begin
-          c:=S[p];
-          case c of
-          '0'..'9': i:=i*10+ord(c)-ord('0');
-          else break;
-          end;
-          if i>$10ffff then
-            RaiseNotYetImplemented(20170207171140,El,'maximum codepoint is $10ffff');
-          inc(p);
-          end;
-        if p=StartP then
-          RaiseInternalError(20170207171148);
-        end;
-      Result:=Result+CodePointToJSString(i);
+        Result:=Result+CodePointToJSString(i);
       end;
     '^':
       begin
       // ^A is #1
       inc(p);
       if p>l then
-        RaiseInternalError(20181025125920);
+        Err(20181025125920);
       c:=S[p];
       case c of
       'a'..'z': Result:=Result+TJSChar(ord(c)-ord('a')+1);
       'A'..'Z': Result:=Result+TJSChar(ord(c)-ord('A')+1);
-      else RaiseInternalError(20170207160412);
+      else Err(20170207160412);
       end;
       inc(p);
       end;
     else
-      RaiseNotYetImplemented(20170207154653,El,'ord='+IntToStr(ord(S[p])));
+      Err(20170207154653);
     end;
   {$IFDEF VerbosePas2JS}
   {AllowWriteln}