ventojs / vento

🌬 A template engine for Deno & Node
https://vento.js.org/
MIT License
212 stars 12 forks source link

auto_trim plugin throws if there are no `next` tokens #73

Closed micmath closed 4 months ago

micmath commented 4 months ago

If a template starts and ends with an if block, auto_trim throws.

To reproduce:

import vento from 'ventojs';
import autoTrim from 'ventojs/plugins/auto_trim.js';

const env = vento();
env.use(autoTrim());

const input = "{{ if 1 }}it works{{ /if }}";

const result = await env.runString(input); // throws

console.log (result.content);

This will throw the following error:

file:///example/node_modules/ventojs/esm/plugins/auto_trim.js:33
            next[1] = next[1].replace(/^[ \t]*(?:\r\n|\n)/, "");
                          ^

TypeError: Cannot read properties of undefined (reading '1')
    at autoTrim (file:///example/node_modules/ventojs/esm/plugins/auto_trim.js:33:27)
    at file:///example/node_modules/ventojs/esm/plugins/auto_trim.js:20:52
    at Environment.tokenize (file:///example/node_modules/ventojs/esm/src/environment.js:72:28)
    at Environment.compile (file:///example/node_modules/ventojs/esm/src/environment.js:39:29)
    at Environment.runString (file:///example/node_modules/ventojs/esm/src/environment.js:31:31)
    at file:///example/bugz/if.js:9:26
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:34:7)
    at async handleMainPromise (node:internal/modules/run_main:106:12)

The problem is that when the input string does not create next tokens, the expression next[1] cannot be evaluated.

Changing the input value to "{{ if 1 }}it works{{ /if }}anything" shows that the extra text allows auto_trim to work again.

I suspect this could be fixed by modifying ventojs/esm/plugins/auto_trim.js:33 to be defensive of the case where there are no next tokens:

            // Remove trailing horizontal space + newline
-            next[1] = next[1].replace(/^[ \t]*(?:\r\n|\n)/, "");
+            if (next) next[1] = next[1].replace(/^[ \t]*(?:\r\n|\n)/, "");
oscarotero commented 4 months ago

Good catch! I just released a new version with a patch for this bug. 1.12.10 should work fine.