From 0d479fcd0cc9e61655ac15084d5cd9fd7fe97cdd Mon Sep 17 00:00:00 2001
From: Andreev Gregory <grinadand@gmail.com>
Date: Wed, 14 Aug 2024 16:12:31 +0300
Subject: [PATCH] Fixed one of those "Cs convenient ways to show error"
 (sigsegv caused by ivalid pointer). It were 2 hours of pure frustration

---
 src/http_server/new_york_transit_line/core.h        |  2 +-
 .../new_york_transit_line/execute_expression.cpp    | 11 ++++++++++-
 src/http_server/new_york_transit_line/parser.cpp    |  1 +
 src/http_server/new_york_transit_line/rendering.cpp |  5 ++---
 src/http_server/new_york_transit_line/templater.cpp |  2 +-
 src/http_server/new_york_transit_line/templater.h   |  2 +-
 .../nytl_tests/HypertextPages/test.nytl.html        | 13 +++++++------
 src/http_server/nytl_tests/test0.cpp                |  9 +++++++--
 8 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/src/http_server/new_york_transit_line/core.h b/src/http_server/new_york_transit_line/core.h
index e03b649..c598fe4 100644
--- a/src/http_server/new_york_transit_line/core.h
+++ b/src/http_server/new_york_transit_line/core.h
@@ -28,7 +28,7 @@ namespace nytl {
     LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
         const std::vector<LocalVarValue>& local_vars, const json::JSON& expr);
 
-    std::string rendering_core(const std::string& entry_func, const std::vector<json::JSON>& entry_arguments,
+    std::string rendering_core(const std::string& entry_func, const std::vector<const json::JSON*>& entry_arguments,
         const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape);
 }
 
diff --git a/src/http_server/new_york_transit_line/execute_expression.cpp b/src/http_server/new_york_transit_line/execute_expression.cpp
index 1d7a371..03b8f16 100644
--- a/src/http_server/new_york_transit_line/execute_expression.cpp
+++ b/src/http_server/new_york_transit_line/execute_expression.cpp
@@ -15,6 +15,15 @@ namespace nytl {
               result(result) {
         }
 
+        // todo: remove this debug function
+        // void print_result() {
+            // if (result.is_json) {
+                // printf("print_result %%p: %p\n", result.JSON_subval);
+                // printf("%s\n", json::generate_str(*result.JSON_subval, json::print_compact).c_str());
+            // } else
+                // printf("element %s\n", result.EL_name.c_str());
+        // }
+
         void descend(const json::JSON& what) {
             if (result.is_json) {
                 const json::JSON& P = *result.JSON_subval;
@@ -24,7 +33,7 @@ namespace nytl {
                     ASSERT(ind_w > 0 && ind_w < arr_p.size(), "Expression \"array[integer]\" caused out-of-bound situation");
                     result = LocalVarValue{true, "", &arr_p[ind_w]};
                 } else if (P.isDictionary() && what.isString()) {
-                    const std::map<std::string, json::JSON> dict_p = P.asDictionary();
+                    const std::map<std::string, json::JSON>& dict_p = P.asDictionary();
                     const std::string& key_w = what.asString();
                     ASSERT(dict_p.count(key_w) == 1, "No such key exception");
                     result = LocalVarValue{true, "", &dict_p.at(key_w)};
diff --git a/src/http_server/new_york_transit_line/parser.cpp b/src/http_server/new_york_transit_line/parser.cpp
index da8b884..c44cc33 100644
--- a/src/http_server/new_york_transit_line/parser.cpp
+++ b/src/http_server/new_york_transit_line/parser.cpp
@@ -437,6 +437,7 @@ namespace nytl {
                 P.called_element["C"] = json::JSON(json::array);
                 skipWhitespace(ctx);
                 P.passed_arguments = {parse_expression(ctx, local_var_names)};
+                skip_magic_block_end(ctx, syntax);
             };
             if (op == "WRITE") {
                 mediocre_operator("str2text");
diff --git a/src/http_server/new_york_transit_line/rendering.cpp b/src/http_server/new_york_transit_line/rendering.cpp
index 1aa3f26..48fc0b1 100644
--- a/src/http_server/new_york_transit_line/rendering.cpp
+++ b/src/http_server/new_york_transit_line/rendering.cpp
@@ -230,18 +230,17 @@ namespace nytl {
         return std::make_unique<RFrame_OverParts>(part.internal_element, saved_args_plus_iter, wsp_before_newlines);
     }
 
-    std::string rendering_core(const std::string& entry_func, const std::vector<json::JSON>& entry_arguments,
+    std::string rendering_core(const std::string& entry_func, const std::vector<const json::JSON*>& entry_arguments,
                                const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape)
     {
         Ditch result;
 
         std::vector<uptr<RFrame>> stack;
-
         {
             size_t AN = entry_arguments.size();
             std::vector<LocalVarValue> entry_arguments_conv(AN);
             for (size_t i = 0; i < AN; i++)
-                entry_arguments_conv[i] = {true, "", &entry_arguments[i]};
+                entry_arguments_conv[i] = {true, "", entry_arguments[i]};
             stack.push_back(std::make_unique<RFrame_OverParts>(entry_func, entry_arguments_conv, 0));
         }
         bool returned = false;
diff --git a/src/http_server/new_york_transit_line/templater.cpp b/src/http_server/new_york_transit_line/templater.cpp
index f66a0bd..ca07098 100644
--- a/src/http_server/new_york_transit_line/templater.cpp
+++ b/src/http_server/new_york_transit_line/templater.cpp
@@ -127,7 +127,7 @@ namespace nytl {
     }
 
     /* Still can throw some stuff derived from std::exception (like bad alloc) */
-    std::string Templater::render(const std::string& element, const std::vector<json::JSON> &arguments) const {
+    std::string Templater::render(const std::string& element, const std::vector<const json::JSON*> &arguments) const {
         ASSERT(is_uname_dotted_sequence(element), "Incorrect entry element name");
         return rendering_core(element, arguments, elements, settings.escape);
     }
diff --git a/src/http_server/new_york_transit_line/templater.h b/src/http_server/new_york_transit_line/templater.h
index d1018d9..599ae75 100644
--- a/src/http_server/new_york_transit_line/templater.h
+++ b/src/http_server/new_york_transit_line/templater.h
@@ -74,7 +74,7 @@ namespace nytl {
         void update();
 
         /* Throws exception, derived from std::exception */
-        std::string render(const std::string& element, const std::vector<json::JSON>& arguments) const;
+        std::string render(const std::string& element, const std::vector<const json::JSON*>& arguments) const;
     };
 }
 
diff --git a/src/http_server/nytl_tests/HypertextPages/test.nytl.html b/src/http_server/nytl_tests/HypertextPages/test.nytl.html
index 90c1f6f..271871e 100644
--- a/src/http_server/nytl_tests/HypertextPages/test.nytl.html
+++ b/src/http_server/nytl_tests/HypertextPages/test.nytl.html
@@ -1,8 +1,9 @@
-{% ELDEF main JSON abc %}
-        {% PUT jesc abc %}
-
-        AAAAAAAA
-    BBB
-        {% PUT jesc abc %}
+{% ELDEF foo JSON cba %}
+BBBB
+{% ENDELDEF %}
 
+{% ELDEF main JSON cba %}
+    AAAA
+        {% PUT test.foo cba %}
+    {% PUT test.foo cba %}
 {% ENDELDEF %}
\ No newline at end of file
diff --git a/src/http_server/nytl_tests/test0.cpp b/src/http_server/nytl_tests/test0.cpp
index 6d9732d..48c7852 100644
--- a/src/http_server/nytl_tests/test0.cpp
+++ b/src/http_server/nytl_tests/test0.cpp
@@ -1,3 +1,4 @@
+#include <jsonincpp/string_representation.h>
 #include <new_york_transit_line/templater.h>
 #include <new_york_transit_line/core.h>
 
@@ -11,8 +12,12 @@ int main(int argc, char** argv) {
     nytl::Templater templater(nytl::TemplaterSettings{nytl::TemplaterDetourRules{dir_path}});
     templater.update();
     nytl::debug_print_templater(templater);
-
-    std::string answer2 = templater.render("test", {json::JSON()});
+    json::JSON cba;
+    cba["boba"] = json::JSON("<>");
+    // printf("DEBUG WAS: %p\n", &cba["boba"].g());
+    // printf("%s\n", json::generate_str(cba["boba"].g(), json::print_compact).c_str());
+    // return 0;
+    std::string answer2 = templater.render("test", {&cba});
     printf("%s\n<a><f><t><e><r><><l><f>\n", answer2.c_str());
 
     return 0;