Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-07-05 23:16
The Security Audit
We do our best to anonymize submissions, but there’s always a chance that some dangerously identifying detail slips through. Every once in a while, a submitter contacts us to ask for a modification. More rarely, a submitter’s employer contacts us.Our rule is to make edits more or less as requested, then move on without comment. There’s nothing about an article so sacrosanct that it’s worth going to war over. However, we recently got a request that was itself too much of a WTF to pass up.An old Errord—practically antique—contained a picture of a freaked-out Windows login screen, submitted by someone we’ll call Johnny. The post contained Johnny's name, username, and an Active Directory Domain. It did not identify the company Johnny worked for. But the company—we’ll call them “Lagomorphic Cogitations”—recently performed a security audit and sent us a message:
CodeSOD: The Story of Things
Every line of code tells a story. It never just… appears. Someone made and crafted that code. There’s a story, and an explanation for how that code could be. The world, even the bad, awful corners of it, makes sense and can be understood.For example, Luke sends us this block.
Time To Transfer
When people think about government, they usually think about a President or Prime Minister, Senators, MPs, or what have you. But government isn't just a handful of people at the top of the food chain: there's government all the way down to the city level, quietly making the country run. Driver's licenses have to be issued, as do pet licenses. Buildings have to be inspected and certified. All those elevator certificates get printed up somewhere. Increasingly, these small functions are being computerized—in bits and pieces, in incompatible systems—and hooked up to the Internet.Lisa was the lead engineer for one of these public websites. At its core, it took in personally identifying details and spat out some sort of official document. This meant they had to deal with the PII issues that come with taking people's information: encrypting and salting the data, securing the database backend, et cetera.One of the pieces in this chain was a separation of data: until the user had paid for the document, proving their identity (or at least their possession of the credit card for the person they claimed to be), their data sat in a frontend database accessible to the Internet. After payment was taken, the data was sent to a more secure database in the backend and removed from the potentially hackable frontend. The frontend ran in a VM that could only make an outgoing connection to the database. It could receive incoming connections and respond, but not initiate them. Basic security for this type of system.There was one issue, however, that Lisa struggled to track down. It seemed that a small percentage of users, fewer than 1%, were getting an error page immediately after payment. Their application was fine; payment was received, and their document was sent to them along with a confirmation. But they saw an error page suggesting they hadn't completed their transaction.When Lisa managed to catch the issue in the act, she was able to reconstruct the sequence from the logs:
CodeSOD: An Emailed Condition
For a change of pace, the code in this CodeSOD isn’t the real WTF. Our Anonymous submitter works for a company that handles meeting scheduling for corporate customers. This entails shipping off loads of HTML-emails, and that means using a relatively terrible WYSIWYG editor that generates code like this:
Error'd: Ride the URL Line
Michael R. wrote, "So, https://TfL.Gov.UK...does that bus go on the 'Information Superhighway'?"
Featurette: Hired!
As you know, Hired has been sponsoring the site for the past few months. I went “behind the scenes” to have a brief chat with Michael Mitchell, a full stack web engineer focused on their “Candidate Experience” features.To ease in, I started with the only truly important question about life at Hired: how’s the coffee. “It’s amazing,” Michael replied. “We have an operations coordinator that worked at a few large coffee roasters, so she takes care of coffee and makes large batches of cold-brew for the office.” That last is an important one- I’ve had too many cups of “iced” coffee that were just, well, hot coffee with ice in it.Michael was an electrical engineer before becoming a web engineer; while high voltage might kill you, NPM will make you wish you were dead. “I’m partial to the story Overpowered,” Michael said. While he never used angular momentum to destroy a hard disk drive, he did build the automation for an industrial packaging line. That automation was entirely run through a single Arduino.“I wasn’t a complete idiot,” Michael said. “All of the safety critical systems were hardwired in a fail-safe manner, and didn’t depend on the Arduino.” It operated for years without incident, and as the line grew, that Arduino ended up running a multi-million dollar business. Eventually, the support contract for the line went elsewhere, and the company taking it over wanted to know what that tiny little board running the line was, and how they could interface with it. “I told them to rip it out and replace it with a PLC, because they really didn’t want to hear the answers to those questions.”Michael isn’t in the business of hacking together millions of dollars of business on hobbyist equipment anymore. Their current stack- mostly Ruby/React.js, with Postgres on the backend, and a bit of Scala/Python data-science for matching/ranking- doesn’t have any of those kinds of hacks. “Our code review process is fairly well enforced- culturally, not through tools. Probably, the most horrific stuff I’ve done is commit some pretty tortured CSS.”Despite that, there are lots of growing pains. When Hired was in its early startup phases, it was “move fast and break things,” but as their customers grew, they needed to shift gears. “When you have large client teams relying on your product, moving a button can break an entire HR team’s workflow.”The upshot is that Michael works with a strong team. “Everyone here is incredibly collaborative and easy to work with.” How do they build the right team? Using Hired, of course! At least half of the engineering team were placed through Hired. “The founders started Hired because they had issues hiring good talent for their previous companies. The company was practically founded to dog-food its own product.”Speaking of, Michael’s team is tackling a lot of work- in addition to two web engineers, they have two mobile engineers and a single designer. Five people supporting web, iOS, and working on delivering an Android app. “That’s with only four engineers, so I’d say our bottleneck is mainly engineering resources. We’re currently Hiring!”Hired was also Michael’s chance to dodge a bit of a bullet. When he was last job hunting, he was shopping around, and interviewed with another startup. The CEO may have been the subject of many an article here: the “I know better than you, and you’re lucky I’m even talking to you,” sort. Michael explains:
CodeSOD: Object Relational Mangling
Writing quality database code is a challenge. Most of your commands need to be expressed in SQL, which is a mildly complicated language made more complicated by minor variations across databases. Result sets often have a poor mapping to our business logic’s abstractions, especially in object-oriented languages. Thus, we have Object-Relational-Mapping tools, like Microsoft’s EntityFramework.With an ORM, you use an object-oriented approach to fetching your objects, and could write something like: IList<HJFRate> rates = db.HJFRates.where(rate=>rate.typeOfUse == typeOfUse) to return all the rows as objects. There’s no concern about SQL injections, no need to process the result set directly. While ORMs can generate poor SQL, or create really inefficient data-access patterns, their ease-of-use is a big selling point.Which is why Bob Zim was surprised to find this EntityFramework code in a C# web-service:
Cut Short
Marcus worked on a small networking team responsible for keeping a series of UK-based garages interconnected with the world-wide web. Seymour, the Team Leader (in title only), knew far less about networking than Marcus, but that didn't stop him from acting like the big shot. Seymour was working a cash register at the original garage several years ago when the owner asked him, "You're a young guy, right? That means you know how the internet works. What can we do to make this place internet-friendly?" After taking a Networking 101 course, Seymour managed to get the garage online, then enabled it to monitor gas prices and perform credit card transactions. This made Seymour a hero to the owner, and earned him the title, "Networking Team Leader" before he even had a team.Eventually the garage grew from a single location into a chain. When each new location opened, Seymour made it "internet-friendly", using the same techniques he learned at the original store, which usually involved sloppy cable runs and the cheapest router he could buy. When it came time to do more than just have the ISP arrive to show where Seymour to plug in the network cable, he was completely lost. Having multiple locations networked together was really advanced stuff, so he convinced the owner to hire some help.Enter Marcus, who was willing to be hired on as Seymour's subordinate while realizing he would be the de facto brains of the networking team. It didn't take long for Marcus to realize he had his work cut out for him to get things in order. There were several hack-y solutions put in place that Marcus was able to improve upon, but in the end he got no credit for it because Seymour was there to take the accolades.
CodeSOD: Attack of the "i" Creatures
“Mrs S” works for a large software vendor. This vendor has a tendency to quickly increase staffing to hit arbitrary release targets, and thus relies heavily on contractors. Since they’re usually doing this during a time crunch, these contractors may have a… dubious skill set.They also don’t care. There is no documentation, no tests, and no explanation. They are just paid tho write the code, not maintain it. They’ll be on another contract before long, so it’s some other schmuck’s problem.Which is why “Mrs S” found this code, which takes a version number, as a pair of integers, and converts them to a string, but still couldn’t tell you why it does any of the things that it does.
Error'd: D.O.A.
John A. writes, "Um, you know, I don't think this was a brilliant idead."
CodeSOD: Protect Your Property
Given the common need to have getter/setter methods on properties, many languages have adopted conventions which try and make it easier to implement/invoke them. For example, if you name a method foo in Ruby, you can invoke it by doing: obj.foo = 5.In the .NET family of languages, there’s a concept of a property, which bundles the getter and setter methods together through some syntactical sugar. So, something like this, in VB.Net.
Disk Administrations
It was a mandatory change control meeting. Steven S.’s department, a research branch of the Ministry of Social Affairs and Health in Belgium, assembled in a cramped meeting room without enough chairs for everyone. Camille, head of IT, was nonplussed.“These orders come directly from Security,” she began. “Just last month, we monitored over a hundred attempts to break into the HCP.” The Home Care Platform was a database of citizens’ requests for doctors’ visits, prescription coverage, etc. Steven’s team had developed a mobile app that gave citizens access to HCP’s records.“An automated script,” she continued, “purged our server logs before Security could investigate. Now we have little information on what these attackers were trying to access, nor if they were able to find a breach.”
CodeSOD: Drop it Like it's a Deployment
Zenith’s company went ahead on and outsourced 95% of their development to the lowest bidder. Said bidder promised a lot of XML and MVC and whatever TLAs sounded buzzwordy that day, and off they went. It’s okay, though, the customer isn’t just taking that code and deploying it- “Zenith” gets to do code reviews to ensure code quality. The general flow of the post-code-review conversation goes something like:
Credential Helper
John S. worked with a customer who still owned several Windows 2008/R2 servers. Occassionally during automated management and deployments, these machines threw exceptions because they weren't configured for remote management. One day, John caught an exception on a SQL box and remoted in to address the problem.The RDP login process always felt like accessing a portal into the distant past. This time, just after the ancient Windows interface appeared, a Notepad document popped open. John skimmed the so-called Readme.txt file—then read through it again (grammatical errors preserved):
Error'd: A Test-imonial
"You know, usually these statements are just marketing B.S., but I think this guy's got the right idea," wrote Philip K.
Nature In Its Volatility
About two years ago, we took a little trip to the Galapagos- a tiny, isolated island where processes and coding practices evolved… a bit differently. Calvin, as an invasive species, brought in new ways of doing things- like source control, automated builds, and continuous integration- and changed the landscape of the island forever.Or so it seemed, until the first hiccup. Shortly after putting all of the code into source control and automating the builds, the application started failing in production. Specifically, the web service calls out to a third party web service for a few operations, and those calls universally failed in production.“Now,” Hank, the previous developer and now Calvin’s supervisor, “I thought you said this should make our deployments more reliable. Now, we got all these extra servers, and it just plumb don’t work.”“We’re changing processes,” Calvin said, “so a glitch could happen easily. I’ll look into it.”“Looking into it” was a bit more of a challenge than it should have been. The code was a pasta-golem: a gigantic monolith of spaghetti. It had no automated tests, and wasn’t structured in a way that made it easy to test. Logging was nonexistent.Still, Calvin’s changes to the organization helped. For starters, there was a brand new test server he could use to replicate the issue. He fired up his testing scripts, ran them against the test server, and… everything worked just fine.Calvin checked the build logs, to confirm that both test and production had the same version, and they did. So next, he pulled a copy of the code down to his machine, and ran it. Everything worked again. Twiddling the config files didn’t accomplish anything. He build a version of the service configured for remote debugging, and chucked it up to the production server… and the error went away. Everything suddenly started working fine.Quickly, he reverted production. On his local machine, he did something he’d never really had call to do- he flipped the build flag from “Debug” to “Release” and recompiled. The service hung. When built in “Release” mode, the resulting DLL had a bug that caused a hang, but it was something that never appeared when built in “Debug” mode.“I reckon you’re still workin’ on this,” Hank asked, as he ambled by Calvin’s office, thumbs hooked in his belt loops. “I’m sure you’ve got a smart solution, and I ain’t one to gloat, but this ain’t never happened the old way.”“Well, I can get a temporary fix up into production,” Calvin said. He quickly threw a debug build up onto production, which wouldn’t have the bug. “But I have to hunt for the underlying cause.”“I guess I just don’t see why we can’t build right on the shared folder, is all.”“This problem would have cropped up there,” Calvin said. “Once we build for Release, the problem crops up. It’s probably a preprocessor directive.”“A what now?”Hank’s ignorance about preprocessor directives was quickly confirmed by a search through the code- there was absolutely no #if statements in there. Calvin spent the next few hours staring at this block of code, which is where the application seemed to hang:
CodeSOD: Synchronized Threads
Tim was debugging one of those multithreading bugs, where there appeared to be a race condition of some kind. The developer who had initially written the code denied that such a thing could exist: “It’s impossible, I used locks to synchronize the threads!”Well, he did use locks at the very least.
Tales from the Interview: The 5% Candidate
There are many kinds of jackasses in this world, from the pretentious prick to the smug cynic. Each has their own flavor of awfulness, their own way of making you hate not only them but the entire world that gave birth to them. This story is about one kind of jackass in particular, perhaps the most classic flavor: the man so sure of his own greatness that he becomes enraged at the world whenever it fails to bow before his massive intellect.You see these people a lot on Twitter these days. With self-righteous fury, they demand that you get with the program and acknowledge their clear superiority. But as obnoxious as they are online, they're worse in person ... especially if they turn up at your job interview.Today's candidate applied for a job at a government IT department. Unlike stories you've seen on this site before, this government shop was actually fairly efficient and pleasant to work for. They were hiring Java developers, preferably ones that also had UI and database skills. As such, they had over 100 CVs to skim through for their first 2 positions. After removing those written in crayon, with massive coffee rings obscuring the text, or which had return addresses in prison, they were able to narrow the field to a mere 30, but it was still far more candidates than they wanted to interview in a few short days.But interview they did. At 10 candidates a day, they barely had time to weed through people; however, it didn't take long to eliminate most of the candidates. Some lacked a basic understanding of computers, such as how to launch applications when they're not strewn across the desktop. Others lacked a basic understanding of programming, being entirely unable to tell Java apart from Microsoft Word. Still others—disturbingly many others—lacked a basic understanding of hygiene.For Round 2, they decided only to work with agencies they'd had firsthand experience with, either from that office or from previous companies. They also put together a quick "sniff test" to filter the wheat from the chaff. This 30-minute test checked for basic logic skills, including some open-ended CS questions and Java code to debug. They were looking more for the explanations behind the answers than the answers themselves, hoping to get some idea of how these people reasoned.It worked like a charm. Those who scored under 50% were always appalling in the interview, and those who scored highly were always at worst acceptable. They quickly found their candidates. When it came time to fill the next junior opening, the decision was unanimous: they would use the sniff test as a screen, refusing to interview anyone who failed.Enter The Architect, our aforementioned jackass. This guy seemed pretty good on paper: "10 years experience in infrastructure architecture, design patterns, certifications, and software development practices" according to his cover letter. Applying for a junior role was a bit odd for this veteran, to be sure, but they gave him the test anyway.And boy, did he fail. His final score was a mere 5%. Every answer included a tirade about how the question was wrong. Every. Single. One.Some of you may not believe this man exists. But some of you have met him, or one of his many counterparts the world over. This is the man who, when faced with a question like:
Representative Line: Groovy Typing, Man
Groovy was one of those programming languages that spent about six months as the trendy language du jour, and I haven’t heard much about it since. If I were to learn it, I’d want to learn by example- going through real-world Groovy code and seeing how it works.An anonymous submitter has provided one sample for me to learn from:
Error'd: The Things That Should Not Be
"I tried to export my game to HTML5, but I guess it just wasn't meant to be," Edward W. writes.
Table 12
We've all encountered database tables that look like this:
CodeSOD: The Nuclear Option
About a decade ago, Gerald worked at a European nuclear plant. There was a “minor” issue where a controller connected to a high-voltage power supply would start missing out on status messages. “Minor”, because it didn’t really pose a risk to life and limb- but still, any malfunction with a controller attached to a high-voltage power supply in a nuclear power plant needs to be addressed.So Gerald went off and got the code. It was on a file share, in a file called final.zip. Or, wait, was it in the file called real-final.zip? Or installed.zip? Or, finalnew.zip?It took a few tries, but eventually he picked out the correct one. To his surprise, in addition to the .c and .h files he expected to see, there was also a mysterious .xls. And that’s where things went bad.Pause for a moment to consider a problem: you receive a byte containing an set of flags to represent an error code. So, you need to check each individual bit to understand what the exact error is. At this point, you’re probably reaching for a bitshift operator, because that’s the easiest way to do it.I want you to imagine, for a moment, however, that you don’t really know C, or bitwise operations, or even what a bit is. Instead, you know two things: that there are 255 possible error codes, and how to use Excel. With those gaps in knowledge, you might perhaps, just manually write an Excel spreadsheet with every possible option, using Excel's range-drag operation to fill in the columns with easily predictable values. You might do this for 254 rows of data. Which, as a note, the range of possible values is 255, so guess what was causing the error?
The Logs Don't Lie
She'd resisted the call for years. As a senior developer, Makoto knew how the story ended: one day, she'd be drafted into the ranks of the manager, forswearing her true love webdev. When her boss was sacked unexpectedly, mere weeks after the most senior dev quit, she looked around and realized she was holding the short straw. She was the most senior. This is her story.As she settled into her new responsibilities, Makoto started coming in earlier and earlier in the hopes of getting some development work done. As such, she started to get accustomed to the rhythm of the morning shift, before most devs had rolled out of bed, but after the night shift ops guys had gone home.Bad sign number 1: the CEO wandering past, looking a bit lost and vaguely concerned."Can I help you?" Makoto asked, putting down her breakfast pastry.Bad sign number 2 was his reply: "Does the Internet look down to you?"Makoto quickly pulled up her favorite Internet test site, /r/aww, to verify that she still had connectivity. "Seems all right to me.""Well, I can't get online."Webdev-Makoto would've shrugged and thought, Not my circus. Manager-Makoto forced a grin onto her face and said, "I'll get my guys on that.""Thanks, you're a real champ." Satisfied, the CEO wandered back to whatever it was he did all day, leaving Makoto to explain a problem she wasn't experiencing to guys way more qualified to work on this than she was.Hoping to explain the discrepancy, she unplugged her laptop. This time, the adorable kittens failed to load."Success!" she told the empty office. "This is officially some weird wi-fi problem."She drafted up a notice to that effect, sent it to the office mailing list, and assigned her teammate Sven to find and fix the problem. By 9:00 AM, all was well, and her team had sent out an update to that effect.Now well into her daily routine, Makoto put the incident behind her. After all, it was resolved, wasn't it?4:00 PM rolled around, and Makoto was somehow the recipient for an angry email from Greg in Sales. Is the internet still out? I need to close out my sales!!! Why hasn't your team fixed this yet! We could lose $300,000 if I can't close out my sales by 5PM!!!!!Makoto rolled her eyes at the unnecessary number of exclamation points and checked the sales pipeline. Sure enough, there was nothing preventing her from accessing Greg's queue and verifying that all $100 worth of sales were present and accounted for.Makoto cracked her knuckles and crafted the most polite response she could muster: As per my update at 9am, the Internet is back online and you should be able to perform any and all job duties at this time.The reply came 2 minutes later: I cannot close my opportunities!!!Makoto forwarded the email chain to Sven before rolling over to his desk. "Greg's being a drama llama again. Can you pull the firewall logs and prove he's got Internet?""'Course."10 minutes and 4 raised eyebrows later, Sven replied to the ticket, copying Greg's boss and attaching a screenshot of the logs. As Makoto stated, we are online at this time. Is it possible your computer received a virus from browsing PornHub since 9:30 this morning?Greg spent the next day in meetings with HR, and the next week on unpaid leave to think about what he'd done. To this day, he cannot look Sven or Makoto in the eye as they pass each other in the hallway. Makoto suspects he won't suffer long—only as long as it takes him to find another job. Maybe one with IT people who don't know what search keywords he uses. [Advertisement] Scale your release pipelines, creating secure, reliable, reusable deployments with one click. Download and learn more today!
CodeSOD: This or That
Processing financial transactions is not the kind of software you want to make mistakes in. If something is supposed to happen, it is definitely supposed to happen. Not partially happen. Not maybe happen.Thus, a company like Charles R’s uses a vendor-supplied accounting package. That vendor has a professional services team, so when the behavior needs to be customized, Charles’s company outsources that development to the vendor.Of course, years later, that code needs to get audited, and it’s about then that you find out that the vendor outsourced their “professional services” to the lowest bidder, creating a less-than-professional service result.If you want to make sure than when the country code is equal to "HND", you want to be really sure.
Error'd: No Thanks Necessary
"I guess we're not allowed to thank the postal carriers?!" Brian writes.
Finding the Lowest Value
Max’s team moved into a new office, which brought with it the low-walled, “bee-hive” style cubicle partitions. Their project manager cheerfully explained that the new space “would optimize collaboration”, which in practice meant that every random conversation between any two developers turned into a work-stopping distraction for everyone else.That, of course, wasn’t the only change their project manager instituted. The company had been around for a bit, and their original application architecture was a Java-based web application. At some point, someone added a little JavaScript to the front end. Then a bit more. This eventually segregated the team into two clear roles: back-end Java developers, and front-end JavaScript developers.“Silos,” the project manager explained, “are against the ethos of collaboration. We’re all going to be full stack developers now.” Thus everyone’s job description and responsibilities changed overnight.Add an overly ambitious release schedule and some unclear requirements, and the end result is a lot of underqualified developers rushing to hit targets with tools that they don’t fully understand, in an environment that isn’t conducive to concentration in the first place.Max was doing his best to tune out the background noise, when Mariella stopped into Dalton’s cube. Dalton, sitting straight across from Max, was the resident “front-end expert”, or at least, he had been before everyone was now a full-stack developer. Mariella was a long-time backend JEE developer who hadn’t done much of the web portion of their application at all, and was doing her best to adapt to the new world.“Dalton, what’s the easiest way to get the minimum value of an array of numbers in JavaScript?” Mariella asked.Max did his best to ignore the conversation. He was right in the middle of a particularly tricky ORM-related bug, and was trying to figure out why one fetch operation was generating just awful SQL.“Hrmmmm…” Dalton said, tapping at his desk and adding to the distraction while he thought. “That’s a tough one. Oh! You should use a filter!”“A filter, what would I filter on?”Max combed through the JPA annotations that controlled their data access, cursing the “magic” that generated SQL queries, but as he started to piece it together, Dalton and Mariella continued their “instructional” session.“In the filter callback, you’d just check to see if each value is the lowest one, and if it is, return true, otherwise return false.” Dalton knocked out a little drum solo on his desk, to celebrate his cleverness.“But… I wouldn’t know which value is the lowest one, yet,” Mariella said.“Oh, yeah… I see what you mean. Yeah, this is a tricky one.”Max traced through the code. Okay, so the @JoinColumn is CUST_ID, so why is it generating a LIKE comparison instead of an equals? Wait, I think I’ve-“Ah ha!” Dalton said, chucking Max’s train of thought off the rails and through an HO-scale village. “You just sort the array and take the first value!” *Thumpa thumpa tadatada* went Dalton’s little desk drum solo.“I guess that makes sense,” Mariella said.At this point, Max couldn’t stay out of the conversation. “No! Don’t do that. Use reduce. Sorting’s an n(lg n) operation.”“Hunh?” Dalton said. His fingers nervously hovered over his desk, ready to play his next drum solo once he had a vague clue what Max was talking about. “In logs in? We’re not doing logging…”Max tried again, in simple English. “Sorting is slow. The computer does a lot of extra work to sort all the elements.”“No it won’t,” Dalton said. “It’ll just take the first element.”“Ahem.” Max turned to discover the project manager looming over his cube. “We want to encourage collaboration,” the PM said, sternly, “but right now, Max, you’re being disruptive. Please be quiet and let the people around you work.”And that was how Dalton’s Minimum Finding Algorithm got implemented, and released as part of their production code base.[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: A Pre-Packaged Date
Microsoft’s SQL Server Integration Services is an ETL tool that attempts to mix visual programming (for designing data flows) with the reality that at some point, you’re just going to need to write some code. Your typical SSIS package starts as a straightforward process that quickly turns into a sprawling mix of spaghetti-fied .NET code, T-SQL stored procedures, and developer tears.TJ L. inherited an SSIS package. This particular package contained a step where a C# sub-module needed to pass a date (but not a date-time) to the database. Now, this could be done easily by using C#’s date-handling objects, or even in the database by simply using the DATE type, instead of the DATETIME type.Instead, TJ’s predecessor took this route instead:
The Little Red Button
Bryan T. had worked for decades to amass the skills, expertise and experience to be a true architect, but never quite made the leap. Finally, he got a huge opportunity in the form of an interview with a Silicon Valley semi-conductor firm project manager who was looking for a consultant to do just that. The discussions revolved around an application that three developers couldn't get functioning correctly in six months, and Bryan was to be the man to reign it in and make it work; he was lured with the promise of having complete control of the software.Upon starting and spelunking through the code-base, Bryan discovered the degree of total failure that caused them to yield complete control to him. It was your typical hodgepodge of code slapped together with anti-patterns, snippets of patterns claiming to be the real deal, and the usual Assortment-o-WTFâ„¢ we've all come to expect.Once he recognized the futility of attempting to fix this mess, Bryan scrapped it and rewrote it as a full-blown modular and compositional application, utilizing MVVM, DDD, SOA, pub/sub; the works. Within three weeks, he had it back to the point it was when he started, only his version actually worked.While he had righted the sinking ship, it was so successful that the project team started managing it, which proved to be its undoing.Given the sudden success of the project, the department head committed the application to all the divisions company wide within three quarters - without informing Bryan or anyone else on the team. After all, it's not like developers need to plan for code and resource scalability issues beyond the original design requirements or anything.We've read countless stories about how difficult it is to work with things like dates and even booleans, but buttons are pretty much solidly understood. Some combination of text, text+image or just image, and an onAction callback pretty much covers it. Oh sure, you can set fg/bg colors and the font, but that's usually to just give visual clues. Unfortunately, buttons would be the beginning of a downward spiral so steep, that sheer inertia would derail the project.The project manager decided that images were incredibly confusing, so all buttons should have text instead of icons. Bryan had created several toolbars (because ribbons were shot down already) which, according to management, made the application unusable. In particular, there was a fairly standard user icon with a pencil bullet that was meant to (as you might have guessed it) edit users...
CodeSOD: Impersonated Programming
Once upon a time, a long long time ago, I got contracted to show a government office how to build and deliver applications… in Microsoft Access. I’m sorry. I’m so, so sorry. As horrifying and awful as it is, Access is actually built with some mechanisms to actually support that- you can break the UI and behavior off into one file, while keeping the data in another, and you can actually construct linked tables that connect to a real database, if you don’t mind gluing a UI made out of evil and sin to your “real” database.Which brings us to poor Alex Rao. Alex has an application built in Access. This application uses linked tables, which he wants to convert to local tables. The VBA API exposed by Access doesn’t give him any way to do this, so he came up with this solution…
Error'd: Unfortunate Timing
"Apparently, I viewed the page during one of those special 31 seconds of the year," wrote Richard W.
CodeSOD: Changing Requirements
Requirements change all the time. A lot of the ideology and holy wars that happen in the Git processes camps arise from different ideas about how source control should be used to represent these changes. Which commit changed which line of code, and to what end? But what if your source control history is messy, unclear, or… you’re just not using source control?For example, let’s say you’re our Anonymous submitter, and find the following block of code. Once upon a time, this block of code enforced some mildly complicated rules about what dates were valid to pick for a dashboard display.Can you tell which line of code was in a reaction to a radically changed requirement?
The Defensive Contract
Working for a contractor within the defense industry can be an interesting experience. Sometimes you find yourself trying to debug an application from a stack trace which was handwritten and faxed out of a secured facility with all the relevant information redacted by overzealous security contractors who believe that you need a Secret clearance just to know that it was a System.NullReferenceException. After weeks of frustration when you are unable to solve anything from a sheet of thick black Sharpie stripes, they may bring you there for on-site debugging.Beforehand, they will lock up your cell phone, cut out the WiFi antennas from your development laptop, and background check you so thoroughly that they’ll demand explanations for the sins of your great-great-great-great grandfather’s neighbor’s cousin’s second wife’s stillborn son before letting you in the door. Once inside, they will set up temporary curtains around your environment to block off any Secret-rated workstation screens to keep you from peeking and accidentally learning what the Top Secret thread pitch is for the lug nuts of the latest black-project recon jet. Then they will set up an array of very annoying red flashing lights and constant alarm whistles to declare to all the regular staff that they need to watch their mouths because an uncleared individual is present.Then you’ll spend several long days trying to fix code. But you’ll have no Internet connection, no documentation other than whatever three-ring binders full of possibly-relevant StackOverflow questions you had forseen to prepare, and the critical component which reliably triggers the fault has been unplugged because it occasionally sends Secret-rated UDP packets, and, alas, you’re still uncleared.When you finish the work, if you’re lucky they’ll even let you keep your laptop. Minus the hard drive, of course. That gets pulled, secure-erased ten times over, and used for target practice at the local Marine battalion’s next SpendEx.Despite all the inherent difficulties though, defense work can be very financially-rewarding. If you play your cards right, your company may find itself milking a 30-year-long fighter jet development project for all it’s worth with no questions asked. That’s good for salaries, good for employee morale, and very good for job security.That’s not what happened to Nikko, of course. No. His company didn’t play its cards right at all. In fact, they didn’t even have cards. They were the player who walked up to the poker table after the River and went all-in despite not even being dealed into the game. “Hey,” the company’s leaders said to themselves, “Yeah we’ll lose some money, but at least we get to play with the big boys. That’s worth a lot, and someday we’ll be the lead contractor for the software on the next big Fire Control Radar!”So Nikko found himself working on a project his company was the subcontractor (a.k.a. the lowest bidder) for. But in their excited rush to take on the work, nobody read the contract and signed it as-is. The customer’s requirements for this component were vague, contradictory, at times absurd, and of course the contract offered no protection for Nikko’s company.In fact, months later when Nikko–not yet aware of the mess he was in–met with engineers from the lead contractor–whom we’ll call Acme–for guidance on the project, one of them plainly told him in an informal context “Yeah, it’s a terrible component. We just wanted to get out from under it. It’s a shame you guys bid on it…”The project began, using a small team of a project manager, Nikko as the experienced lead, and two junior engineers. Acme did not make things easy on them. They were expected to write all code at Acme’s facilities, on a network with no Internet access. They were asked to bring their own laptops in to develop on, but the information security guys refused and instead offered them one 15-year-old Pentium 4 that the three engineers were expected to share. Of course, using such an ancient system meant that a clean compile took 20 minutes, and the hidden background process that the security guys used to audit file access constantly brought disk I/O to a halt.But development started anyway, depsite all the red flags. They were required to use an API from another subcontractor. However, that subcontractor would only give them obfuscated JAR files with no documentation. Fortunately it was a fairly simple API and the team had some success decompiling it and figuring out how it works.But their next hurdle was even worse. All the JAR did was communicate with a REST interface from a server. But due to the way the Acme security guys had things set up, there was no test server on the development network. It wasn’t allowed. Period.The actual server lived in an integration lab located several miles away, but coding was not allowed there. Access to it was tightly-controlled and scheduled. Nikko found himself writing code, checking it in, and scheduling a time slot at the lab (which often took days) to try out his changes.The integration lab was secured. He could not bring anything in and Acme information security specialists had to sign off on strict paperwork every time he wanted to transfer the latest build there. Debuggers were forbidden due to the fears of giving an uncleared individual access to the system’s memory, and Nikko had to hand-copy any error logs using pen and paper to bring any error messages out of the facility and back to the development lab.Three months into the project, Nikko was alone. The project manager threw some kind of temper tantrum and either quit or was fired. One of the junior engineers gave birth and quit the company during maternity leave. And the other junior engineer accepted an offer from another company and also left.Nikko, feeling burned out and unable to sleep one night, then remembered his father’s story of punchcard programming in computing’s early days. Back then, your program was a stack of punchcards, with each card performing a single machine instruction. You had to schedule a 15-minute timeslot with the computer to run through your program which was actually a stack of punchcards. And sometimes the operator accidentally dropped your box of punchcards on the way to the machine but made no effort to ensure they were executed in the correct order, ruining the job.The day after that revelation, Nikko met with his bosses. He was upset, and flatly told them that the project could not succeed, they were following 1970’s punchcard programming methodologies in the year 2016, and that he would have no part in it anymore.He then took on a job at a different defense contractor. And then found himself working again as a subcontractor on an Acme component. He decided to stick with it for a while since his new company actually read contracts before signing, so maybe it would be better this time? Still, in the back of his mind he started to wonder if he had died and Acme was his purgatory.[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: Questioning Existence
Michael got a customer call, from a PHP system his company had put together four years ago. He pulled up the code, which thankfully was actually up to date in source control, and tried to get a grasp of what the system does.There, he discovered a… unique way to define functions in PHP:
Rubbed Off
Early magnetic storage was simple in its construction. The earliest floppy disks and hard drives used an iron (III) oxide surface coating a plastic film or disk. Later media would use cobalt-based surfaces, providing a smaller data resolution than iron oxide, but wouldn’t change much.Samuel H. never had think much about this until he met Micah.The Noisiest AlgorithmIn the fall of 1980, Samuel was a freshman at State U. The housing department had assigned him Micah as his roommate, assuming that since both were Computer Science majors, they would get along.On their first night together, Samuel asked why Micah kept throwing his books off the shelf onto the floor. “Oh, I just keep shuffling the books around until they’re in the right order,” Micah said.“Have you tried, I don’t know, taking out one book at a time, starting from the left?” Samuel asked. “Or sorting the books in pairs, then sorting pairs of pairs, and so on?” He had read about sorting algorithms over the summer.Micah shrugged, continuing to throwing books on the floor.Divided PrioritiesIn one of their shared classes, Samuel and Micah were assigned as partners on a project. The assignment: write a program in Altair BASIC that analyzes rainfall measurements from the university weather station, then displays a graph and some simple statistics, including the dates with the highest and lowest values.All students had access to Altair 8800s in the lab. They were given one 8“ floppy disk with the rainfall data, and a second for additional code. Samuel wanted to handle the data read/write code and leave the display to Micah, but Micah insisted on doing the data-handling code himself. ”I’ve learned a lot," he said. Samuel remembered the sounds of books crashing on the floor and flinched. Still, he thought the display code would be easier, so he let Micah at it.Samuel finished his half of the code early. Micah, though, was obsessed with Star Trek, a popular student-coded space tactics game, and waited until the day before to start work. “Okay, tonight, I promise,” he said, as Samuel left him in the computer lab at an Altair. As he left, he hard Micah close the drive, and the read-head start clacking across the disk.CorruptedThe next morning, Samuel found Micah still in the lab at his Altair. He was in tears. “The data’s gone,” he said. “I don’t know what I did. I started getting read errors around 1AM. I think the data file got corrupted somehow.”Samuel gasped when Micah handed him the floppy cask. Through the read window in the cover, he could see transparent stripes in the disk. The magnetic write surface had been worn away, leaving the clear plastic backing.Micah explained. He had written his code to read the data file, find the lowest value, write it to an entirely new file, then mark the value in the original file as read. Then it would read the original file again, write another new file, and so on.Samuel calculated that, with Micah’s “algorithm,” the original file would be read and written to n–1 times, given n entries.Old Habits Die HardSamuel went to the professor and pleaded for a new partner, showing him the floppy with the transparent medium inside. Samuel was given full credit for his half of the program. Micah would have to write his entire program from scratch with a new copy of the data.Samuel left Micah for another roommate that spring. He didn’t see much of him, as the latter had left Computer Science to major in Philosophy. He didn’t hear about Micah again until a spring day in 1989, after he had finished his PhD.A grad student, who worked at the computer help desk, told Samuel about a strange man at the computer lab one night. He was despondent, trying to find someone who could help him recover his thesis from a 3 1/2" floppy disk. The student offered to help, and when the man handed him the disk, he pulled the metal tab aside to check for dust.Most of the oxide coating had been worn away, leaving thin, transparent stripes.[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!
Error'd: Unmapped Potential
"As an Australian, I demand that they replace one of the two Belgiums with something to represent the quarter of the Earth they missed!" writes John A.
Error'd: Unmapped Potential
"As an Australian, I demand that they replace one of the two Belgiums with something to represent the quarter of the Earth they missed!" writes John A.
Announcements: Build Totally Non-WTF Products at Inedo
As our friends at HIRED will attest, finding a good workplace is tough, for both the employee and the employer. Fortunately, when it comes looking for developer talent, Inedo has a bit of an advantage: in addition to being a DevOps products company, we publish The Daily WTF.Not too long ago, I shared a Support Analyst role here and ended up hiring fellow TDWTF Ben Lubar to join the Inedo team. He's often on the front lines, supporting our customer base; but he's also done some interesting dev projects as well (including a Source Gear Vault to Git migration tool).Today, we're looking for another developer to work from our Cleveland office. Our code is all in .NET, but we have a lot of integrations; so if you can write C# fairly comfortably but know Docker really well, then that's a great fit. The reason is that, as a software product company that builds tools for other developers, you'll do more than just write C# - in fact, a big part of the job will be resisting the urge to write mountains of code that don't actually solve a real problem. More often than not, a bit of support, a tutorial, an extension/plug-in, and better documentation go a heck of a lot further than new core product code.We do have a couple of job postings for the position (one on Inedo.com, the other on Indeed), and you're welcome to read those to get a feel for the actual bullet points. But if you're reading this and are interested in learning more, you can use the VIP line and bypass the normal process: just shoot me an email directly at apapadimoulis at inedo dot com with "[TDWTF/Inedo] .NET Developer" as the subject and your resume attached.Oh, we're also looking for a Community Manager, to help with both The Daily WTF and Inedo communities. So if you know anyone who might be interested in that, send them my way![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!
Announcements: Build Totally Non-WTF Products at Inedo
As our friends at HIRED will attest, finding a good workplace is tough, for both the employee and the employer. Fortunately, when it comes looking for developer talent, Inedo has a bit of an advantage: in addition to being a DevOps products company, we publish The Daily WTF.Not too long ago, I shared a Support Analyst role here and ended up hiring fellow TDWTF Ben Lubar to join the Inedo team. He's often on the front lines, supporting our customer base; but he's also done some interesting dev projects as well (including a Source Gear Vault to Git migration tool).Today, we're looking for another developer to work from our Cleveland office. Our code is all in .NET, but we have a lot of integrations; so if you can write C# fairly comfortably but know Docker really well, then that's a great fit. The reason is that, as a software product company that builds tools for other developers, you'll do more than just write C# - in fact, a big part of the job will be resisting the urge to write mountains of code that don't actually solve a real problem. More often than not, a bit of support, a tutorial, an extension/plug-in, and better documentation go a heck of a lot further than new core product code.We do have a couple of job postings for the position (one on Inedo.com, the other on Indeed), and you're welcome to read those to get a feel for the actual bullet points. But if you're reading this and are interested in learning more, you can use the VIP line and bypass the normal process: just shoot me an email directly at apapadimoulis at inedo dot com with "[TDWTF/Inedo] .NET Developer" as the subject and your resume attached.Oh, we're also looking for a Community Manager, to help with both The Daily WTF and Inedo communities. So if you know anyone who might be interested in that, send them my way![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!
Open Sources
Here's how open-source is supposed to work: A goup releases a product, with the source code freely available. Someone finds a problem. They solve the problem, issue a pull request, and the creators merge that into the product, making it better for everyone.Here's another way open-source is supposed to work: A group releases a product, with the source code freely available. Someone finds a problem, but they can't fix it themselves, so they issue a bug report. Someone else fixes the problem, issues a pull request, and the creators merge that into the product, making it better for everyone.Here's one way open-source works: Someone creates a product. It gets popular—and I mean really, really popular, practically overnight. The creator didn't ask for this. They have no idea what to do with success. They try their best to keep up, but they can't keep on top of everything all the time. They haven't even set up a build pipeline yet. They're flying by the seat of their pants. One day, unwisely choosing to program with a fever, they commit broken code and push it up to GitHub, triggering an automatic release. Fifteen thousand downstram dependencies find their build broken and show up to scold the creator for not running tests before releasing.Here's another way open-source works: A group creates a product. It gets popular. Some time later, there are 600 open issues and over 50 pending pull requests. The creator hasn't commented in a year, but people keep vainly trying to improve the product.Here's another way open-source works: A group creates a product. They decide to avoid the above PR disaster by using some off-site bug tracker. Someone files a bug. Then another bug. Then 5 or 10 more. The creator goes on a rampage, insisting that everyone is using it wrong, and deletes all the bug reports, banning the users who submitted them. The product continues to gain success, and more and more people file bugs, only to find the bug reports summarily closed. Sometimes people get lucky and their reports will be closed, then re-opened when another dev decides to fix the problem.Here's another way open-source works: Group A creates a product. Group B creates a product, and uses the first product as their support forum. That forum gets hacked. Group B files a bug to Group A, rightly worried about the security of the software they use. After all, if the forum has a remote code exploit, maybe they should move to something newer, maybe written in Ruby instead of PHP. One of the developers from Group A, today's submitter, offers to investigate.Many forums allow admins to edit the themes for the site directly; for example, NodeBB provides admins a textbox in which they can paste CSS to tweak the theme to their liking. This forum figures that since the admins are already on the wrong side of the airtight hatchway, they can inject bits of PHP code directly into the forum header. Code like, say, saving a poison payload to a disk that creates a endpoint that accepts arbitrary file uploads so they can root the box.But how did the hacker get access to that admin panel? Surely that's a security flaw, right? Turns out they'd found a weak link in the security chain and applied just enough force to break their way in. If you work in security, I'm sure you won't be surprised to hear the flaw: one of the admins had a weak password, one right out of a classic dictionary list.Here's another way open-source works: 15% of the NPM ecosystem was controlled by people with weak passwords. Someone hacks them all, tells NPM how they did it, and gets a mass forced-reset on everyone's passwords. Everyone is more secure. [Advertisement] Universal Package Manager – store all your Maven, NuGet, Chocolatey, npm, Bower, TFS, TeamCity, Jenkins packages in one central location. Learn more today!
Open Sources
Here's how open-source is supposed to work: A goup releases a product, with the source code freely available. Someone finds a problem. They solve the problem, issue a pull request, and the creators merge that into the product, making it better for everyone.Here's another way open-source is supposed to work: A group releases a product, with the source code freely available. Someone finds a problem, but they can't fix it themselves, so they issue a bug report. Someone else fixes the problem, issues a pull request, and the creators merge that into the product, making it better for everyone.Here's one way open-source works: Someone creates a product. It gets popular—and I mean really, really popular, practically overnight. The creator didn't ask for this. They have no idea what to do with success. They try their best to keep up, but they can't keep on top of everything all the time. They haven't even set up a build pipeline yet. They're flying by the seat of their pants. One day, unwisely choosing to program with a fever, they commit broken code and push it up to GitHub, triggering an automatic release. Fifteen thousand downstram dependencies find their build broken and show up to scold the creator for not running tests before releasing.Here's another way open-source works: A group creates a product. It gets popular. Some time later, there are 600 open issues and over 50 pending pull requests. The creator hasn't commented in a year, but people keep vainly trying to improve the product.Here's another way open-source works: A group creates a product. They decide to avoid the above PR disaster by using some off-site bug tracker. Someone files a bug. Then another bug. Then 5 or 10 more. The creator goes on a rampage, insisting that everyone is using it wrong, and deletes all the bug reports, banning the users who submitted them. The product continues to gain success, and more and more people file bugs, only to find the bug reports summarily closed. Sometimes people get lucky and their reports will be closed, then re-opened when another dev decides to fix the problem.Here's another way open-source works: Group A creates a product. Group B creates a product, and uses the first product as their support forum. That forum gets hacked. Group B files a bug to Group A, rightly worried about the security of the software they use. After all, if the forum has a remote code exploit, maybe they should move to something newer, maybe written in Ruby instead of PHP. One of the developers from Group A, today's submitter, offers to investigate.Many forums allow admins to edit the themes for the site directly; for example, NodeBB provides admins a textbox in which they can paste CSS to tweak the theme to their liking. This forum figures that since the admins are already on the wrong side of the airtight hatchway, they can inject bits of PHP code directly into the forum header. Code like, say, saving a poison payload to a disk that creates a endpoint that accepts arbitrary file uploads so they can root the box.But how did the hacker get access to that admin panel? Surely that's a security flaw, right? Turns out they'd found a weak link in the security chain and applied just enough force to break their way in. If you work in security, I'm sure you won't be surprised to hear the flaw: one of the admins had a weak password, one right out of a classic dictionary list.Here's another way open-source works: 15% of the NPM ecosystem was controlled by people with weak passwords. Someone hacks them all, tells NPM how they did it, and gets a mass forced-reset on everyone's passwords. Everyone is more secure. [Advertisement] Universal Package Manager – store all your Maven, NuGet, Chocolatey, npm, Bower, TFS, TeamCity, Jenkins packages in one central location. Learn more today!
CodeSOD: Swap the Workaround
Blane D is responsible for loading data into a Vertica 8.1 database for analysis. Vertica is a distributed, column-oriented store, for data-warehousing applications, and its driver has certain quirks.For example, a common task that you might need to perform is swapping storage partitions around between tables to facilitate bulk data-loading. Thus, there is a SWAP_PARTITIONS_BETWEEN_TABLES() stored procedure. Unfortunately, if you call this function from within a prepared statement, one of two things will happen: the individual node handling the request will crash, or the entire cluster will crash.No problem, right? Just don’t use a prepared statement. Unfortunately, if you use the ODBC driver for Python, every statement is converted to a prepared statement. There’s a JDBC driver, and a bridge to enable it from within Python, but it also has that problem, and it has the added cost of requiring a a JVM running.So Blane did what any of us would do in this situation: he created a hacky-workaround that does the job, but requires thorough apologies.
CodeSOD: Swap the Workaround
Blane D is responsible for loading data into a Vertica 8.1 database for analysis. Vertica is a distributed, column-oriented store, for data-warehousing applications, and its driver has certain quirks.For example, a common task that you might need to perform is swapping storage partitions around between tables to facilitate bulk data-loading. Thus, there is a SWAP_PARTITIONS_BETWEEN_TABLES() stored procedure. Unfortunately, if you call this function from within a prepared statement, one of two things will happen: the individual node handling the request will crash, or the entire cluster will crash.No problem, right? Just don’t use a prepared statement. Unfortunately, if you use the ODBC driver for Python, every statement is converted to a prepared statement. There’s a JDBC driver, and a bridge to enable it from within Python, but it also has that problem, and it has the added cost of requiring a a JVM running.So Blane did what any of us would do in this situation: he created a hacky-workaround that does the job, but requires thorough apologies.
Classic WTF: The Proven Fix
Classic WTF: The Proven Fix
CodeSOD: Classic WTF: When the Query String is Just Not Enough
CodeSOD: Classic WTF: When the Query String is Just Not Enough
Error'd: Best Null I Ever Had
"Truly the best null I've ever had. Definitely would purchase again," wrote Andrew R.
Error'd: Best Null I Ever Had
"Truly the best null I've ever had. Definitely would purchase again," wrote Andrew R.
The Agreement
In addition to our “bread and butter” of bad code, bad bosses, worse co-workers and awful decision-making, we always love the chance to turn out occassional special events. This time around, our sponsors at Hired gave us the opportunity to build and film a sketch.I’m super-excited for this one. It’s a bit more ambitious than some of our previous projects, and pulled together some of the best talent in the Pittsburgh comedy community to make it happen. Everyone who worked on it- on set or off- did an excellent job, and I couldn't be happier with the results.Once again, special thanks to Hired, who not only helped us produce this sketch, but also helps keep us keep the site running. With Hired, instead of applying for jobs, your prospective employer will apply to interview you. You get placed in control of your job search, and Hired provides a “talent advocate” who can provide unbiased career advice and make sure you put your best foot forward. Sign up now, and find the best opportunities for your future with Hired. And now, our feature presentation: The AgreementBrought to you by:
The Agreement
In addition to our “bread and butter” of bad code, bad bosses, worse co-workers and awful decision-making, we always love the chance to turn out occassional special events. This time around, our sponsors at Hired gave us the opportunity to build and film a sketch.I’m super-excited for this one. It’s a bit more ambitious than some of our previous projects, and pulled together some of the best talent in the Pittsburgh comedy community to make it happen. Everyone who worked on it- on set or off- did an excellent job, and I couldn't be happier with the results.Once again, special thanks to Hired, who not only helped us produce this sketch, but also helps keep us keep the site running. With Hired, instead of applying for jobs, your prospective employer will apply to interview you. You get placed in control of your job search, and Hired provides a “talent advocate” who can provide unbiased career advice and make sure you put your best foot forward. Sign up now, and find the best opportunities for your future with Hired. And now, our feature presentation: The AgreementBrought to you by:
...33343536373839404142...