diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index e7c9ce01b5..0e5ec61050 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -16,19 +16,19 @@ namespace esphome::api { // Helper functions for ZigZag encoding/decoding -static constexpr uint32_t encode_zigzag32(int32_t value) { +inline constexpr uint32_t encode_zigzag32(int32_t value) { return (static_cast(value) << 1) ^ (static_cast(value >> 31)); } -static constexpr uint64_t encode_zigzag64(int64_t value) { +inline constexpr uint64_t encode_zigzag64(int64_t value) { return (static_cast(value) << 1) ^ (static_cast(value >> 63)); } -static constexpr int32_t decode_zigzag32(uint32_t value) { +inline constexpr int32_t decode_zigzag32(uint32_t value) { return (value & 1) ? static_cast(~(value >> 1)) : static_cast(value >> 1); } -static constexpr int64_t decode_zigzag64(uint64_t value) { +inline constexpr int64_t decode_zigzag64(uint64_t value) { return (value & 1) ? static_cast(~(value >> 1)) : static_cast(value >> 1); } diff --git a/esphome/components/substitutions/jinja.py b/esphome/components/substitutions/jinja.py index cf393d2a5d..c6e40a668d 100644 --- a/esphome/components/substitutions/jinja.py +++ b/esphome/components/substitutions/jinja.py @@ -25,6 +25,24 @@ def has_jinja(st): return detect_jinja_re.search(st) is not None +# SAFE_GLOBAL_FUNCTIONS defines a allowlist of built-in functions that are considered safe to expose +# in Jinja templates or other sandboxed evaluation contexts. Only functions that do not allow +# arbitrary code execution, file access, or other security risks are included. +# +# The following functions are considered safe: +# - ord: Converts a character to its Unicode code point integer. +# - chr: Converts an integer to its corresponding Unicode character. +# - len: Returns the length of a sequence or collection. +# +# These functions were chosen because they are pure, have no side effects, and do not provide access +# to the file system, environment, or other potentially sensitive resources. +SAFE_GLOBAL_FUNCTIONS = { + "ord": ord, + "chr": chr, + "len": len, +} + + class JinjaStr(str): """ Wraps a string containing an unresolved Jinja expression, @@ -66,7 +84,11 @@ class Jinja: self.env.add_extension("jinja2.ext.do") self.env.globals["math"] = math # Inject entire math module self.context_vars = {**context_vars} - self.env.globals = {**self.env.globals, **self.context_vars} + self.env.globals = { + **self.env.globals, + **self.context_vars, + **SAFE_GLOBAL_FUNCTIONS, + } def expand(self, content_str): """