B and E Blog

Just a couple of opinionated nerds talking about ColdFusion, PHP, and technology in general.

B and E Blog header image 1

Follow up to Real Time Command Execution Feedback Post

April 9th, 2008 · ColdFusion, Programming

With ColdFuison 8.0.1 Adobe has introduced errorVariable and/or errorFile to the attributes of the tag. You can only use one of the two in the same tag.

This will give some insight once the tag has completed execution if there is an error. Before there was no way for CF to report errors to a file or to the browser.

→ No CommentsTags:

Speed Limiter

April 8th, 2008 · Debugging, Programming

Once in a while you need to simulate what a user experience will be at a certain connection speed. I’ve added up data sizes and times and did some math to figure out what the numbers will be, but this ignores tcp and http header overhead.

Fortunately there exists a simple tool for Windows to let you simulate any connection speed to any TCP port from any TCP client. Notably, web browsers are TCP clients which connect to TCP ports.

The tool is called Speed Limiter, and it’s freeware (an English download page can be found here). It includes some special functions related to HTTP, but it can be used for any protocol.

→ No CommentsTags: ·

ColdFusion Preserve POST variable name case

April 1st, 2008 · ColdFusion, Programming

ColdFusion provides access to POSTed data via the FORM structure. Unfortunately ColdFusion always upper-cases the names of these variables. Recently a chunk of code I was working on needed to know the original case of these keys. At first I worked on passing a hidden form field with the original field name text, but this bothered me as way too much of a work-around.

This chunk of code will give you a structure called FormContent where the case of the field names is preserved.

  1. <cfset keys = ListToArray(GetHttpRequestData().content, '&')>
  2. <cfset FormContent = StructNew()>
  3. <cfloop from="1" to="#ArrayLen(keys)#" index='x'>
  4. <cfset key = ListFirst(keys[x], '=')>
  5. <cfset val = ListDeleteAt(keys[x], 1, '=')>
  6. <cfset FormContent[URLDecode(key)] = URLDecode(val)>
  7. </cfloop>

Unfortunately this code will not distinguish between two fields with the same name but different case. To do that, you’ll want to use a case-sensitive StructNew() alternative. I recommend CreateObject(”java”, “java.util.LinkedHashMap”).init(). This has the added value of preserving the order that the fields appeared in the calling form when you iterate over it for output. It has the disadvantage that you’ll have to properly match case of the keys when you retrieve them in your code.

→ 3 CommentsTags:

ColdFusion REMatchAll

April 1st, 2008 · ColdFusion, Programming

This ColdFusion method offers functionality similar to PHP’s preg_match_all function. It searches for the supplied regular expression in the supplied text. The return value is an array with one entry for each time the pattern matches the string. The array entries are structs with a numbered element for each parenthesized sub-expression within the match, and a zero-entry for the whole match.

It’s probably easier to see example data.

  1. <cfset text = "Test {foo|bar|baz} testing {moo|boo} Another test {zoo} test.">
  2. <cfset pattern = "{([a-z]+)(?:\|([a-z]+))?(?:\|([a-z]+))?}">
  3. <cfdump var="#ReMatchAll(pattern, text)#">

Screenshot of the dump result from a ReMatchAll call

As you can see, it returns every match, position, and full text of the match, as well as each parenthesized subexpression. The example pattern basically matches {foo|bar|baz}, {foo|bar}, or {foo}, and returns the alphabetical sub-components as the sub-expressions.

Here is the code.

  1. <cffunction name="REMatchAll">
  2. <cfargument name="regexp">
  3. <cfargument name="haystack">
  4. <cfset var start = 1>
  5. <cfset var result = ArrayNew(1)>
  6. <cfset var test = "">
  7. <cfset var tmp = "">
  8. <cfset var x = "">
  9. <cfloop condition="start gt 0">
  10. <cfset test = REFind(regexp, haystack, start, true)>
  11. <cfset tmp = StructNew()>
  12. <cfif ArrayLen(test.len) gt 0 and test.len[1] gt 0>
  13. <cfloop from="1" to="#ArrayLen(test.len)#" index="x">
  14. <cfset tmp[x-1] = StructNew()>
  15. <cfif test.pos[x] gt 0>
  16. <cfset tmp[x-1].start = test.pos[x]>
  17. <cfset tmp[x-1].len = test.len[x]>
  18. <cfset tmp[x-1].text = mid(haystack, test.pos[x], test.len[x])>
  19. <cfelse>
  20. <cfset tmp[x-1].start = 0>
  21. <cfset tmp[x-1].len = 0>
  22. <cfset tmp[x-1].text = ''>
  23. </cfif>
  24. </cfloop>
  25. <cfset result[ArrayLen(result)+1] = tmp>
  26. <cfset start = tmp[0].start + 1>
  27. <cfelse>
  28. <cfset start = 0>
  29. </cfif>
  30. </cfloop>
  31. <cfreturn result>
  32. </cffunction>

→ No CommentsTags: ··

Spry Email Validation

March 31st, 2008 · Programming

First you have to include the js and css files for the spry framework. In this example taken from the spry demos we have two files. Both are designed for text fields.

  1. <link href="../../widgets/textfieldvalidation/SpryValidationTextField.css" rel="stylesheet" type="text/css">
  2. <script type="text/javascript" src="../../widgets/textfieldvalidation/SpryValidationTextField.js">

The actual form field will be wrapped in a div or span tag with an id. Any messaging then gets its own span class within the div.

  1. <div id="theTitle">
  2. <input name="movieName" type="text" id="theMovieTitle">
  3. <span class="textfieldRequiredMsg">Please enter a title.</span>
  4. </div>

Below the form on the page, the following scripting is added. This will validate that there is a correct email typed into the text field. Validating on change checks the field on each character entered. For emails it would be better to validate on blur. The user will not get constant reminders as they type.

  1. <script type="text/javascript">
  2. var theTitle = new Spry.Widget.ValidationTextField("theTitle", "email", {useCharacterMasking:true, validateOn:["blur","change"]});
  3. </script>

Notice that there’s no Regex on the screen. I didn’t need any, the Spry framework took care of it.

→ 1 CommentTags: ··

iWoz Review

March 29th, 2008 · books

iWoz was an interesting read. He basically spoke the book and his co-author put his ramblings into print. The book reads like he talks, so the style took a few pages to get used to.

It is a very good insight to the beginning days of computers. Before reading the book, I really had no idea what it was like 30+ years ago.

I had an Atari in the 70’s. I remember the Pong and Breakout games. I’ve never linked those games and systems to what would become the personal computers of today. The book details the journey from hand drawing the chips on paper, through games like Breakout to the Apple I and II.

Steve Wozniak is a gifted engineer and visionary. I recommend reading this book to get a better insight on the man and process behind the first personal computer.

→ No CommentsTags: ·

Photoshop Express

March 28th, 2008 · Image Editing, Software

Adobe released Photoshop Express.

Looks like a very slick flex application. Similar interface to the share site that Adobe has to share documents.

I have limited photos at work, but I’ll continue to play with this over the weekend. It seems to have improved photo editing capabilities and it can login into Picasa/Facebook/Photobucket and get pics from those apps.

Nice job adobe.

→ 1 CommentTags: ··

Hacker Super Bowl

March 27th, 2008 · security

At this year’s CanSecWest, there are three computers set up for open hacking, one running Vista, one running OSX, and one running Ubuntu Linux. Hacks must be done with a new zero-day exploit (that is, it can’t be an already known-about crack).

Organizers have worked to make the attack surface area the same on each system. That’s important because each OS comes with a different amount of pre-installed software — from Vista’s “it’s up to you to install anything useful” to OSX’s “We’ll give you a common set of simple tools” to Ubuntu’s “What do you want to do today? It’s already installed or available with a click.”

Day 1, the cracks must only be done over the network in non-user-interactive mode, and the prize is $20,000
Day 2, the cracks must only be done against software which is already installed, but it can involve tricking the user. Prize is $10,000
Day 3, the cracks can be done against a suite of commonly installed software, but the prize is only $5,000.

Update: Two minutes into day two, the Macbook Air was the first of the three systems to fall, due to an exploit against Safari.
Update 2: Late into the third day, the Vista laptop fell to a exploit against Adobe Flash. Ubuntu wins the contest.

→ 2 CommentsTags: ···

Regular Expression for Validating Email Addresses

March 27th, 2008 · Programming, Regular Expressions

This is the regular expression I use to validate email addresses:
Thought it might be useful to some folks. Most email validation regular expressions fail to allow all the valid characters before the @ sign (for example, you can have a +, an & slashes, a single quote, =, ?, ^, _, {, }, ~, *).

In ColdFusion, you can test an address with:

  1. <cfif ReFindNoCase("^[&'*+\/=?^_{}~a-z0-9.-]+@([a-z0-9-]+\.)+[a-z0-9]+$", emailAddress)>

In Javascript, you can test with:
if (emailAddress.match(/^[&'*+\\/=?^_{}~a-z0-9.-]+@([a-z0-9-]+\.)+[a-z0-9]+$/i))

In PHP, you can test with:
if (preg_match("/^[&'*+\\\/=?^_{}~a-z0-9.-]+@([a-z0-9-]+\\.)+[a-z0-9]+$/i", $emailAddress))

→ 2 CommentsTags: ·

Real Time Command Execution Feedback

March 27th, 2008 · ColdFusion, Programming

Did you ever write a utility ColdFusion script which uses <cfexecute> to run a command and send output back to the browser? It makes for convenient and monitorable remote execution of certain repetitive tasks. My most common use for this sort of thing is for example an rsync process which can be invoked from anywhere in the world, and most recently I’ve been working with Selenium-RC to set up regression test scenarios which can be initiated by business users and business analysts without having to have Selenium IDE installed or know how to use it.

I’ve always found it frustrating though when the task is long-running, and potentially error-prone to not know the success or failure, until the entire command has been executed, and even more frustrating not knowing if it has hung up for some reason today, or does it just have a lot more work to do today than normal?

This little snippet will use Java runtime to capture and pipe the output of the program back to the browser in real time. There’s a couple of caveats surrounding needing to not be used inside a forced-buffer area (like <cfsavecontent>), but otherwise this should work just fine. That means you can’t really use it inside most modern CF frameworks which depend heavily on <cfsavecontent> and the like.

Standard input (stdin) is shut down right at the start of execution; if you wanted to interact with the program in some way (such as to script some responses to prompts), you could undo that and write to it. Standard output (stdout) and standard error (stderr) are sent to the browser and flushed in nearly real time (stderr outputs in red to boot). I use a non-busy sleep via a Java thread to check in on the running program once a second for new output. Return value is a structure containing the elements exitValue, stdOut, and stdErr, so you can do further processing with it after the fact.

Anyway, enough blather, here is the code. This is not hyper-efficient (too many string concatenations and HTMLEditFormats), so I don’t recommend you use it in any high volume situations, especially if there’s a lot of output expected from your command, but it’s been sufficient for my needs.

  1. <cfscript>
  2. function executeRealTime(script) {
  3. var runtime = CreateObject("java","java.lang.Runtime").getRuntime();
  4. var thread = CreateObject("java", "java.lang.Thread");
  5. var process = runtime.exec(script);
  6. var inputStream = process.getInputStream(); // Std Out
  7. var errorStream = process.getErrorStream(); // Std Err
  8. var outputStream = process.getOutputStream(); // Std In
  9. var continueLoop = true;
  10. var count = 0;
  11. var x = 0;
  12. var char = 0;
  13. var outputReceived = false;
  14. var result = StructNew();
  15. // We are not passing any std in, close it in case this process is waiting for user input
  16. outputStream.close();
  17. result.stdOut = ";
  18. result.stdErr = ";
  19. result.exitValue = -1;
  20. writeOutput("
  21. <pre>");
  22. while(continueLoop){
  23. try {
  24. //this will throw an exception if the process hasn't exited yet.
  25. process.exitValue();
  26. continueLoop=false;
  27. }catch (Any e){}
  28. outputReceived = false;
  29. while(inputStream.available() gt 0){
  30. outputReceived = true;
  31. for (x = 1; x lte inputStream.available(); x=x+1){
  32. char = inputStream.read();
  33. if (char gte 0){
  34. char = chr(char);
  35. result.stdOut = result.stdOut &amp; char;
  36. writeOutput(HTMLEditFormat(char));
  37. }else{
  38. continueLoop = false;
  39. }
  40. }
  41. }
  42. while (errorStream.available() gt 0){
  43. outputReceived = true;
  44. writeOutput("<span style="color: red;">");
  45. for (x = 1; x lte errorStream.available(); x=x+1){
  46. char = errorStream.read();
  47. if (char gte 0){
  48. char = chr(char);
  49. result.stdErr = result.stdErr &amp; char;
  50. writeOutput(HTMLEditFormat(char));
  51. }else{
  52. continueLoop = false;
  53. }
  54. }
  55. writeOutput("</span>");
  56. }
  57. if (outputReceived) {
  58. thread.sleep(10);
  59. } else {
  60. thread.sleep(1000);
  61. }
  62. flush();
  63. }
  64. result.exitValue = process.exitValue();
  65. WriteOutput("</pre>
  66. Done (#result.exitValue#).
  67. ");
  68. flush();
  69. thread.sleep(1000);
  70. return result;
  71. }
  72. </cfscript>
  73. <cffunction name="flush"><cfflush></cffunction>

Example usage:

  1. <cfset result = executeRealTime("rsync -rtv ""#SourceDir#"" ""#DestDir#"" ")>

→ No CommentsTags: ··