So, I'm building a system that allows users to create document templates. I have a pretty simple, human readable way of adding "dynamic" data to the templates:
#firstName from client#" <--- where "client" is a ref(), and firstName would be a property of that object.
Now, I can figure out how to replace these tags with the actual data without using eval(). Now, obviously I can't trust what people enter here, so I have an array of "allowedTags", and when I parse, I only parse the RegEx matched list of #..# values. So they can't do anything like #someEvil code here from SomeOtherEvilStuff" because it won't be an allowed tag.
Is this really that bad, or is there another way to dynamically replace using ref() values?
function processTemplate(text: string): string {
const re = new RegExp(/#\w+ from \w+#/, 'g')
const matches = text.match(re) ?? []
for (const match of matches) {
if (!allowedTemplateTags.includes(match)) {
continue
}
const split = match.replace(/#/g, '').split(' from ')
const replaceRegEx = new RegExp(`(${match})`, 'g')
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
text = text.replace(replaceRegEx, eval(`${split[1]}?.value.${split[0]}`))
}
return text
}
So basically what you want is access variables of which you get the name from the user? My approach would be to have a reactive data object and just use the strings to point at the correct entry.
import { reactive } from ‘vue’;
// For the idea: these two strings you get from the user
const string1 = ‘firstName’;
const string2 = ‘client’;
const data = reactive({
client: {
firstName: ‘John’,
});
const text = data[string2][string1] // text will be ‘John’
data[string2][string1] = ‘Anna’; // now firstName will be ‘Anna’
I did not test this code, but I think you get the idea.
Hope this helps.