Today I got a comment on a blog entry from close to 6 years ago: ColdFusion 101: Config Files A-Go-Go (what was I thinking with when I picked that title??). The blog entry discusses ColdFusion native INI file processing. I use an INI file to config BlogCFC and have used it elsewhere in the past as a simple form of configuration. I'm not one of the anti-XML folks but you can't deny that an INI file is pretty simple to use. I've moved away from this type of configuration though due to the issues that ColdFusion's INI functions have with internationalization inside ini files. That being said, I was a bit surprised today Cori pointed out a bug with ColdFusion's getProfileString function.
Apparently INI files support a way to add comments. Wikipedia's entry says this:
Semicolons (;) indicate the start of a comment. Comments continue to the end of the line. Everything between the semicolon and the End of Line is ignored.
And a bit later goes on to say...
In some implementations, a comment may begin anywhere on a line, including on the same line after properties or section declarations. In others, any comments must occur on lines by themselves.
This last point is important. Depending on your implementation, you may allow for semicolon comments "inline" or only on a line by itself. ColdFusion definitely ignores inline comments. Let's look at an example. First, here is my INI file.
[main]
name=Raymond
age=37
coolness=high ; lies!
; What does this do?
[sub]
age=42
email=foo@foo.com
And here is a very generic "reader" for an INI file.
<cfloop item="section" collection="#sections#">
<cfoutput><h2>#section#</h2></cfoutput>
<cfset items = sections[section]>
<cfloop index="item" list="#items#">
<cfset value = getProfileString(inifile, section, item)>
<cfoutput>#item#=#value#<br/></cfoutput>
</cfloop>
<p>
</cfloop>
<cfset inifile = expandPath("./test.ini")>
<cfset sections = getProfileSections(inifile)>
When run, this is the output I get:
name=Raymond
age=37
coolness=high ; lies! sub age=42
email=foo@foo.com
main
As you can see, the inline comment is returned. The comment on the line by itself was not returned. With that said - I'd say ColdFusion's implementation isn't bugged - it's just strict about where comments are allowed. So that being said - is there an easy way to account for this? Sure. Consider this version:
<cfloop item="section" collection="#sections#">
<cfoutput><h2>#section#</h2></cfoutput>
<cfset items = sections[section]>
<cfloop index="item" list="#items#">
<cfset value = getProfileString(inifile, section, item)>
<cfif find(";", value)>
<cfset value = trim(listDeleteAt(value, listLen(value, ";"), ";"))>
</cfif>
<cfoutput>#item#=#value#<br/></cfoutput>
</cfloop>
<p>
</cfloop>
<cfset inifile = expandPath("./test.ini")>
<cfset sections = getProfileSections(inifile)>
I've simply added a find call in there and if a semicolon exists, we treat it as a list and chop off the end. Not rocket science, but useful if you have to parse INI files you don't have control over.