Kaynağa Gözat

Mangle predefined JS object fields: 'constructor' and 'prototype'

Vladislav Folts 10 yıl önce
ebeveyn
işleme
0342c0f94f

+ 4 - 1
src/context.js

@@ -302,8 +302,11 @@ function castCode(type, context){
 function mangleField(id, type){
     if (Type.isScalar(type) 
         || (type instanceof Type.Array 
-            && Type.isScalar(Type.arrayBaseElementsType(type))))
+            && Type.isScalar(Type.arrayBaseElementsType(type)))){
+        if (id == "constructor" || id == "prototype")
+            return id + "$";
         return id;
+    }
 
     return "$" + id;
 }

+ 2 - 3
src/eberon/eberon_context.js

@@ -599,10 +599,9 @@ var RecordType = Class.extend.call(Type.Record, {
     },
     __hasMethodDeclaration: function(id){
         var type = this;
-        var result;
-        while (type && !(result = type.__declaredMethods[id]))
+        while (type && !type.__declaredMethods.hasOwnProperty(id))
             type = Type.recordBase(type);
-        return result;
+        return type && type.__declaredMethods[id];
     },
     __hasMethodDefinition: function(id){
         var type = this;

+ 1 - 1
src/ob/JsMap.ob

@@ -27,7 +27,7 @@ PROCEDURE find*(m: Type; s: STRING; VAR r: Object.PType): BOOLEAN;
 VAR
     result: BOOLEAN;
 BEGIN
-    JS.do("var value = m[s]; if (value !== undefined){result = true; r.set(value);}");
+    JS.do("if (m.hasOwnProperty(s)){result = true; r.set(m[s]);}");
     RETURN result
 END find;
 

+ 11 - 0
test/expected/record.js

@@ -39,6 +39,10 @@ var RTL$ = {
     makeRef: function (obj, prop){
         return {set: function(v){ obj[prop] = v; },
                 get: function(){ return obj[prop]; }};
+    },
+    assert: function (condition){
+        if (!condition)
+            throw new Error("assertion failed");
     }
 };
 var m = function (){
@@ -57,10 +61,15 @@ function RecordWithInnerArray(){
 	this.$aRecords = RTL$.makeArray(3, function(){return new T1();});
 	this.aPointers = RTL$.makeArray(3, null);
 }
+function RecordWithMangledFields(){
+	this.constructor$ = 0;
+	this.prototype$ = false;
+}
 var b1 = new Base1();
 var r1 = new T1();
 var recordWithInnerRecord = new RecordWithInnerRecord();
 var recordWithInnerArray = new RecordWithInnerArray();
+var recordWithMangledFields = new RecordWithMangledFields();
 
 function p1(r/*T1*/){
 }
@@ -81,4 +90,6 @@ byRef(RTL$.makeRef(recordWithInnerRecord.$r, "i"));
 recordWithInnerArray.aInts[0] = 123;
 recordWithInnerArray.$aRecords[0].i = 123;
 recordWithInnerArray.aPointers[0].i = 123;
+RTL$.assert(recordWithMangledFields.constructor$ == 0);
+RTL$.assert(!recordWithMangledFields.prototype$);
 }();

+ 9 - 0
test/input/record.ob

@@ -12,11 +12,17 @@ TYPE
         aRecords: ARRAY 3 OF T1;
         aPointers: ARRAY 3 OF POINTER TO T1
     END;
+
+    RecordWithMangledFields = RECORD
+        constructor: INTEGER;
+        prototype: BOOLEAN
+    END;
 VAR
 	b1: Base1;
 	r1: T1;
     recordWithInnerRecord: RecordWithInnerRecord;
     recordWithInnerArray: RecordWithInnerArray;
+    recordWithMangledFields: RecordWithMangledFields;
 
 PROCEDURE p1(r: T1);
 END p1;
@@ -42,4 +48,7 @@ BEGIN
     recordWithInnerArray.aInts[0] := 123;
     recordWithInnerArray.aRecords[0].i := 123;
     recordWithInnerArray.aPointers[0].i := 123;
+
+    ASSERT(recordWithMangledFields.constructor = 0);
+    ASSERT(~recordWithMangledFields.prototype);
 END m.

+ 2 - 0
test/test_unit.js

@@ -213,6 +213,8 @@ return {
     fail(["i^", "POINTER TO type expected, got 'INTEGER'"],
          ["r^", "POINTER TO type expected, got 'anonymous RECORD'"],
          ["p.unknown := 0", "type 'anonymous RECORD' has no 'unknown' field"],
+         ["pt.constructor := 0", "type 'PT' has no 'constructor' field"], // "constructor" is JS predefined property
+         ["pt.prototype := 0", "type 'PT' has no 'prototype' field"], // "prototype" is JS predefined property
          ["pt.unknown := 0", "type 'PT' has no 'unknown' field"])
     ),
 "POINTER assignment": testWithContext(