Browse Source

don't use reserve words for variable names

Khaleel Al-Adhami 2 weeks ago
parent
commit
9a7d317bec
3 changed files with 100 additions and 3 deletions
  1. 5 2
      reflex/components/core/foreach.py
  2. 8 1
      reflex/state.py
  3. 87 0
      reflex/vars/base.py

+ 5 - 2
reflex/components/core/foreach.py

@@ -15,7 +15,7 @@ from reflex.constants import MemoizationMode
 from reflex.state import ComponentState
 from reflex.utils import types
 from reflex.utils.exceptions import UntypedVarError
-from reflex.vars.base import LiteralVar, Var
+from reflex.vars.base import LiteralVar, Var, is_illegal_javascript_identifier
 
 
 class ForeachVarError(TypeError):
@@ -130,7 +130,10 @@ class Foreach(Component):
 
         if len(params) >= 1:
             # Determine the arg var name based on the params accepted by render_fn.
-            props["arg_var_name"] = params[0].name
+            name = params[0].name
+            if is_illegal_javascript_identifier(name):
+                name = f"arg_{name}"
+            props["arg_var_name"] = name
 
         if len(params) == 2:
             # Determine the index var name based on the params accepted by render_fn.

+ 8 - 1
reflex/state.py

@@ -84,6 +84,7 @@ from reflex.vars.base import (
     dispatch,
     get_unique_variable_name,
     is_computed_var,
+    is_illegal_javascript_identifier,
 )
 
 if TYPE_CHECKING:
@@ -1048,7 +1049,13 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
 
         # create the variable based on name and type
         var = Var(
-            _js_expr=format.format_state_name(cls.get_full_name()) + "." + name,
+            _js_expr=format.format_state_name(cls.get_full_name())
+            + "."
+            + (
+                name
+                if not is_illegal_javascript_identifier(name)
+                else name + "_" + md5(name.encode()).hexdigest()
+            ),
             _var_type=type_,
             _var_data=VarData.from_state(cls, name),
         ).guess_type()

+ 87 - 0
reflex/vars/base.py

@@ -89,6 +89,93 @@ SEQUENCE_TYPE = TypeVar("SEQUENCE_TYPE", bound=Sequence)
 
 warnings.filterwarnings("ignore", message="fields may not start with an underscore")
 
+ILLEGAL_JAVASCRIPT_NAMES = frozenset(
+    [
+        "abstract",
+        "arguments",
+        "as",
+        "async",
+        "await",
+        "boolean",
+        "break",
+        "byte",
+        "case",
+        "catch",
+        "char",
+        "class",
+        "const",
+        "continue",
+        "debugger",
+        "default",
+        "delete",
+        "do",
+        "double",
+        "else",
+        "enum",
+        "eval",
+        "export",
+        "extends",
+        "false",
+        "final",
+        "finally",
+        "float",
+        "for",
+        "from",
+        "function",
+        "get",
+        "goto",
+        "if",
+        "implements",
+        "import",
+        "in",
+        "instanceof",
+        "int",
+        "interface",
+        "let",
+        "long",
+        "native",
+        "new",
+        "null",
+        "of",
+        "package",
+        "private",
+        "protected",
+        "public",
+        "return",
+        "set",
+        "short",
+        "static",
+        "super",
+        "switch",
+        "synchronized",
+        "this",
+        "throw",
+        "throws",
+        "transient",
+        "true",
+        "try",
+        "typeof",
+        "var",
+        "void",
+        "volatile",
+        "while",
+        "with",
+        "yield",
+    ]
+)
+
+
+def is_illegal_javascript_identifier(name: str) -> bool:
+    """Check if the name is an illegal JavaScript identifier.
+
+    Args:
+        name: The name to check.
+
+    Returns:
+        True if the name is an illegal JavaScript identifier, False otherwise.
+    """
+    return name in ILLEGAL_JAVASCRIPT_NAMES
+
 
 @dataclasses.dataclass(
     eq=False,