ColdFusion, INI files, and comments

This post is more than 2 years old.

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.

<cfset inifile = expandPath("./test.ini")> <cfset sections = getProfileSections(inifile)>

<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>

When run, this is the output I get:

main

name=Raymond age=37 coolness=high ; lies!

sub

age=42 email=foo@foo.com

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:

<cfset inifile = expandPath("./test.ini")> <cfset sections = getProfileSections(inifile)>

<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>

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Brian posted on 2/17/2011 at 8:28 PM

Knowing your input stream is important -- even more so if the INI file allows escaping of semi-colons as documented in that page -- some may escape with a backslash, some may enclose in quotes -- so the "chop off the last nibbly bit" may not always be the most effective solution -- although it will force the INI provider to rethink their data if they're using semis as a significant value...

Having a squiggly spec seems to be all too common in the computing world. CSV. HTML. Number of beers consumed to get you feeling tiddly but not drunk...

Comment 2 by Carol posted on 2/18/2011 at 1:14 AM

Great information, Jedi! How come this doesn't work though:

file = "G:\My Documents\Pics\.picasa.ini";
xx = getProfileSections(file);

CF doesn't like a variable passed into getProfileSections()?

Comment 3 by Raymond Camden posted on 2/18/2011 at 1:16 AM

Sorry - how is it failing?

Comment 4 by hmmmm posted on 4/4/2012 at 4:35 AM

just by and by, I know this is an old post, but just seen it....either make sure your ini files are not downloadable (outside webroot) or make them .cfm and surround by cf comments that way if found (or even funnier, indexed by google) the contents are not visible like so
&lt---
;secret mans business
[live]
somethingthatshouldnotbeknown=thisvalue
---&gt

Comment 5 by scott johnson posted on 3/3/2014 at 10:52 PM

you say you've moved away from .ini files, but what to? xml configu files or something else entirely?

Comment 6 by Raymond Camden posted on 3/5/2014 at 7:45 PM

I'd either use XML or JSON. Probably JSON more nowadays.