[Closed] How do fight a Crazy node name?
the max allows to name a node with probably no a limitations… for many years i used some ‘insure’ method to make a node’s name executable…
let’s say the node is named THE NODE. to execute this name i can do:
execute ("$'" + node.name + "'")
well... but what if the name is [[b]THE NODE]*[/b], or worse [b]\[[b]THE' 'NODE]\*[/b][/b]?
simple single-quotation does work anymore.
ok... we can add "\" before every special literal. the name will look like [b]\\\[[b]THE\' \'NODE\]\\\*
[/b][/b]that will work.
the simple function that might ensure the name can be:
fn getInsureName node =
(
name = substitutestring node.name "\\" "\\\\"
name = substitutestring name "*" "\*"
name = substitutestring name "[" "\["
name = substitutestring name "]" "\]"
name = substitutestring name "'" "\'"
"'" + name + "'"
)
that is a list of known by me special literals... may be there are some more. but the function already looks ugly.
does anyone see a smarter way?
edit
here is some cleaner version but it’s still ugly:
fn getInsureName node =
(
literals = "\*[]'"
name = node.name
for k=1 to literals.count do name = substitutestring name literals[k] ("\\" + literals[k])
"'" + name + "'"
)
that’s what i said… i forgot the question mark… so literals are *[]’? now
I might be overlooking something (has to be the case), as for me simple getNodeByName call works for all these cases (provided that the \ is properly escaped (max 9 here, no verbatim string) )
getNodeByName works well if need a single node. i need sometimes a pathname, like all namesake nodes, or node with children, or a property path… in short, everything what PathName is for.
Hmm, (dotNetClass “System.Text.RegularExpressions.Regex”).Escape catches some, not all though (and many undesired too)… Intriguing question.
… is the real problem. i can make the Regex but with the Regex the function will look worse
Yeah, fugly… (dotNetClass “System.Text.RegularExpressions.Regex”).Replace str “[[]\*’?]” “\$0”
so we have a leader:
struct NodeNameExt
(
private
regex = dotNetClass "System.Text.RegularExpressions.Regex",
pattern = "[\[\]\\\*'?]",
replacement = "\\$0",
public
fn insureName node =
(
"'" + (regex.Replace node.name pattern replacement) + "'"
)
)
/*
nne = NodeNameExt()
nne.insureName <node>
*/
which is a little slower than ‘substitutestring’ used version but… and it’s very important… the regex version in the structure eats 4 time less memory
let’s continue have a fun
struct NodeNameExt
(
private
regexClass = dotnetclass "System.Text.RegularExpressions.Regex",
pattern = "[\[\]\\\*'?]",
replacement = "\\$0",
stringClass = dotnetclass "System.String",
format = "{1}{0}{1}",
public
fn doubleEnd name end:"'" = stringClass.Format format name end,
fn insureName node = (doubleEnd (regexClass.Replace node.name pattern replacement))
)
On a different but still related note. I much prefer to capture all potential illegal characters at source. ie: use callbacks to capture any dodgy user input and this is the key – BEFORE it can do any damage further downstream in the pipeline.
Of course, you need to have exceptions such as “.Target” must be allowed
we used to do the same, it was a big stick we used to beat the artists with.