Posted in ColdFusion | Posted on 03-30-2007 | 2,939 views
For today's Friday Puzzler (remember those?), I'm going to describe a hypothetical situation that will be - unfortunately - a bit too familiar for most readers. You are a worker at MegaCorp Web, a large web design firm in greater Podunk. One of the banes of your existence is Bob. Bob is your cube mate. Bob loves to point out each and every little mistake on your web application, even in the middle of development. So it's time to get medieval on Bob and teach him a lesson.
Your task is to write a UDF that will take in a string of HTML. You will then find 10-15 random words that are not inside HTML tags. The words can be wrapped by tags of course, so the words in this block is fine:
For each word, you will then remove 1-3 random letters and replace it into the original HTML string.
What's going to make this so nice is how you would use this UDF in our hypothetical situation. As you know, Application.cfc's onRequest method can actually modify a request before it is returned to the user. What we would do is simply say:
2 <cfset newresult = confusinator(result)>
3 <cfoutput>#newresult#</cfoutput>
4</cfif>
Then just sit back and grin as Bob is unable to replicate the bugs on your machine.
Ok guys. Get to it. Let's teach Bob to leave well enough alone.
p.s. In case it isn't clear, you just need to build the UDF. Don't worry about Application.cfc and all that. If you want to build a simple form to let folks type in a URL and see the results, you get bonus points. 2 trillion bonus points will buy you nothing, but Web 2.0 Nothing.


Create a folder under a mapped path COM called tagLib
Make a file under it called a.cfm
Anywhere you can hide it in his code, add <cfimport taglib="/com/tagLib">
Now, for the source of a.cfm:
<cfif thistag.executionMode eq 'Start'><a href="www.owned.com"></cfif>
<cfif thistag.executionMode eq 'End'></a></cfif>
Now watch him rip his (thinning) hair out trying to figure out why his simple non-coldfusion <a href> tags are being re-written. =)
<cffunction name="confusinator" returntype="string" hint="Removes random letters from all words in a string that are not contained within HTML tags">
<cfargument name="theString" required="yes" type="string">
<cfloop condition="find('<', theString, 1) NEQ 0">
<cfset startPos = find('<', theString, 1)>
<cfset endPos = find('>', theString, startPos) + 1>
<cfset tagLen = endPos - startPos>
<cfset theString = removeChars(theString, startPos, tagLen)>
</cfloop>
<cfset newString = listToArray(theString, " ")>
<cfloop index="theWord" from="1" to="#arrayLen(newString)#">
<cfset stripCount = randRange(1, 3)>
<cfloop from="1" to="#stripCount#" index="i">
<cfif len(newString[theWord]) GT 0>
<cfset stripChar = randRange(1, len(newString[theWord]))>
<cfset newString[theWord] = removeChars(newString[theWord], stripChar, 1)>
</cfif>
</cfloop>
</cfloop>
<cfset theString = arrayToList(newString, " ")>
<cfreturn theString>
</cffunction>
code start =======================================
<CFFUNCTION NAME="tweakoutput" RETURNTYPE="STRING">
<CFARGUMENT NAME="theString" REQUIRED="YES" TYPE="STRING">
<CFSCRIPT>
var theResult = '';
var bodyFound = 0;
var scriptHit = 0;
var randRows = 0;
var theRows = '';
total = ListLen(theString, chr(10) & chr(13));
for (i = 1; i lt total; i = i + 1){
thisItem = listGetat(theString, i, chr(10) & chr(13));
if (thisItem does not contain "body" AND NOT bodyFound){
// we do not want to muck with anyting till we pass the body tag
theResult = theResult & chr(10) & chr(13) & thisItem;
continue;
} else {
bodyFound = 1;
if (randRows EQ 0){
// generate a random row numbers to alter
for (r = 1; r lt 50; r = r + 1){
thisNum = randRange(i, total);
if (listfind(theRows, thisNum)){
continue;
}
randRows = listAppend(randRows, thisNum);
}
}
}
if (thisItem contains "<script" AND Thisitem does not contain "/script"){
scriptHit = 1; // we do not want to edit the contents of a script
theResult = theResult & chr(10) & chr(13) & thisItem;
continue;
}
if (scriptHit AND thisItem contains "/script"){
scriptHit = 0; // found end of script;
}
if (NOT listfind(randRows, i)){
theResult = theResult & chr(10) & chr(13) & thisItem;
continue;
}
noTags = ReReplaceNoCase(thisItem, "<(.|\n)+?>", " ", "ALL");
if (listLen(noTags, " ")){
thisWord = ListGetAt(noTags, RandRange(1, listLen(noTags, " ")), " ");
if (len(thisWord) gt 3){
newWord = thisWord;
for(s=1; s lt randRange(1,3); s = s + 1){
newWord = removeChars(newWord, RandRange(1, len(newWord)), 1);
}
thisItem = replace(thisItem, thisWord, newWord);
}
}
theResult = theResult & chr(10) & chr(13) & thisItem;
}
return theResult;
</CFSCRIPT>
</CFFUNCTION>
code end =======================================
--Dave
Replace this:
if (scriptHit AND thisItem contains "/script"){
scriptHit = 0; // found end of script;
}
with this:
if (scriptHit AND thisItem DOES NOT contain "/script"){
theResult = theResult & chr(10) & chr(13) & thisItem;
continue;
}
scriptHit = 0; // found end of script;
Sorry about that.
--Dave
=======================================================
<cffunction name="messWithBob" access="public" returntype="string">
<cfargument name="textToDestroy" required="true" type="string" />
<cfscript>
var regex="</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>";
var arModContent = ArrayNew(1);
var lModContent = REReplaceNoCase(arguments.textToDestroy,regex," ","all");
var killList = "";
var wordstokill = 0;
var numLetters = 0;
var newWord = "";
</cfscript>
<cfloop list="#lModContent#" index="i" delimiters=" ">
<cfif Len(Trim(i))>
<cfset ArrayAppend(arModContent,i)>
</cfif>
</cfloop>
<cfif ArrayLen(arModContent) GT 15>
<cfset WordsToKill = RandRange(10,15,"SHA1PRNG")>
<cfelse>
<cfset WordsToKill = RandRange(1,ArrayLen(arModContent),"SHA1PRNG")>
</cfif>
<cfloop from="1" to="#WordsToKill#" index="j">
<cfset killWord = RandRange(1,ArrayLen(arModContent),"SHA1PRNG")>
<cfif NOT ListFindNoCase("cylon,borg",arModContent[killword])>
<cfset numLetters = RandRange(1,3,"SHA1PRNG")>
<cfset newWord = arModContent[killword]>
<cfloop from="1" to="#numLetters#" index="i">
<cfset newWord = RemoveChars(arModContent[killword],RandRange(1,Len(arModContent[killword]),"SHA1PRNG"),1)>
<cfif Len(newWord) LT (numLetters - i)>
<cfbreak>
</cfif>
</cfloop>
<cfset arguments.textToDestroy = Replacenocase(arguments.textToDestroy,arModContent[killword],newWord)>
<cfelse>
<cfset arguments.textToDestroy = Replacenocase(arguments.textToDestroy,arModContent[killword],"Dalek","all")>
</cfif>
</cfloop>
<cfreturn arguments.textToDestroy />
</cffunction>
That was one of the most delightfully evil things I have ever seen.
This isnt to be a "feature" in the next version of Blog.cfc is it??
Is "Bob" really a code name for "Those mugs in the CF world who dont write their own code but sponge off me instead"??
However, I like 'messing with Bob' because ironically you have to understand quite a bit of CF to see what's really going on with these fun little exercises.
Justice's entry is the kind of evil that would happen in Spy vs. Spy (if they were programmers). ;-)
[Add Comment] [Subscribe to Comments]