CodeSOD: Classic WTF: RegExp from Down Under |
"The company I work for sells vacation packages for Australia," writes Nathan, "and for whatever reason, they're marketed under different two different brands — redacted-travel.com.au and redacted-travel.com — depending on whether you live Down Under or somewhere else in the world."
Nathan continues, "one of the requirements for the international website (redacted-travel.com) is to disallow people from within Australia and New Zealand to make bookings. But the way this is done from the front end... well, it's a real gem."
/** *Checks to see if Australia is typed into the other country box */ function checkContactCountry(inputBox) { var validator = new RegExp( /^(A|a)(U|u)(S|s)(T|t)(R|r)(A|a)(L|l)(I|i)(A|a) |(N|n)(E|e)(W|w)(Z|z)(E|e)(A|a)(L|l)(A|a)(N|n)(D|d) |(N|n)(E|e)(W|w) (Z|z)(E|e)(A|a)(L|l)(A|a)(N|n)(D|d)$/); if(validator.test(inputBox.value)) { alert("Your Residential Address must be outside Australia. " + "Enter your residential address outside this country," + "or visit redacted-travel.com.au to make a booking if " + " you live in Australia."); inputBox.focus(); inputBox.select(); } }
[Advertisement] Release!
is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
http://thedailywtf.com/articles/classic-wtf-regexp-from-down-under
|
Метки: CodeSOD |
Classic WTF: Manual Automation |
Aikh was the new hire on the local bank’s data warehousing/business intelligence team. His manager threw him right into the hurricane: a project with the neediest, whiniest and most demanding business unit. Said business hated their unreliable batch process for archiving reports, and the manual slog of connect > find/create directory > upload > pray. They hoped the DW team would code to the rescue.
Eager to impress, Aikh sketched out a simple, automated client/server solution. The business quickly approved his design and estimates. To mentor and keep the project on-track, Aikh’s manager assigned Dean, a more senior developer, to help out.
![]()
What do you mean, steam powered hammer?
“I could really use a good library to transfer files via secure shell,” Aikh told Dean during their initial meeting.
Dean leaned back in his chair with confident disinterest. “I know a good open-source package. I’ll build you a wrapper.”
A month passed. Aikh hammered out the UI and daemon, and now needed to write the code for file transfer. However, he’d never received anything from Dean. Aikh hadn’t wanted to nag- surely Dean had several important projects on his plate- but found himself stymied. He visited the senior dev’s cube to inquire about the library and wrapper.
“Oh, right,” Dean said, never pausing from his typing. “I’ll email the package in couple of days.”
Aikh received the open-source library as promised… and an executable file that simply displayed an empty command prompt. He was back at Dean’s cube in short order. “What’s this?”
Dean narrowed his eyes, not sure he was dealing with a sentient creature. “It’s waiting for a command. See?” He demoed an execution, typing rapidly and without explanation.
“This, uh, isn’t what I’m looking for,” Aikh said. “I need something to integrate with my Java application.”
“Execute this with the Runtime class, then pass in commands.” Dean had already tabbed back to Facebook.
Aikh tamped down his aggravation. “Sorry, but, can you please just write a wrapper and jar it up for me?”
Several days later, Dean sent a jar file containing the class, no comments. Aikh replied to the email. Any documentation on how to use this?
Another few hours, and Dean replied with a single line:
SFTPWrapper.write( srcDir, tgtDir, user, pass ); SFTPWrapper.read( srcFile, user, pass ); …
After a few moments’ experimentation, Aikh returned to his email client to hit Reply with a vengeance. How will I know whether that call was successful? No errors were reported on invalid parameters!
An entire day passed as Dean composed his riposte. Each method will return a StringBuffer, which contains the response from the command-line.
For? Aikh asked.
Log from the sftp package, Dean replied. Yknow, the code I told you to write.
Aikh gaped at the email chain, having watched this horror show unfold in achingly slow motion. This was just supposed to expose a simple interface to a third party SFTP package. How was it so hard?
He made a more diplomatic lament to his manager. “Dean… isn’t giving me what I need,” he admitted. “We’re coming up on our deadline, and I’m getting worried.”
“I’m not.” His manager’s smile was reassuring. “Go with what Dean’s given you. The business is used to a manual interface anyway.”
“They don’t want a manual interface anymore. That’s the whole point of this project!” Aikh cried. “We’d be delivering something out of spec!”
“It’s what we can deliver on-time and on-budget. They’ll take it.” The manager leaned in and lowered his voice. “Listen, Aikh, we don’t like automation around here. Automation means the businesses have no need for our very lucrative support services. You don’t want to break our budget, do you? Of course not. So you’ll produce software that keeps us… involved. Understood?”
Aikh’s jaw crashed through the floor.
What could the poor junior dev do but report his roadblocks at the next project status meeting? The business was so worried about losing their automated process, they approved the purchase of a fast, supported library for file transfer. Aikh finished the solution done in time, much to the business users’ delight.
Aikh’s manager grumbled about the new guy “depriving the department of future support revenue.” Fortunately, he didn’t remain Aikh’s manager for long. When the business decided they needed their own internal IT staff, Aikh was at the top of their list.
http://thedailywtf.com/articles/classic-wtf-manual-automation
|
Метки: Feature Articles |
Independence Day |
Today is the 4th of July, which is a holiday with historical significance in the US. Twenty years ago, Jeff Goldblum and the Fresh Prince defeated an alien invasion using a PowerBook and a hastily written computer virus. Its such a big holiday, theyve just released a mediocre and forgettable film about it.
This scene has spawned many a flamewar. Anyone with a vague idea of how computers work may note that hardware architectures are complicated, and even with access to alien hardware and software, designing a virus capable of disabling all of the alien spacecraft in one fell swoop strains credulity. Some people point to a deleted scene which explains that computers are based on alien technology captured in Roswell, and thus, our computers are already compatible. Others mutter something about, Its just a movie, what the hell is wrong with you? while rolling their eyes.
Here at TDWTF, we know that no competently run IT organization is going to let its entire shielding system across an entire battlefleet be vulnerable to a single virus delivered to a single node on the network. We know the real story must be quite the WTF.
Lisa graduated from the Aldebaran Institute of Technology in 1996, expecting the rising tide of the late 90s tech boom to carry her to wealth and riches. She went to a college job fair shortly before graduating, handed out some resumes, and tried to resist senioritis long enough to make it to the end of the semester.
This is Lisa
A week later, she got a comm from a recruiter. Hey, Lisa, I just saw your resume, and have I got an opportunity for you! An established invasion fleet with a proven track record of subjugating alien planets needs some junior engineers to provide tier1 technical support. This is a great entry-level job, with 100% travel, which is such an amazing opportunity for a young Sectoid such as yourself- you really get to experience the whole galaxy. Now, the salary might not look like much, but youll also receive equity in the invasion, and you are absolutely going to make out extremely well- theyve identified a planetary sector thats completely unexploited.
Lisa was young, inexperienced, and the recruiter was very good at his job. She went in for an interview, chatted with Al (the head of IT), met a few of the other techs, and even got to meet one of the fighter pilots, who cut quite the dashing figure. Star struck and seduced by the promises of fantastic wealth (once they handle that minor, piddling problem of conquering the Earth and blowing up a few easily recognizable landmarks), Lisa signed on and boarded the mothership just a few days after graduation.
Spoilers: that dashing pilot doesnt look as dashing by the end of the movie
On her first day, Lisa was invited into Als office for some orientation. The office was little more than a closet, just off the main hangar bay. It was made even more cramped by Als insistence on covering the walls with the various certifications hed earned in his career- A+, Net+, and in the fanciest frame, MCSE.
Now, I know youre a college-educated wunderkind, Al said, but I got here through old-fashioned knowhow. The first and most important thing you need to understand is that we deliver IT services, and were not happy unless our users are happy.
A few days into the voyage to Earth, one of their users wasnt happy- the Hangar Operations Officer was having issues with spacemail. Lisa went to his workstation to try and help.
My broodmate sent me pictures of our newly hatched clutch, but Outlook wont let me open the attachement!
It was instantly obvious to Lisa what was going on, since the file was familyphotos.jpeg.zip.exe. This is almost certainly not pictures of your clutch, but is probably a virus.
Thats absurd, the hangar operations officer said, his tentacles waving angrily. My mate wouldnt send me a virus!
Well, it might not have come from your mate, Lisa explained. See, spacemail lets you claim the email comes from any-
Look, are you going to let me get these photos or not?
I cant, Lisa said. Theyre not photos.
Well see about that! the officer said. He commed Al directly. I want you to know that your new tech is refusing to let me see my pictures.
Theyre quarantined as a virus, Lisa said.
Oh, well, Al said, we can fix that. Let me just disable the quarantine.
What? Lisa cried.
Remember, Al warned her over the comm, were not happy unless our users are happy.
Cringing, Lisa watched the hangar operations officer open the virus. Fortunately, or perhaps unfortunately, it did open a window with a picture in it- a lewd picture of a Mutons posterior- and flashed a message that you have been pranked!. For a finale, it inverted the mouse pointer.
I told you, Lisa said, that probably wasnt from your mate. Youre just lucky it was a piece of joke software and not a dangerous virus. A quick reboot set the mouse back to normal, and Lisa made sure the dangerous email was deleted before she handed the mouse back to the Ops Officer. Please dont open strange attachments in the future, she warned.
The next few weeks were mostly routine support, until that dashing pilot- Lieutenant Bradford- submitted a ticket about his fighter craft. It was stuck in a reboot loop- the main computer would turn on, print out an error message, and then reboot. Obviously, this needed to be fixed before the invasion started. Lisa fired up Gopher to try and find out what was going on.
As it turned out, this was a bug in the v8.0.2 firmware running on the entire fleet of fighters. When the system clocks battery started running low and the clock started to drift, the firmware had a bug that would trap it in this reboot cycle. This particular bug had been fixed in v8.0.5, which was released six years prior. The manufacturer had actually cut support for the entire v8.x.x series and was up to v11.x.x.
You could fix it by replacing the battery and resetting the BIOS, which Lisa did, but she approached Al about these dangerously out of date software versions. Theres been a LOT of bugfixes that our ships dont have.
Al shook his head and laughed at Lisa. See, you dont get it. These software vendors, they just want to sell you new things. Trust me, the last time we tried to do an upgrade to the latest patches, they sent a tech onsite who kept trying to get us to buy new versions of all of their software. Its a scam, Lisa, just a scam. Our users are happy, so why should we spend money with the vendor when we can just keep using firmware that works perfectly fine?
Two days before they arrived at Earth, a new ticket came in, this time from the invasion fleets Supreme Commander. It was a bit of a cluttered mess of a ticket, in that it didnt represent one single issue, but instead the Supreme Commander wanted to vent about all of the problems she had with IT. Lisa interpreted the ticket as a series of bullet points:
A slow network was difficult to diagnose, but an inability to access a shared folder was easier to explain: the motherships firewall blocked that port. Unfortunately, the firewall software wasnt one shed ever seen before, and the configuration Al had built for it was pretty much an incomprehensible mess of exceptions and whitelists and blacklists and more exceptions. Lisa needed to get Al to fix it.
Oh, a slow network, eh, Al said.
Well, Im less worried about that, and more worried about the shared folder…
Enh, Al said, waving a tentacle dismissively, we can probably fix both at once. He turned off the firewall. I mean, he explained, this is just a barrier between the ships in our invasion fleet. It doesnt really make sense to put security software between the ships that we control, right? Right.
Things got really busy during the invasion. There was a lot of coordination that needed to happen. Several squadrons of fighters- including Lt. Bradfords- got transfered to the Assault Ships. Lisa barely had time to notice. As it turned out, no one had run a test on the landmark-destroying superlasers since the last invasion, and Al- in a fit of cost-saving- had installed 15 amp breakers in the power supply, which were entirely insufficient to the task. Lisa had to walk the Assault Ship techs through the process of identifying which circuit had the necessary 40 amp breaker on it, and then how to find the superlasers power cable to connect it to the right circuit. Thats if there was a 40 amp breaker available- Lisa had to coordinate an on-site electrician for Assault Ship ZX80 (which hovered over the White House), and it was a near thing to get the circuit re-wired in time to fire as part of the coordinated attack.
After a few days of eighteen hour shifts, Lisa finally got a bit of a break. All the easily recognizable landmarks had been blown up, and the Supreme Commander was confident that the humans would surrender any second. And thats when she noticed a new fighter joining the network. This one was running an ancient version of the firmware- v4.1.2, which was supposed to be removed from service fifty years ago.
Lisa grumbled and tried to identify the asset tag for that fighter craft. By the time she found it, the craft had docked just several meters from her workstation. She could see into the cockpit… and thats when the two humans inside waved at her…
For the next few days, we'll be running some classic WTFs as we have a small summer break. We'll be back on Friday with a fresh Error'd.
|
Метки: Feature Articles |
Error'd: Not What I Had in Mind |
Rob writes, "Sorry, but I'm not into Microsoft Office in that way."
"No, Virgin Money, that's not what I meant at all!" wrote Paul W.
Ben B. writes, "I was trying to report an issue with an online defensive driving course, but now I have an issue with their bug report form!"
"I guess the wait is the price I pay for trying to read a newspaper article during working hours," wrote Roland R.
"I'm all for continuous improvement and speedily shipping code, but sometimes just a little QA doesn't hurt," wrote Casey J.
Pat writes, "Oh no! It looks like the Westfield Shopping Center has crashed!"
"I use English language, with Dutch localization and a Brazilian keyboard. I think this confused the SteelSeries driver a bit," Marco G. writes.
|
Метки: Error'd |
Representative Line: The Validation Regex |
Regular expressions are a powerful tool for validating inputs, but what if your input is itself a regular expression? Is there a regular expression that can validate regular expressions?
Well, yes, if your regular expression engine supports recursion: /^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/.
Todays Representative Line (which is more than a single line) comes from Ryan S, who found an implementation of isValidRegex which is perhaps a bit more elegant:
public static bool isValidRegEx(string value)
{
// intent is to block empty strings from being accepted
return !string.IsNullOrEmpty(value);
}
You might be thinking, That doesnt validate anything at all!, but at least it doesnt summon dread Cthulhu from Rgexyleh. I count that as a win.
[Advertisement] Release!
is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
|
Метки: Representative Line |
Analyze This |
When asked to choose among several possible tools to do a job, qualified technical people look at the manual and test to see if the tool actually does what they need it to do. Is it reasonably configurable? Must it have root privilege to launch, or can it be installed as your application login id? Smarter folks will do a load test to see if it will scale beyond a handful of records and work with the expected volumes of data. And all of this will be combined to form an informed opinion as to whether the tool is appropriate for the task at hand.
High Level Managers have a different approach. They are too busy to deal with mere technical details.
After numerous outages at a large multi-national bank, a high level manager decided that they needed to do something to stabilize things, so he put together numerous charts to compare the various software packages that were available to automate solving their problems. There were slide shows, spreadsheets and myriad documents detailing how one tool was better than the others and that it would solve all of their problems.
The only problem with his analysis was that it was not based upon actual features or testing, but on the sales brochures and promises made by the salesman.
Not to let the facts get in the way of managing a problem, several suitcases of money were provisioned and turned over to the salesman in exchange for a full all-bells-and-whistles site license for the new tool. The new tool was brought in house and ran through a few simple test cases. Then it went live in production. Then it hit the fan.
Bob was brought in to see why their applications were crashing in spite of their shiny new be-all end-all tool.
Queries that should have completed in milliseconds took several minutes to complete. The tool was sucking up 80GB of memory just to launch in basic mode. And we're not even going to go into how the tool mistook email addresses for websites it had to crawl.
The manager, realizing that the salesman had lied to him, had to deal with the spilled milk, and opted to forge ahead at all costs.
Bob created a web app that alleviated the worst problems by pre-massaging input and query results. He could not push away a gnawing suspicion that he was merely repairing damage rather than adding actual value to the company.
After about a year of this, the manager committed to drastic changes in the work processes. When Bob learned about this, he asked them if they'd even done rough, back-of-napkin estimations of the expected manual workload in the changed process; after all, they already had a wealth of data from the past year and estimations surely could be done given the new process was specified in substantial detail. After all, they had gotten burned on their 'analysis' of the product they bought to solve all the instability. He was met with blank stares.
The new process was put in place and the amount of manual work tripled overnight.
Bob put in a lot of overtime trying to fight all manner of fires. Still, he was only partially successful, as the task of developing an app to totally fix the situation for a huge and complex package on top of a pretty complex work process was out of the question for a single developer.
After many, many months of this ongoing failure, the manager who started all of this had analysed the cause of the all of problems. The entire team was called in by the manager to a meeting. As could be expected, it was announced that the productivity was deemed too low while the risk and cost were too high, and so the entire team; analysts, lower level managers and Bob were laid off.
The manager was promoted for recognizing the cause of the failures and was given more responsibility to oversee other projects in addition to his own.
|
Метки: Feature Articles |
CodeSOD: The Bare Minimum |
Lets say you needed to find the maximum and minimum values for a field in a SQL database. If youre like most people, you might write a query like SELECT MAX(someval), MIN(someval) FROM table.
Thats the least you could do. Thats the bare minimum. And do you want to be the kind of person who does the bare minimum? Kevin Ls co-worker doesnt. Hes a Brian.
$querymin = " select hmid ";
$querymin .= " from tagdetail ";
$querymin .= " Where tagdetail.tag_ordr_ref=$grphdr_tag_ordr_ref";
$querymin .= " and tagdetail.refgrp=$grphdr_refgrp ";
$querymin .= " order by hmid ";
$resultmin = displayTable($conn_id1, $querymin, "N", "");
$counter = 1;
foreach ($resultmin as $a) {
$count_rcds = $count_rcds + 1;
if ($counter == 1) {
$min_hmid = (trim($a [hmid]));
}
$max_hmid = (trim($a [hmid]));
$counter = $counter + 1;
}
Thats way better than using aggregate functions.
[Advertisement]
Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.
|
Метки: CodeSOD |
Logging, Retooled |
In every company, there is a tendency to value code that was invented in-house over code that was, to put it bluntly, Not Invented Here. There is an eternal struggle to find balance between the convenience of pre-packaged code that is not fully vetted and the trustworthiness of code they themselves have written. As is typical in these tales, Jon's company got it wrong.
When Jon was asked what logging solution he was planning to implement in his company's .NET-based application, he gave the right answer: log4net.
No sooner had he spoken, however, than the room grew quiet. The locusts could be heard clearly from outside the window, screaming their disgust at the idea. Not-here! Not-here! Not-here!
"Or ... maybe I could throw something together?" he suggested timidly.
"Splendid!" replied Jon's boss, Ned, heartily. "You can use my logger as a head start. Rolled it by hand back in my university days. It's much better than that log4net crap. Did you realize that piece of dung uses reflection? Reflection! Something as simple as a logger doesn't need anything as expensive as that."
And Ned was right, in a way. His logger didn't use reflection; it hardcoded the method name into each log call made. But that's not all. In a bid to save on "expensive" new features Ned barely understood, the logger was held to a strict 2.0 code level, despite the project using the 4.5 framework. And in a flash of coursework-inspired brillance, he had implemented his own custom stack to store incoming logs—a move that entirely undid any cost savings achieved by avoiding reflection three times over.
But Jon tried. He rewrote the stack structure, desperate to reclaim some of the cycles. He documented methods that confused him, hoping to leave the codebase better than he found it. And he tried and tried to make it work consistently.
The days turned into weeks, and the project deadlines began to slip. Ned grew sterner and sterner with every depressing status meeting. "That logger can't possibly be responsible for all this! It was fine when I wrote it!"
"But sir, if we just pull it and use Log4Net—" Jon began.
"I don't want to hear another word about Log4net! Just get the project done!"
And so it was done—weeks behind schedule, and with a tendency to drop log files in the event of a crash, just when you'd want them the most. Jon privately swore he'd never touch the logger again; come hell or high water, he'd use log4net next time and be done with it.
It was three months later before he had another chance. Another desktop app needed to be built where logs would be mission-critical in the event of a disaster.
"Sir, about the logging—" Jon piped up.
"I know what you're going to say, and I won't hear of it," Ned cut him off.
"But sir, if you'll just listen a moment—"
"I said no and that's final: there's no way you'll be using that POS logger you put into production last time! No, you're going to have to write something custom from scratch, no getting around it!"
Jon put in his custom, from scratch, two weeks' notice that very day.
|
Метки: Feature Articles |
Error'd: It Ain't Over Til It's Over |
"Countdowns are hard, particularly once they run out!" writes Peter.
Valts S. wrote, "Steam lures you in with what looks like a good deal and then bends how addition works."
"This used to be just a 16 megabyte SD card, but Disk Utility knows it has potential," writes Andrew C.
Simon N. wrote, "Thank goodness the details of my order are correct else I'd have no recourse!"
"One must ask themselves - is this a case of accidental labeling or the rise of the burger dogs?" wrote Sam.
Jake M. writes, "There's the right way to get people to use your app, and then there's the wrong way...guess which one this is."
"There's just no pleasing some web login forms," wrote Jacob.
|
Метки: Error'd |
Dumb's The Word |
Brent's latest software project contained a story for adding a word-cloud to a PDF report that was already being generated on a production server using Java. Instead of being handled by Brent's in-house team, the requirement was assigned—against Brent's wishes—to overseas developers whom the company had recently contracted to "add more horsepower" to things.
Being fairly technical, the product manager found an example word-cloud library, linked to it in the ticket, and commented, "The output should look something like this."
A month passed. Then, Brent reported into work one morning to find a new ticket in JIRA listed as blocking the word-cloud ticket. Its title was Having trouble launching Internet Explorer from Selenium on Linux servers (works fine locally on my Windows development machine).
Brent's confusion left him paralyzed for a few moments. Then he realized, this was probably just a testing ticket that'd somehow gotten linked to the story by accident. To make sure, he called up Bobby, his counterpart from the contracting firm, who'd been the one to file the ticket.
"It's not a mistake," Bobby explained. "The story really is blocked."
"OK, so, you're really trying to launch Internet Explorer on the production app server?" Brent asked. "You realize IE's not installed on that server, right? What do you need it for?"
"It's integral to the implementation I came up with," Bobby replied.
Brent was afraid to ask. "How?"
"I couldn't find a native Java word-cloud library, so this is what I have to do to fulfill the specifications," Bobby said. "First, I take the PDF report data and serialize it to JSON. Then, I import Selenium into the production codebase. Then, I generate an HTML page and a Selenium script. Once Selenium is started, the script launches Internet Explorer and opens the HTML page. Once the HTML page loads, Selenium captures a screenshot of it. With Java, the screenshot is opened, cropped, and then embedded into the PDF report."
Brent was stunned speechless.
"I got this to work on my local machine, but then I tried to test on a server and hit the error," Bobby continued.
That's what you were doing all month? Brent marveled. "Uh, OK ... listen, the implementation you just described is unacceptable. I don't see why we can't keep it within Java. We're coming up on our deadline."
Brent's eyes strayed toward the calendar tacked to his cubicle wall, showing him how few empty squares he had left to deal with this. He took a deep breath, composed himself, then donned his project manager hat to do the managerly thing.
"Leave this alone for now, all right? I'm going to speak with some of my developers and let you know what we decide to do from here."
"OK," Bobby replied.
Once off the call, Brent opened up Outlook and fired off a meeting request for the earliest possible time. A short while later, he looked upon his assembled developers within a dimly lit conference room, half of whom were more interested in their laptops than in the minor crisis Brent related to them.
"What can we do about this on short notice?" he begged. "Is there a native Java library that can generate word-clouds?"
No amount of Internet-hunting turned up anything useful. Brent tugged at his collar. He'd been hoping Bobby had been wrong about that, and that a solution would only require a download and a few lines of code.
"All right. How hard would it be to code our own implementation?" Brent asked.
Cheryl, who'd been typing furiously all meeting, finally let up on the keyboard and shoved away from the table. "Here, I just finished."
As it turned out, her keyboard exercise had not been in the service of bashing trolls in comment threads. Everyone gathered to peek over her shoulder at the PDF-embedded word-cloud it'd taken her minutes to code and generate, an accomplishment that'd eluded their contractors for a whole month.
"Meeting adjourned!" Brent cried in triumph.
[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
|
Метки: Feature Articles |
CodeSOD: Built Up |
In most languages, strings are immutable. As developers, we often need to manipulate strings- for example, constructing output through concatenation.
Constructs like foo += " and then I appended this"; solve this immutability issue by creating a new string instance. If youre doing a long round of concatenation, especially if it happens inside of a loop, this could get very expensive, which is why most languages also have a StringBuilder type, which allows you to append without all that overhead of new instances. Often, the advice is that you should prefer StringBuilder objects to string.
Jonathans co-worker applied this advice without understanding why.
private static string PrivateValidateRequestAndGetReserve(string ProductCode, int TransactionType, string Username, string Password, ref string ReserveId)
{
StringBuilder ReturnMessage = new StringBuilder();
string TransactionCode = Enum.GetName(typeof(Common.Enums.TransactionCodesEnum), TransactionType);
ReserveId = string.Empty;
using (var AdminWS = new wsAdmin.AdminClient())
{
if (!AdminWS.AuthenticateUser(Username, Password))
{
ReturnMessage.Append("Error Logging on with the username and password supplied.");
return ReturnMessage.ToString();
}
if (!AdminWS.CanUserAccessProductAndTransaction(Username, ProductCode, TransactionCode))
{
ReturnMessage.Append("You don't have access to this transaction.");
return ReturnMessage.ToString();
}
if (!(AdminWS.CheckBalanceForTransactionFromUsername(out ReserveId, Username, TransactionCode)))
{
ReturnMessage.Append("Not Enough Credits to perform current transaction");
return ReturnMessage.ToString();
}
}
return ReturnMessage.ToString();
}
This isnt the worst of it. First, note all those calls to AdminWS methods. The developers who wrote those did not believe in throwing exceptions, since an uncaught exception could cause the program to crash. Instead, they wrote every method to return a boolean value indicating success or failure. This meant if any function needed to return a value, that could only be done as an out or ref parameter.
But the real prize here is with the parameter int TransactionType. As you can see in the code, they convert the int into a string by pulling it through an enumerated type called TransactionCodesEnum. It makes you wonder, why is TransactionType an int, couldnt they have just passed the enum into the method? There must be a good reason, right? Well, heres the code that calls this method:
Enums.TransactionCodesEnum transactionEnum = getCurrentTransactionCode();
string validationText = Admin.ValidateRequestAndGetReserve(ProductName, (int) transactionEnum, username, password, ref reserveId);
[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
|
Метки: CodeSOD |
Putting the "No" in "Novell" |
In the late 90's, Gregg was hired to administer a small Novell network at EduLoans, a student loan processing company. What it amounted to though was a toxic waste cleanup at a Superfund site. To say his predecessor, Loretta, was underqualified was a blunt understatement. The company wanted a network on the cheap, which included elevating a receptionist with slight technical skills to the ranks of Novell administrator. They figured the only training she would ever need was a two week hands-on Novell CNA course.
Loretta returned from training with tons of free swag in tow. This included a CD-ROM beta version of Netware 3.12, with bold text printed across its face reading NOT FOR USE IN A PRODUCTION ENVIRONMENT. Ignoring that, she convinced the President of EduLoans that they could get by with this great free version so there would be more money to spend on hardware - and her raise.
Fast-forward a couple years and the EduLoans network was barely functional. Things were fouled up so bad that the Administrator account could do nothing except delete existing user accounts, manage - but not create or delete - print queues, and setup automatic backups which the system would not actually run. Administrator could not even change its own password, nor could any of the other user accounts.
Around the same time, Loretta was ready to start a family and decided to leave EduLoans just before having her first child. Thus, the need for Gregg arose. He was brought in to fix the mess, and do it in a very budget-conscious manner. So obviously having Novell technicians come in to help was out of the question.
Combined with the Netware disarray was the crappy loan processing software EduLoans ran its entire business through. It had originally been written in COBOL then ported to MS-DOS batch files thousands of lines long. These mammoth batch files had to be run from a workstation, which resulted in pulling the entire million-dollar database over a 10 megabit Ethernet connection. The workstation would then process the transactions, send them back to the server, and print the results on 15" greenbar.
Strapped for cash and not sure what else to do, Gregg unhatched a bold plan. He would personally take an upcoming three day weekend to wipe every hard drive at EduLoans to remove the scourge Loretta had setup. He would then use an existing Netware 4.11 license he personally owned the rights to from his last job and set up a fresh Novell network, re-install everything on the workstations, and connect it to the new clean network. From there he would take the backed-up application and database and set it up in a manner that it could run from a server. It might take him the entire 72 hours of the weekend, but it should work and he'd be hailed as a hero.
In order to execute this plan, he would need signoff from Bob, EduLoans' Vice President and the only rung of the ladder Gregg ever had to run his ideas up to. Bob wasn't the most technical person, so it didn't usually take Gregg much effort to convince him. "Seems like a solid enough plan," he said. "If you're willing to burn up this glorious long weekend doing it, that is. Me, I'll be out of state on a golf course somewhere, so I am not to be bothered!" Bob thrust his index finger in to the air to drive home the point. "I'll see you on Tuesday once this mess is sorted out!"
For Gregg, the 3 day weekend seemed like one long, never-ending day. He had all the workstations wiped and reloaded by Saturday night but the rest of the time was a total nightmare. The new network was more difficult to set up and configure than he originally anticipated. Once that was done, none of the workstations would talk to it until he found some obscure setting in the wee hours of Monday.
After a power nap, he got to work configuring the server to run EduLoans' application. He came to find the documentation he was planning to use to help set it up hadn't been updated since the time Zubaz were cool. That led to a lot of guesswork and missteps, which eventually led to the sun coming up on Tuesday morning and a non-functional environment that EduLoans depended on for business.
Bob strolled in an hour late, looking lobster-ish from too much sun on the golf course. "Gregg! Good morning. I forgot all about you being here this weekend. How'd it go?" Bob's tone suggested he expected everything went well and Gregg had worked a miracle. But the answer he got made him turn an even deeper shade of red. "We need to go explain this to the President, pronto!"
Gregg was prepared to fess up to what he did, but did not anticipate the proverbial bus Bob was about to toss him under. "He acted alone! I told him this was a bad idea that could damage our business! But did he listen? NO!" Bob blathered on as Gregg sat there stunned. "I even tried calling him several times to see if he had any other ideas! I will not be held responsible in any way for this disaster!"
If looks could kill, The Prez's icy stare would have struck Gregg down. Instead, he calmly spoke, "Gregg, I'm afraid your services are no longer needed here. Bob, please escort him out. After that, get on the phone to Loretta and tell her we will spare no expense to bring her back to get our network back to the way she had it!"
[Advertisement]
Otter, ProGet, BuildMaster – robust, powerful, scalable, and reliable additions to your existing DevOps toolchain.
|
Метки: Feature Articles |
CodeSOD: Now There's a Switch… |
You know whats awful? If-then-elseif conditions. You have this long, long chain of them, and then what? If only there were a shorter, clearer way to write a large number of conditions.
Oh, whats that? There is? Its called a switch statement? But doesnt a switch statement only work on equality comparisons? Id really like something that works on any condition.
Fortunately for me, Sergejs boss has found a way.
clients.findById( req.authUser._doc._id).then( function( client, error ){
switch( true ) {
case client == null:
res.send( { success: false, message: 'Your profile has not been found. Try it again or logout and then login again' });
break;
case client.password != req.body.profile.password:
res.send( { success: false, message: 'Profile has not been updated. Password is wrong.' });
break;
default:
var updateObj = {};
switch( true ) {
case client.firstname != req.body.profile.firstname:
updateObj.firstname = req.body.profile.firstname;
case client.lastname != req.body.profile.lastname:
updateObj.lastname = req.body.profile.lastname;
case client.username != req.body.profile.username:
updateObj.username = req.body.profile.username;
case client.companyName != req.body.profile.companyName:
updateObj.companyName = req.body.profile.companyName;
case client.companyAddress != req.body.profile.companyAddress:
updateObj.companyAddress = req.body.profile.companyAddress;
case client.companyCity != req.body.profile.companyCity:
updateObj.companyCity = req.body.profile.companyCity;
case client.companyCountry != req.body.profile.companyCountry:
updateObj.companyCountry = req.body.profile.companyCountry;
case client.registrationNumber != req.body.profile.registrationNumber:
updateObj.registrationNumber = req.body.profile.registrationNumber;
case client.vatNumber != req.body.profile.vatNumber:
updateObj.vatNumber = req.body.profile.vatNumber;
}
}
clients.update({_id: client._id},{$set: updateObj})
.exec()
.then(function(data,err){
typeof err != 'undefined'
? res.send({success:false, message: 'Your profile could not be updated.'})
: res.send({success:true, message: 'Your profile has been updated.'});
});
});
All the functionality of an if-then-else, but its even more flexible, because its got fall-through! Why does anybody use regular if statements when theyve got this efficient and easy-to-read construct?
[Advertisement] Release!
is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
|
Метки: CodeSOD |
Error'd: Pirates, Your Days are Numbered |
"If you pirate Windows 10, watch out," Norman D. wrote, "One week and 100 years from now, Microsoft is going to catch you."
"The experience of 3D navigating a tape drive just can't be beat," writes McKay S.
Sam writes, "Seeing a Windows error on an ATM isn't a huge surprise. Seeing one on a video game though is just sad."
"Orion SolarWinds threw its hands up, and then threw up, from the looks of it," writes Charles R.
Steffen M. wrote, "There was an internal error so bad that it shook Eclipse to its very core!"
"I was looking for a ATX power supply tester, on the same page it linked me to this cosy looking POST diagnostic tool," writes Dave L., "And you wouldn't know it, but it has a built-in speaker too!"
http://thedailywtf.com/articles/pirates-your-days-are-numbered
|
Метки: Error'd |
Announcements: Our Next Kickstarter: Lairs Board Game |
I've been a board/tabletop gamer for as long as I can remember, even before writing my first program (obviously, 10 PRINT "ALEX IS COOL" / 20 GOTO 10). After seeing how much you supported the Release! game, it turned out that a lot of you are into games, too.
But since then, I've learned that games came be more than just a fun activity for us to do off-hours with our friends and family. They can also serve as a great team-building activity for developers and engineers.
And it's not just the social aspect. Understanding and applying a set of fixed rules to achieve a desired outcome describes both writing software and playing games, and seeing how other team members think and apply these rules can create a better understanding, and facilitate better communication. That, and it's a bit more fun than most corporate team-building activities.
Of course, this wasn't exactly the driver behind my next Kickstarter Project (or the other two games we've since launched), but it's one of the reasons I wanted to share it with you today.
Here's a the short story on how the game works:
In Lairs, players take on the roles of powerful creatures that each build their homes in The Mountain.
Deep in The Mountain lie powerful artifacts, ancient sorceries, and untold riches. These Legacies, when claimed, will grant great power.
At the start game, players compete to excavate and build their Lairs to the center of the mountain to claim one of these prizes.
Once one player has taken the Legacy, they become the Enemy of the other players, who are not content to let one soul hold such power.
The remaining players band together as the Allies and fight their way through each chamber of the Enemy’s lair, and eventually confront them in a climatic finale.
The project is live, and I'd love to get your feedback!
I'm putting this up here right at launch time so you can can score an early bird copy of the game for just $22! There are plenty of other rewards too, but you folks gave me a lot of support in past projects so I wanted to give you the first shot at Lairs. Thanks all!
[Advertisement]
Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.
http://thedailywtf.com/articles/our-next-kickstarter-lairs-board-game
|
Метки: Announcements |
CodeSOD: Trained Developer |
ASP.NET, like any other web development system, has a role provider system to handle authorization. With a small quantity of code, you can hook your custom security settings into this API and get authorization essentially for free. Not every organization uses it, because its not sufficient for every security situation, but its a good starting point, and its guaranteed that itll be covered in any ASP.NET training course.
Pauls employer recently found a new hiring strategy. Instead of hiring expensive, well qualified people, they hire completely inexperienced people on the cheap, and send them to training classes. Thats likely where this code started its life- cribbed from notes in a training class.
private void AddUserToRole(List users, int r)
{
if (!Roles.RoleExists("Level" + users[r].Accesslevel))
{
Roles.CreateRole("Level" + users[r].Accesslevel);
}
//checks if they are in the role... GOOD
if (!(Roles.IsUserInRole(users[r].User_name, "Level" + users[r].Accesslevel)))
{
string[] rolesforuser = Roles.GetRolesForUser(users[r].User_name);
string[] userroles = Roles.GetUsersInRole("Level" + users[r].Accesslevel);
int count = rolesforuser.GetUpperBound(0);
string currentrole = "";
for (int i = 0; i <= count; i++)
{
currentrole = rolesforuser[i].ToUpper() + currentrole;
}
if (!(currentrole.Contains("LEVEL" + users[r].Accesslevel.ToUpper())))
{
try
{
Roles.AddUserToRole(users[r].User_name, "Level" + users[r].Accesslevel);
}
catch (Exception ex)
{
createfile("AddUserToRole", users[r].User_name + "\r\n" + users[r].Accesslevel + "\r\n" + ex.Message + "\r\n" + ex.Source + "\r\n" + ex.StackTrace);
}
}
}
//if (Roles.IsUserInRole(users[r].User_name.ToLower()) == false && Roles.IsUserInRole(users[r].User_name.ToUpper()) == false)
}
Now, there are a few obvious problems with this code. The for loop in the middle is an incredibly special snowflake. Beyond that, this code is in-line in the code-behind for a SharePoint page , and is called every time the page is rendered.
The real kicker, though, is that Pauls organization uses a custom membership provider that doesnt implement RoleExists, meaning this code just throws an exception every time its called anyway.
|
Метки: CodeSOD |
Coming of Age |
When you discover the truth about Santa and the Easter Bunny, you die a little inside as you leave some innocence behind and begin to grow up.
When you get your first pay check at your first real job and discover that the government gets the first bite, you get a little disenchanted as you grow up.
When you realize that the prettiest members of the opposite sex aren't always as nice and sweet as you might fantasize, you face a reality of life and grow up.
None of that holds a candle to the coming-of-age you experience as you find out about management in the workplace...
D.H. was a student pursuing a degree in Computer Games Programming. The program required a year of work in the real-world workplace. He thought he was pretty lucky to find a job at a massive Consultancy and IT company. Unlike most of the 20 interns in the group, D.H. wound up with some actual hands-on experience as a developer.
Toward the end of the stint, D.H. had developed a healthy fear of Management Stupidity©
From the get-go, he discovered that real-world programming was vastly different from university homework problems. What he hadn't expected however, was for common sense to have been replaced entirely with "business sense", and for all coding practices to be thrown out of the window.
When someone raised a defect because you could only select one out of several radio buttons on screen, management forced him to break functionality. There were radio buttons assigned to the question "Would you like to review your answers?" Yes, No, followed by two buttons: "Review" and "Continue". After the change, you could click no to review and then review anyway.
We all know that you shouldn't trust user input. He discovered that a field that took 3 characters for a promotion code brought the application crashing down around it if the data was entered incorrectly.
Or if someone has a surname with a space.
Or if you share a house with someone with the same birth date and surname (twins, or a coincidental marriage spring to mind).
Or if you need to handle international phone numbers.
Or street addresses.
And then he found this:
if (foo || !foo) { /*Code*/ } else { /*same code as above*/ }
D.H. felt violated that such foolishness could be perpetrated by so-called professionals.
Welcome to the wonderful world of IT!
[Advertisement]
Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.
|
Метки: Feature Articles |
CodeSOD: Simulated Congealing |
Simulated Annealing is a class of algorithms from moving through a search space to find a solution, balancing good enough results against a computational budget.
John L has a co-worker that has taken this logic and applied it to writing code. Whenever code needs to change, he randomly changes the function in small increments until it works. The result is code that looks like this:
private void handleDoubleClickTreeNode(object sender, FormTreeNodeArgs e)
{
if ( e.FormTreeNode.FormElement != null)
{
AddScoreElement(e.FormTreeNode.FormElement);
}
else if (e.FormTreeNode.FormElement == null)
{
if (e.FormTreeNode != null)
{
if (!string.IsNullOrEmpty(e.FormTreeNode.Name))
{
AddScoreElement(e.FormTreeNode.Name);
}
}
}
}
This code does work, but some of the conditionals make it clear that it works more through an accident than any intentional design.
|
Метки: CodeSOD |
The Shield |
Russell M. knew better than to tempt fate. The last time someone asked him about Big Telcos network downtime, he bragged about not having any since he began & only for the network to go down within minutes. That time, a construction worker plugged a power drill into a UPS and drained it.
This time, with no construction on-site, he couldnt use that excuse.
No one can call anyone, anywhere, on our regional network, the CEO rasped through a speakerphone. Russell sat in a conference room with the other four employees in SysOps. The executive board were all on the other line. I want hourly reports & No, semi-hourly reports. If someones not calling me every thirty minutes about whats been done, therell be a box and a pink slip at each of your desks come Monday morning.
The CEO had a flair for the dramatic, but Russell knew he couldnt brush this one off, not after last time. Okay, he said to the rest of SysOps, lets do a visual check.
Down in the equipment room, a basement where phone books were once archived, Russell and the others visually inspected Big Telcos CLEC infrastructure. All of the switches and other equipment were stored here. Russell and the rest of SysOps rarely came through for anything other than an emergency.
Russell, checking that all of those boxes were still turned on, didnt notice the three-inch-thick paperback manual splayed on top of a keyboard at first. He picked up the blue-and-white doorstop and put it back onto the shelf above. He switched on the monitor and checked the logs. Through bad luck, the manual had mashed just the right key combo to trigger a feedback loop in the network switch. This was what had brought down an entire regional telephone network: some bad commands triggered by a knocked-over equipment manual. However, Russell had no means to stop the loop from the console itself. He sighed, knowing the fire and brimstone about to come down on him.
He rebooted the switch.
Big Telcos investigative team arrived that Monday. Russell knew you never rebooted part of the network unless you had no other choice, because Big Telco would be obligated to file a report with the FCC. The investigative team, nicknamed Scully and Mulder, summoned Russell to the conference room.
Accounting estimates we lost a million dollars in revenue due to the outage, Scully began. Thats potential revenue, estimates for lost customers over eight quarterly cycles, Scully continued. So tell me: did you really have to reboot that piece of equipment?
No other choice, Russell said. It would have kept the network down indefinitely.
If I could speculate, Mulder said, you said that the book had fallen off the shelf. Could it have been sabotage? Do you think a member of SysOps could have done it?
No one ever goes down there, Russell said, except us and custodial.
Mulder wrote on a notepad. Check & custodial & for & recent & hires.
I mean, you couldnt have prevented it, Russell continued. Unless you chained the manuals to the shelves and put plexiglass over the keyboards.
Is that your recommendation? Scully asked.
A shipping pallet stacked with boxes was delivered to SysOps the following week. Russell and the others unpacked them. Inside were twenty-something pieces of moulded plexiglass, along with hundreds of feet of thin chains. Russell read aloud the attached instructions.
Use a 3/4 inch bit to drill a hole in the spine large enough to pass the chain through. Only use three feet of chain per book. That would barely be enough to open the book on its shelf. Each plexiglass shield has been custom-made for a single keyboard in the equipment room, per the latest inventory. Do not put a plexiglass shield over the wrong keyboard.
After SysOps implemented the changes recommended by Scully and Mulder, Big Telco submitted its findings to the FCC, and it dodged a hefty fine for the outage.
A few months later, one of the ancient book shelves collapsed onto on a console. The monitor shattered, but the keyboard, protected by its shield, remained intact. None of its sensitive keys had been pressed.
[Advertisement]
Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.
|
Метки: Feature Articles |
Error'd: All Rights Reversed |
Tim B. writes, "If you violate Laotel's rights, does this mean that you can sue them instead?"
"Unfortunately, this is what I've come to expect from the website that provides my pay stubs," Leo T. wrote.
Charlie writes, "Not quite what I had expected, but whatever needs to be fixed, needs to be fixed!"
"After clicking on a UPS to check on load capacities, I was assured that there would be no problem with my server," wrote Kevin.
"While many SSD manufacturers rate their drive durability in 'terabytes written', this one has a somewhat smaller threshold," writes Matt.
"Thoughtworks clearly doesn't think too highly of their documentation," writes Mike R.
"So, do premium users get to keep their software installed?" writes Wim.
|
Метки: Error'd |