Recent Blog Posts by Ben Nadel
Inspecting The Form Upload File Field Metadata In ColdFusion
When you upload a file in ColdFusion, the fileUpload() function and the CFFile[action=upload] tag aren't actually uploading the file to the server—at that point in the workflow, the file already exists on the server. The fileUpload() function is just moving the file from a temporary location to a permanent location of your choosing. And, when you're uploading files through a standard form post, the form field that represents your file upload contains the path to that temporary location. Which means you can therefore inspect a file in ColdFusion before you move it to its permanent location... read more →
VARCHAR(Length) Limit Refers To Characters, Not Bytes, In MySQL
When you define a varchar field in a MySQL database table, you can provide a length limit, ex varchar(255). For as long as I can remember, I thought this limit referred to the number of bytes that could be stored in the field. And, to be fair, back when I was only consuming ASCII characters, this assumption was coincidentally true—one ASCII character is represented by one byte. In reality, this length limit refers to the number of characters that can be stored in a field, regardless of how many bytes are needed to represent said character string... read more →
Using JSoup To Report Untrusted HTML Elements And Attributes In ColdFusion
Yesterday, I took my first look at using JSoup to sanitize untrusted HTML in ColdFusion. Historically, I've been using the OWASP AntiSamy project to do the same thing; and while the JSoup approach feels more flexible is easier to consume, it's missing one important feature that AntiSamy had: an ability to report on which aspects of the untrusted DOM (Document Object Model) were being removed during the sanitization process. As such, I wanted to look at how I can use JSoup to report the untrusted HTML elements and attributes that were being removed in my ColdFusion processing... read more →
Using jSoup To Sanitize Untrusted HTML In ColdFusion
For years, I've been using the OWASP AntiSamy project to sanitize untrusted HTML in ColdFusion. And for years, James Moberg has suggested that I just use JSoup. I'm not one to switch tools unnecessarily. However, when I went to install AntiSamy in a new project and remembered just how many JAR files were required, I figured it was time to look at JSoup's single JAR approach to cleaning and sanitizing HTML... read more →
Safe-Navigation Operator Swallows Method Errors In Adobe ColdFusion 2023
This morning, I was running into a strange null-reference error in my ColdFusion dependency injector (DI). A CFProperty-based component wasn't being injected; but, no error was being thrown or logged. After commenting-out a bunch of code, I finally narrowed it down to a bug in ColdFusion. If you use the safe-navigation operator to invoke a component method, any error thrown in that method will be swallowed up and the method will be short-circuited. I confirmed this behavior in both Adobe ColdFusion (ACF) 2021 and 2023... read more →
Working Code Podcast - Episode 200: We're Taking A Break
After recording 200 episodes, we've decided to take a short break from the show. We never really had a plan going into this endeavor; and, there was no sense of a seasonal cadence to what we were doing. As such, we're gonna call this the end of "season one" and take a hiatus through the end of the calendar year 2024. In January, we'll regroup and start "seasons two". Thank you all for listening to the show and for following along on this journey... read more →
Feature Flags Book Playground, Videos, And Code
As a companion piece to my Feature Flags Book, I've created a feature flags playground to provide my readers with some lightweight hands-on experience. It's great to read about a concept in a book. But, some concepts don't become tangible until you can roll your sleeves up and get little bit dirty. This feature flags playground gives people an opportunity to define feature flags, add rules, target cohorts, and incrementally release new features to a demo user-base. The primary goal of this playground is to add dimension to the content of the book; but, if you want to see the underlying code, I've made it all available on GitHub—it's built in ColdFusion, Parcel.js, Alpine.js, and Less CSS and runs on Docker... read more →
Playing With Window Functions In MySQL 8
Earlier this week, I went through the High Performance SQLite course by Aaron Francis. Among the many SQL topics that he covered, he included something that I've never tried before: Window Functions. These functions allow you to calculate data based on the current row. These functions behave somewhat like a subquery that is locked-down to the existing result-set. And, which can be further subdivided using a partition column... read more →
High Performance SQLite Video Course By Aaron Francis
Last night, I finished the High Performance SQLite video course by Aaron Francis. It is one of the best video courses that I've taken to date. Aaron strikes the perfect balance between density of content, depth of discussion, levity, and flow. And the quality of the video production is outstanding—this is obvious from the very first video; and, remains consistent through to the end. Using a distraction-free staging context, Aaron delivers the information in bite-size morsels that are easy to consume. If you're interested in learning more about SQLite, I highly recommend this course... read more →
Working Code Podcast - Episode 199: Country Code TLDs
All 2-character top level domains (TLDs) represent country codes. For example, .us is the TLD for the United States; .ai is the TLD for Anguilla; and, .io is the TLD for the British Indian Ocean Territory. In addition to their original purpose, these TLDs have been heavily co-opted by the tech sector. Normally this wouldn't be an issue; however, the British government has recently ceded control over the India Ocean's Chagos island. This may obviate the need for an .io TLD. Which could mean—in theory—that .io domains eventually stop working. This gives us a moment to pause and reflect upon the practice of overloading country code TLDs... read more →
Running Memory Leak Detection After Every ColdFusion Request
In the comments of a post over on LinkedIn, I was talking to Charles Robertson about how unnerving it is to have unscoped local variables leak into the variables scope of a persisted component. This type of memory leak can lead to the cross-contamination of requests; and, in a worst case scenario, will cause one user's data to be shown to another user. Inspired by that conversation, I decided to add memory leak detection to the post-processing of every ColdFusion request in my feature flags playground application... read more →
Collocating My ColdFusion, CSS, And JavaScript Files
When building a ColdFusion multi-page application (MPA), I've never been satisfied with how files are organized. Client-side files (CSS and JS) that are tightly coupled to server-side files (CFML) are often located in completely different parts of the application's folder structure. This adds friction to the maintenance of the ColdFusion application. In an effort to experiment with a more cohesive file strategy, I want to try putting CSS and JavaScript files right next to their CFML counterparts... read more →
Dave Farley On What Makes High Quality Code
This morning, on the latest episode of the Engineering Room podcast, Dave Farley said something about code quality that really connected with the way in which I see software development. In the past, I've talked about the importance of writing code that's easy to find and easy to delete. But, both of these concepts tactically roll-up in a higher-level strategy that Dave identifies: write code that's safe and easy to change:.. read more →
Making A Case For Var Declarations In ColdFusion Templates
Last week, I opened a feature request in the Adobe bug tracker to allow for var declarations in CFML templates. After I opened this, I shared it within the Working Code discord; and, all those who responded did so in opposition to the idea. As such, I wanted to take a moment to more clearly articulate my case for allowing var declarations in, essentially, any ColdFusion context... read more →
CSV To CTE Transformer In Angular 18
When generating reports at work, I make heavy use of common table expressions (CTE) as well as the VALUES / ROW construct to create derived tables in MySQL 8. Thanks to the awesome power of SublimeText multi-cursor functionality, going from CSV (comma separated values) to CTE only takes a minute or two; but, it's a repetitive task that I'm keen to create a utility for (see my blog's utilities section). As such, I wanted to create a rough draft of this utility using Angular 18... read more →
Working Code Podcast - Episode 197: Potluck
On this week's show, we talk about a variety of topics. Adam examines the notion that you get promoted into the job that you're already doing. Carol discusses the AI training course that she just took in order to start using chat-bots in government work. Tim talks about leading your team through hard times; and how to focus on the one most important goal. And I lament the idea that I don't spend enough time sitting alone with my thoughts and connecting with the world at large... read more →
Using Canonicalize() To Embed Emoji In Email Subject Lines In ColdFusion
In my previous post on using canonicalize() to render emoji characters in ColdFusion, I mentioned that this technique can be helpful in contexts where HTML entities aren't well supported. Email subject lines appear to be one such context; as I discovered yesterday when trying to add a police siren emoji to an email subject line for a time-sensitive (expiring) link. To get around this, we can use the canonicalize() function to embed emoji safely within email subject lines in our CFML... read more →
Using Canonicalize() To Render Emoji In ColdFusion
In ColdFusion, the canonicalize() function is used to reduce a given string down to its simplest form. This is typically used during user input sanitization and validation; but, this normalization process can also be used to convert HTML entities into their associated characters. In other words, we can use the canonicalize() function to convert encoded emoji characters into native emoji glyphs... read more →
Working Code Podcast - Episode 195: Isn't Worth The Squeeze
On a recent episode of the Economics of Everyday Things, Zachary Crockett explains that the perfect amount of money laundering is not zero. Attempting to eliminate all money laundering would be so disruptive to commerce that the net-loss of such an extreme position would far outweigh the potential benefits. Over here on our podcast, that got us thinking about areas within our work in which lofty goals aren't worthwhile. Topics include error logs, code coverage, feature completeness, consistency, time tracking, elegance, and requirements gathering... read more →
Dynamically Define For-Loop Increment In ColdFusion
In my Lopem Ipsum generator, I take a collection of paragraphs and I split them up into sections of random lengths. To do this, I iterate over the collection using a dynamically defined increment. In other words, the "step" value is randomly assigned on every for-loop iteration. I don't think I've ever done this before; and it worked like a charm. So, I thought it was a mechanic worth sharing in ColdFusion... read more →
Generating Lorem Ipsum Text In ColdFusion
As a fun code kata for my /utils section, I wanted to create a Lorem Ipsum text generator. Lorem Ipsum is a common way to create placeholder text during the design phase of the prototyping process. Lorem Ipsum text uses Latin words to embody English-looking text distributions without the distraction of being readable (except by those 4 people who took Latin classes in high school). What follows is my attempt to generate this placeholder text in ColdFusion... read more →
ColdFusion: Comparison Method Violates Its General Contract
This week, a single instance of an error showed up in my ColdFusion logging: "Comparison method violates its general contract!". The stacktrace pointed to something in the Java layer called TimSort; which is what ColdFusion's Array.sort() method is using under the hood. This error may be thrown if the .sort() callback / operator doesn't adhere to the set of requirements defined by the Comparable interface... read more →
Working Code Podcast - Episode 193: Bonding In The Foxhole
Without a doubt, there is a special bond formed between people who've shared an intense experience. At work, we see this all the time during incident triage and remediation—there is something truly special about those Zoom calls in which everyone on the team is suddenly on the same page and is working with a singular purpose. But, do we end up glorifying these metaphorical foxholes? Can we build those lasting bonds during the good times? Or, is there something unique about a company that has gone through trial-by-fire?.. read more →
TODO: Granting Yourself Permission To Move Forward
I just read Chris Ferdinandi's latest newsletter, Gardening and code, about the importance of solving the problems in front of you. In it, Chris touches upon an issue that we all struggle with at some point: feeling like our first solution has to be the perfect solution. It reminded me of a powerful cognitive tool that I use in my own programming: the TODO: comment... read more →
Signals And Array Mutability In Angular 18
Like many change detection mechanisms, Signals in Angular 18 rely on reference changes in order to trigger change detection. When consuming simple values, this is fine because simple values are passed by value, not by reference. But, when wrapping complex objects in a Signal, the mutability of objects becomes a point of consideration. It's important to understand how the change detection mechanisms in Angular work so that you don't end up falling down the immutability rabbit-hole... read more →
Exploring Lazy Evaluation Of Computed Signals In Angular 18
Yesterday, on Episode 192 of the Working Code podcast, I expressed a fear that the magic of reactivity might lead to unanticipated performance issues when a computed value relies on more than one dependency. But, this fear was purely theoretical. And, it turns out, unwarranted. Computed values in Angular 18 are lazily evaluated. Meaning, they are not computed until they are actually read. And, if they're never read, they're never computed. This post is a small exploration of these Signal timing mechanics in Angular 18... read more →
Building An Angular App For ColdFusion Using Docker Compose
In a world where containerized development exists, I feel like a failure any time I have to run a build script—such as npm install or nvm use—directly on my host computer. Containers should be obviating this type of workflow. But, the problem is, I'm not really that good at containerization. Recently, however, I had a mental breakthrough. I realized that my JavaScript builds didn't have to execute inside my ColdFusion container; instead, I could use a separate Node.js Docker container to perform the build and then output the distribution files to my ColdFusion container... read more →
Working Code Podcast - Episode 192: The Best And Worst Code
On today's show we discuss some of the best code that we've seen and some of the worst code that we've seen. But, "best" and "worst" are fuzzy terms. What does it meant when we even talk about code quality? Does it relate to the maintainability of the code? Does it pertain to revenue generation for the company or how many problems were solved for the customer? Is it about being DRY (Don't Repeat Yourself) or WET (Write Everything Twice) in your intentions? How much does debuggability and logging matter? And, is the best code really just the most boring and predictable code?.. read more →
Working Code Podcast - Episode 191: Too Much Process
People have a lot of trouble existing in the grey. I think we all understand that too much process exists. But, we don't know what to do about it. We have a lot of evidence that in critical arenas—such as medical care and flying planes—that checklists do save lives. But, at the same time, we all believe that spelling corrections on a website don't call for full regression testing. And yet, we do full regression testing anyway. Because, we either don't understand nuance; or, we work at companies that don't allow for human judgement within the decision making framework... read more →
Creating A Transient View Helper In Angular 18
One of the really nice features of Angular 18 is the ability to use a DestroyRef injectable to define your component's clean-up logic. This allows your setup and teardown logic to be collocated within the ngOnInit() life-cycle method. In order for the DestroyRef functionality to work, its own life-cycle has to be married to the host component's life-cycle. Which got me thinking about creating my own transient "View Helper" service that might make other workflows easier... read more →