For years, I've been using regular expressions as a means to traverse file paths in my ColdFusion applications. By chopping-off the last directory "pattern" in a file path, I was able to move up into the parent directory:
<!--- Get the current directory. ---> <cfset currentDirectory = getDirectoryFromPath( getCurrentTemplatePath() ) /> <!--- Get parent directory by chopping off the last directory of the current directory path: /(xxxxxxxx/) ---> <cfset parentDirectory = reReplace( currentDirectory, "[^/]+/$", "", "one" ) /> <!--- If the Hello file exists, execute it. ---> <cfif fileExists( parentDirectory & "relative_paths/subfolder/hello.cfm" )> <cfinclude template="./subfolder/hello.cfm" /> </cfif>
Here, you can see that I am using the reReplace() method to move up the currentDirectory path in order to obtain the parentDirectory path. Then, I am using this parentDirectory path in a fileExists() call. This code successfully runs and outputs the following message:
Hello from the SubFolder!
This works. But, it lacks clarity and readability. While the intent may be evident from my variable name choices, the implementation may remain a mystery to anyone who's not comfortable with regular expressions.
In the last few months, I've abandoned this convoluted approach to path traversal and replaced it with relative-path constructs in my ColdFusion path logic:
<!--- Get the current directory. ---> <cfset currentDirectory = getDirectoryFromPath( getCurrentTemplatePath() ) /> <!--- Get the parent directory using relative pathing. ---> <cfset parentDirectory = (currentDirectory & "../") /> <!--- If the Hello file exists, execute it. ---> <cfif fileExists( parentDirectory & "relative_paths/subfolder/hello.cfm" )> <cfinclude template="./subfolder/hello.cfm" /> </cfif>
Here, rather than chopping off the last directory, I am simply adding the relative-path construct, "../", to my currentDirectory value. And, when I run this code, I get the following output:
Hello from the SubFolder!
Not only does this work, it's significantly more intuitive than the regular-expression-based approach.
I used to dislike the idea of having "../" constructs in my ColdFusion file paths. But, this fear was emotional. For some reason, it felt dirty; like there was "clean up" left to be done on the file path and I wasn't doing it. But, I have since overcome this emotional limitation and started using the easier, more intuitive, more maintainable notation in my ColdFusion file paths.
A Note On Security
Using relative-file-path constructs can be dangerous if you're letting your uses define or manipulate paths. This is why (I believe) "../" constructs are disabled, by default, in ASP Classic applications. If you are using "../" file paths as part of your internal configuration, however, there is absolutely no security exposure.
Want to use code from this post? Check out the license.