From 6649519542fbc18cea4d92581737d3fdc8ecbb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szoboszlay?= Date: Wed, 12 Jul 2023 19:24:59 +0200 Subject: [PATCH] Respect text encoding in !env tag --- CHANGELOG.md | 10 +++++++++- src/bec_node_env_variable.erl | 14 +++++++++++--- test/bec_yml_SUITE.erl | 28 ++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d7e74a..74e86c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [unreleased] + +### Fixed + +- `!env` tag now respects the `str_node_as_binary` option, so injected vars won't crash Mustache templates. + ## [1.5.0] - 2023-07-05 ### Added @@ -40,5 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Open sourcing of an existing internal project -[unreleased]: https://github.com/klarna-incubator/bec/compare/v1.0.0...HEAD +[unreleased]: https://github.com/klarna-incubator/bec/compare/v1.5.0...HEAD +[1.5.0]: https://github.com/klarna-incubator/bec/releases/tag/1.5.0 +[1.3.0]: https://github.com/klarna-incubator/bec/releases/tag/1.3.0 [1.0.0]: https://github.com/klarna-incubator/bec/releases/tag/1.0.0 diff --git a/src/bec_node_env_variable.erl b/src/bec_node_env_variable.erl index 6a2ee6f..eda80b3 100644 --- a/src/bec_node_env_variable.erl +++ b/src/bec_node_env_variable.erl @@ -17,7 +17,8 @@ tags() -> [?TAG, "!env"]. -construct_token(#yamerl_constr{detailed_constr = Detailed}, +construct_token(#yamerl_constr{detailed_constr = Detailed, + ext_options = Options}, undefined, #yamerl_scalar{text = Text} = Token) -> case os:getenv(Text) of @@ -28,11 +29,11 @@ construct_token(#yamerl_constr{detailed_constr = Detailed}, Node = #yamerl_str{ module = ?MODULE , tag = ?TAG , pres = Pres - , text = Value + , text = encode_text(Value, Options) }, {finished, Node}; Value -> - {finished, Value} + {finished, encode_text(Value, Options)} end; construct_token(_, _, Token) -> parsing_error(Token, "Invalid OS environment variable"). @@ -49,3 +50,10 @@ parsing_error(Token, Text) -> column = ?TOKEN_COLUMN(Token) }, throw(Error). + +encode_text(Text, Options) -> + case proplists:get_value(str_node_as_binary, Options, false) of + false -> Text; + true -> unicode:characters_to_binary(Text); + Encoding -> unicode:characters_to_binary(Text, unicode, Encoding) + end. diff --git a/test/bec_yml_SUITE.erl b/test/bec_yml_SUITE.erl index fb84173..47b6d0f 100644 --- a/test/bec_yml_SUITE.erl +++ b/test/bec_yml_SUITE.erl @@ -14,6 +14,8 @@ %% Testcases -export([ environment_variable_substitution/1 , missing_environment_variable/1 + , environment_variable_as_string/1 + , environment_variable_as_binary/1 ]). %%============================================================================== @@ -65,9 +67,9 @@ environment_variable_substitution(_Config) -> Yml = <<"myval: !env TEST_VAL\n">>, try os:putenv("TEST_VAL", "abc"), - ?assertEqual([#{<<"myval">> => "abc"}], bec_yml:decode(Yml)), + ?assertEqual([#{<<"myval">> => <<"abc">>}], bec_yml:decode(Yml)), os:putenv("TEST_VAL", "xyz"), - ?assertEqual([#{<<"myval">> => "xyz"}], bec_yml:decode(Yml)) + ?assertEqual([#{<<"myval">> => <<"xyz">>}], bec_yml:decode(Yml)) after os:unsetenv("TEST_VAL") end. @@ -77,3 +79,25 @@ missing_environment_variable(_Config) -> Yml = <<"myval: !env TEST_VAL\n">>, os:unsetenv("TEST_VAL"), ?assertThrow({yamerl_exception, _}, bec_yml:decode(Yml)). + +-spec environment_variable_as_string(config()) -> ok. +environment_variable_as_string(_Config) -> + Yml = <<"myval: !env TEST_VAL\n">>, + Opts = [{map_node_format, map}], + try + os:putenv("TEST_VAL", "abc"), + ?assertEqual([#{"myval" => "abc"}], yamerl:decode(Yml, Opts)) + after + os:unsetenv("TEST_VAL") + end. + +-spec environment_variable_as_binary(config()) -> ok. +environment_variable_as_binary(_Config) -> + Yml = <<"myval: !env TEST_VAL\n">>, + Opts = [str_node_as_binary, {map_node_format, map}], + try + os:putenv("TEST_VAL", "abc"), + ?assertEqual([#{<<"myval">> => <<"abc">>}], yamerl:decode(Yml, Opts)) + after + os:unsetenv("TEST_VAL") + end.