CodeSOD: Hero on the Half Shell |
Melissas co-worker needed to write some Python code to kill an external process. There are some third-party modules, like psutil that can solve that problem, but companies like Initech tend to put lots of obstacles along the path of bringing third-party code into your applications.
Without third-party tools, youre stuck shelling out. Using built-in Python functions like os.system or the subprocess module. This lets you run commands like ps and kill from inside of your Python program. Its inelegant, but it works just fine. Theres certainly nothing wrong with it.
Melissas co-worker saw the inelegant solution, and said to themselves, Can I make that more ineleganter?
This code searches for every process thats a server for their application, and then kills them.
def kill_process(self):
server_pid_count_str = ""
server_pid_count_str = subprocess.check_output(
"ps -e -opid,args | grep SERVER | grep " + self.server_name +
" | sed '/grep/d' | wc -l", shell=True).strip()
if server_pid_count_str.isdigit():
server_pid_count = int(server_pid_count_str)
for i in range(0, server_pid_count):
pid_server = subprocess.check_output(
"ps -e -opid,args | grep SERVER | grep " +
self.server_name + " | sed '/grep/d' | sort | head -1 | tail -1 | awk '{print $1}'",
shell=True).strip()
if pid_server.isdigit():
subprocess.check_call("kill -9 " + pid_server, shell=True)
Look at that thing of beauty. It counts the number of server processes using wc -l, then it does a for-loop that number of times. Inside the for-loop, it calls out to ps again, but this time it sorts the results and passes them through head -1 | tail -1 to get a single line, which it then picks the PID out of to kill. Also, I dont know where the variable self.server_name gets its value from, but I hope its not from some external source, because the use of shell=True makes this vulnerable to shell injection.
|
Метки: CodeSOD |
Thrilling Tales of Software Development: The Eighth Man |
Today, we bring you another hastily-drawn, stick-figure video that recounts a true tale of requirements gathering and software development. Remember: gathering requirements is hard.
http://thedailywtf.com/articles/thrilling-tales-of-software-development-the-eighth-man
|
Метки: Feature Articles |
CodeSOD: Random Ruby |
Peri, the new intern, was proving her worth as a programmer rapidly. She was great with finding clever solutions to problems, and she didn't bother the more senior devs too often while doing it: a boon, as they were trying to get their own work done.
So when Steven assigned her a simple task—generate some unique IDs for repeated dynamic elements so the automated test team could keep track of which ones were which—he figured she didn't need any hand-holding.
"Good news!" she reported a few days later. "I completed that task you assigned me easily, ahead of schedule, and in only a single line of code." She preened, clearly proud of her work.
Steven, who had long since moved on to other things, smiled at her. "That's great, Peri! I'll get you another ticket in a few minutes, after I approve your pull request."
Peri skipped away happily.
Steven finished the line he was on, pulled up Stash to skim over the PR—and stopped short.
You see, the thing about Ruby is that you can do a lot in a single line of code. It's very compact and expressive that way. So when Peri said she'd written only a single line, well ...
unique_id = ('a'..'z').to_a.shuffle[0,8].join
For those of you who aren't familiar with Ruby, let's break that down:
('a'..'z') creates a Range object for iterating over the characters 'a' through 'z' to_a casts to an array by iterating over the Range and pushing each element into a fresh arrayshuffle randomizes the elements in the array (which internally calls Ruby's rand function 25 times)[0,8] grabs the first eight elements in the array and creates a new array with themjoin merges that array into a stringSteven declined the pull request, replacing it with his own, far less "clever" code:
rand(1000000000)
|
Метки: CodeSOD |
Error'd: Questionable Judgement |
"Definitely memorable, but I'm not so sure about the question," writes Shish.
"Not sure about you, but that's always how I answer questions," writes Andy D.
"I'd love to know how I'm supposed to remember the security answer to THAT one...," writes Gino.
"I swear I only selected one update, but Windows is going to install another one anyway," wrote George Q.
"Trains in Germany are among the best in the world," Jan writes, "Their secret, I assume, is frequent kernel updates."
Jason M. wrote, "The MSDN newsletter had a great deal on the NDC Australia conference...even though it was three weeks late."
"Since I never received the email, I'm assuming the registration didn't work, but it's kinda hard to tell from the messages," Ryan wrote.
Doug R. wrote, "Dear Auspost - your help page needs help."
[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!
|
Метки: Error'd |
CodeSOD: Authorized Users |
Hey, since Jack quit, you could add Jane to the investigation users?
William M supported one piece of a large, complicated intranet application used by auditors as part of investigations into events within the organization. The overall audience is small, and the purpose of the application is mostly to document the process of the investigation. Since its so niche, it doesnt even have a screen for managing user accounts- the users raise a ticket and rope in developers to manage it.
The developer in charge of the secure portion of the application- Rick- was busy, so William caught the ticket. He wasnt sure what to do, so he shot an IM over to Rick.
Oh, its easy, Rick replied. Just update Jacks record with Janes user info. Thats the easiest way, since Jack quit.
That didnt seem like a smart process, but William was in a rush and this was Ricks baby, so he just followed instructions and closed the ticket. Jane re-opened the ticket- she couldnt access the audit compliance tracker. Jack had never used that page, but Jane planned to.
Rick was still busy, so William decided to take a look at the authorization process. He found this code in the main-menu screen of the application.
if (Convert.ToInt32(Session["UserID"]) == 201 ||
Convert.ToInt32(Session["UserID"]) == 226 ||
Convert.ToInt32(Session["UserID"]) == 214 ||
Convert.ToInt32(Session["UserID"]) == 258 ||
Convert.ToInt32(Session["UserID"]) == 260 ||
Convert.ToInt32(Session["UserID"]) == 22 ||
Convert.ToInt32(Session["UserID"]) == 303 ||
Convert.ToInt32(Session["UserID"]) == 444 ||
Convert.ToInt32(Session["UserID"]) == 32 ||
Convert.ToInt32(Session["UserID"]) == 388 ||
Convert.ToInt32(Session["UserID"]) == 413 ||
Convert.ToInt32(Session["UserID"]) == 392)
{
btnSecureArea.Visible = true;
}
No… no way.
William checked one of the other secure pages.
int userID;
if (!int.TryParse(Session["UserID"].ToString(), out userID))
{
Response.Redirect("NavigationPage.aspx");
}
if (
!(userID == 201 //Jerry
|| userID == 226 //Lisa
|| userID == 214 //Alban
|| userID == 258 //David
|| userID == 22 //Jack
|| userID == 444 //Tyrell
|| userID == 303 //Brenda
|| userID == 413 //Phung
|| userID == 388 //Ignacio
|| userID == 399)//Norma
)
{
Response.Redirect("NavigationPage.aspx");
}
This wasnt looking so great. William pulled up the code for the audit compliance tracker that was causing Jane trouble.
if (Convert.ToInt32(Session["UserID"]) == 201 ||//Jerry
Convert.ToInt32(Session["UserID"]) == 226 ||//Lisa
Convert.ToInt32(Session["UserID"]) == 214 ||//Alban
Convert.ToInt32(Session["UserID"]) == 258 ||//David
Convert.ToInt32(Session["UserID"]) == 303 ||//Brenda
Convert.ToInt32(Session["UserID"]) == 32 ||//Clementina
Convert.ToInt32(Session["UserID"]) == 199 ||//Shyla
Convert.ToInt32(Session["UserID"]) == 232 ||//Harmony
Convert.ToInt32(Session["UserID"]) == 413 ||//Phung
Convert.ToInt32(Session["UserID"]) == 388 ||//Ignacio
Convert.ToInt32(Session["UserID"]) == 399) //Norma
{
}
else
{
Response.Redirect("NavigationPage.aspx");
}
Well, it wasnt hard to see why Jack-now-Janes user id got kicked out of the page. With all the copypasta, things had gotten out of sync. Even better, this code was inside of the Page_Load handler on a WebForm, and since it didnt return on failure, the rest of the Page_Load event executed, even though the user didnt have permission to access the page.
William didnt have the time or permission to actually move this data into the database, but he did spend the time to refactor the copy/pasted code into a single method that used a list of IDs. By making sure the authorizer quits on failure, he also fixed half-a-dozen low-priority unexplainable bugs caused by side effects from the Page_Load executing.
[Advertisement]
Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.
|
Метки: CodeSOD |
Website Hacker |
An investment bank had just completed development on a new digital retailing platform. Daniel was assigned to a cross-functional automated test team, gearing up to test the platform's web application—or at least trying to. Charlie, a veteran manual tester from QA, had been vocal in his opposition.
"Automated tests need to be tested themselves, which means the testers need to test the tests, so automation doesn't save anything. If anything, it creates more work! Besides, we should always be striving to recreate the user experience as closely as possible!"
Daniel and the other developers insisted that manual testing was valuable, but automation needed to happen too. The conflict marched up the org chart, culminating in a meeting with Charlie's boss, Daniel's boss, their bosses, their bosses' bosses, all the way up the org-chart to where these branches of the organization finally joined.
The verdict was handed down. Charlie was appointed the leader on testing the web application, running through the same test cases in a manual fashion to catch any problems that fell through the cracks.
The team—developers, QA, and a tech lead—all abandoned their cubes to huddle together in a large conference room. Everything went smoothly until one afternoon, when Charlie piped up with the nervousness of one staring down a cobra poised to lash out.
"Fellas? I don't know how I did it, but I hacked into the website somehow. I see all of the code."
The people seated closest to him glanced up from their work to trade frowns.
"What do you mean?" Daniel asked, glancing across the table at Charlie.
"I'm in the browser, and I can see all of the code!" Charlie explained. "I've hacked into the website. I see stuff like, 'div class equal sign—'"
In other words, the HTML source. Those who were listening in burst into relieved laughter, prompting everyone else in the room to quit their work and pay attention to the faux emergency.
The far more patient tech lead bit her bottom lip to hide her grin. "Charlie, it sounds like you opened the developer tools in Chrome by accident. Press F12, it'll go away."
Charlie hunted down the key and pecked it with a single loud stroke. "OK, it's gone," he said as though he’d just diverted a nuclear strike. His gaze swept over the room with a mix of urgency and confusion. "I'm still really concerned. That shouldn't happen!"
"It's supposed to do that," Daniel explained. "Go to any website you want, you can do that on any of them."
"What?!" Charlie flipped to a different browser tab, then pressed F12 again. "What?! No!"
Another burst of laughter drowned out his concern.
"Check out the leet haxxor here," one of the developers cracked.
"Step away from the computer, Charlie, before you hack the whole Internet!" another developer commanded, pointing a finger-gun at the hapless tester.
"Charlie, it's just—" Daniel tried to say.
"We can't keep using this browser!" Charlie declared. "I'm raising a defect for this!"
"All browsers have something like that for debugging purposes," Daniel explained. "It's not just Chrome."
But as the giggles continued around him, Daniel's plea seemed to fall on deaf ears. Charlie tabbed over to their bug tracker and took to some furious hunting and pecking.
Daniel shook his head. Let Charlie log his defect if it made him feel better. Surely no one would take it seriously.
Unfortunately, QA heads and project leads took "security threats" very seriously. The conflict escalated up through bosses, bosses' bosses, and eventually, the verdict was handed down. To avoid exposing code to users, further web development and testing involving Chrome was suspended company-wide.
[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: Safely Configured |
Configuration files are, well… files. File operations are risky- theres a lot of reasons why they might fail, and we have to be prepared to handle those execptions.
For example, maybe youve written an application that reads a configuration file at launch. If, for some reason, it failed to load that config, youd need to deal with that. If the configuration were just some minor settings, you might choose to fallback to some reasonable defaults. If, on the other hand, the configuration contained important security settings, you would probably want to quit the application, or maybe fallback into some safety mode.
Patrick U. assumed that was how the NodeJS application he was working on behaved. Then, one of his fellow developers pushed their latest release into production. He went to log into his admin account, and found his password didnt work- because it had been mysteriously changed to the incredibly insecure admin. After a little poking, he found someone had left off a closing-quote in their JavaScript configuration file, and that solved the problem. But why did his password get changed when the config file was broken? Well, this code was responsible for loading the file:
try {
settings = require('../Settings');
}
catch (e) {
settings = {
users: {
admin: { password: 'admin', is_admin: true },
grace: { password: 'admin', is_admin: true },
patrick: { password: 'admin', is_admin: true },
bert: { password: 'foobar', is_admin: false }
}
};
}
[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 Laser Storm of Family Fun |
Ben was half of the two-man IT department at Bobs Family Fun Center. It was a popular local place for kids and adults alike to come get wild in go-carts, blast each other in laser tag, and spend copious amounts of tokens to win cheap plastic crap with tickets from arcade games. Bob the owner employed his nephew Ted as the head of IT. All it took to qualify Ted for the job was helping Bob out with a home computer problem once.
|
Метки: Feature Articles |
Error'd: The Errors Mean that it's Working |
"After all, it's the courage to install that counts," writes Aaron
"Cool, looks like IMAPSize has also the concept of anti-mailspace, just like matter and anti-matter?" wrote Michael B.
"Everyone knows Alienware is way overpriced, but they're taking the joke way too far," Mike H. writes.
Mike L. wrote, "I have to wonder if SQL Server even knows what it's doing."
"Great! Spending NaN zl on some games fits right into my budget!" writes Jakub C.
"While I was away from my keyboard, JIRA thought it should tell me everything is OK with a error," writes Niels.
Peter G. wrote, "Sure! I'd love to... wait, what?"
Chris D. wrote, "I ordered product.DisplayName on my satellite box, but who wouldn't? product.Price is a heck of a good deal."
[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/the-errors-mean-that-it-s-working
|
Метки: Error'd |
CodeSOD: Unselected |
In the movie Man of the Year, Robin Williams plays a Jon Stewart-esque comedian who runs for President of the United States. He wins the general election due to a programming glitch in some e-ballot machines deployed nationwide.
In Belgium, as Adrien F. can attest, this very nearly happened.
The city of Brussels has used electronic voting since 1994. Delacroy Europe implemented the first electronic ballots for the city; the firm developed their e-ballot program in C, which ran on floppy disks and stored votes on plastic cards using magnetic strips. Every year the firm would introduce little tweaks to make their system easier to use, but it was showing its age.
On May 25th, 2014, Belgium held elections for many EU and national parliament seats, as well as some local contests. The next day, election officials noticed some irregularities with votes cast in Brussels using Delacroy Europes program.
About 2000 votes had to be voided, as they contained multiple votes for the same office from different parties (called lists in Belgium). It wasnt enough to sway any one election, but the media had already caught wind of the potential voter fraud. Adriens company was hired for an independent code review of Delacroy Europes voting program to determine if anything criminal had transpired.
First, Adrien ruled out users manually rewriting data to the magnetic strip on the ballot card. It would require a credit card reader, which would have been difficult to smuggle into a polling place, and unlikely to happen on the scale of 2000 ballots or so. He suspected the problem was in the code.
He noticed something strange in the UI selection functions, triggered when the user selects a candidate on the viewscreen. Parliamentary ballots were organized by lists that a user picked from. Cand_Check_Selection() determines if a candidate was checked, and if so, whether to select or unselect them (either Cand_Select() or Cand_Unselect()).
void Cand_Select(int _x, int _y, int _z)
{
arcMemoCandid[_x][_y][_z] = 1;
arcMemoList[_x][_y] = 1;
arcMemoScrutin[_x] = 1;
}
void Cand_Unselect(int _x, int _y, int _z)
{
arcMemoCandid[_x][_y][_z] = 0;
//280613 arcMemoList[_x][_y] = 0;
//280613 arcMemoScrutin[_x] = 0;
}
static int Cand_Check_Selection(int _iX, int _iY)
{
...
if((_iY>=y1) && (_iY<=y2)) /* This area */
{
if(arcMemoCandid[giCurrentScr][giCurrentList][i] == 0) /* Unselected -> Selected */
{
++giNbCandidSel; /* cfr iSWDeselectC */
Cand_Select(giCurrentScr,giCurrentList,i);
Cand_Update(i);
Cand_Circle(i);
Cand_Switch(i);
return(0);
}
#ifdef EL2014
else /* Selected -> Unselected */
{
--giNbCandidSel; /* cfr iSWDeselectC */
if (giNbCandidSel == 0) {
swpas = swnoir = swconf = 0;
}
Cand_Unselect(giCurrentScr,giCurrentList,i);
Cand_Update(i);
Cand_Circle(i);
Cand_Switch(i);
return(0);
}
#endif
}
...
}
He found two commented lines, dated June 28, 2013, a year before election day. A developer, looking at Card_Unselect(), realized that by unselecting a candidate, it also unselected everyone in that candidates list. They commented out two lines, thinking they had fixed the error. However, the unselection algorithm never decremented the check counter, which kept track of how many candidates had been chosen. If a user checked a candidate on one list, changed their mind, and picked another from a separate list, then both votes would be counted.
It hadnt been a case of fraud, but some poorly-placed comments.
So far, Brussels has not seen any further election scandals, but Adrien knows with this kind of code, its only a matter of time.
[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 |
Overpowered |
Mike had a different perspective on wiring and cable management- because he worked at a factory which made wires and cables. It was the early90s, and he was in charge of babysitting a couple of VAXes and their massive, 85lb hard drives. It was an easy job: the users knew the system and needed very little support, the VAXes were practically unstoppable, and the backup battery system could keep the entire thing running for over an hour.
The computers supported HR and accounting, which meant as the year ticked towards its end, Mike had to prep the system for its heaviest period of use- the year end closing processes. Through the last weeks of December, his users would be rushing to get their reports done and filed so they could take off early and enjoy the holidays.
Mike had been through this rodeo before, but Reginald, the plant manager, called him up to his office. There was going to be a wrench in the works this year. Mike sat down in Reginalds cramped and stuffy office next to Barry, the chief electrician for the plant.
Our factory draws enough power from the main grid that the power company has a substation thats essentially dedicated to us, Reginald explained. But theyve got a problem with some transformers loaded with PCBs that they want to replace, so they need to shut down that substation for a week while they do the work.
The factory portion was easy to deal with- mid-December was a period when the assembly line was usually quiet anyway, so the company could just shift production to another facility that had some capacity. But there was no way their front-office could delay their year-end closing processes.
So, to keep the office running, well be bringing in a generator truck, Reginald said. And that means were going to need to set up a cut-over from the main grid to the generator.
From the computer-room side, the process was easy, but that didnt stop Mike from writing up a checklist, taping it to the wall beside his desk and sharing a copy with Barry. Before the generator truck arrived, hed already tested the process several times, ensuring that he could go from mains power to battery and back to mains power without any problem.
The generator truck arrived a week before the changeover. The electricians ignored it for a few days. Just as Mike was starting to get worried about deadlines, he looked out a window and saw a trio of electricians, lead by Barry, starting to connect cables to it. Later that day, when Mike left to go to lunch, he walked past the generator truck, and noticed something odd about the cables- they were clearly single phase power cables.
Typical residential power systems are single-phase alternating current- one peak, one trough. This creates dead moments in the cycle, where no work is being done. Thats fine for residential use- but industrial systems need three-phase power- three offset AC cycles that, when added together, guarantee current is always flowing.
Hey, Mike said to one of the electricians loitering near the truck, youre planning to run some three-phase cabling, right?
Nope. The factorys shut down- this thing is just gonna run lights and heating.
And computers, Mike said. The hard drives need three-phase power.
Well have to order some parts, the electrician said.
A few more days ticked by with no three-phase connections, and Mike checked in with the electricians again.
The parts are coming.
At this point, Reginald came down from his office to the computer room. Mike, Barrys telling me youre being a disruption.
What?
Look, theres a chain of command, Reginald said. And you cant tell the electricians how to do their job.
Im no-
From now on, if you have any concerns, bring them to me.
The day of the cut-over, the three-phase cabling finally arrived. Barry and his electricians quickly strung those cables from the generator. Mike wasnt exactly watching them like a hawk, but he was worried- there was no way they could test the configuration while they were working so hastily. Unlike single-phase power, three-phase power could be out-of-sync, which would wreak havoc on the hard drives. He thought about bringing this up to the electricians, but recalled Reginalds comments on the chain of command. He went to Reginald instead.
Mike, Reginald said, shaking his head. I know you computer guys think you know everything, but youre not an electrician. This is a factory, Mike, and youve got to learn a little about what its like to work for a living.
Now, the electricians and Mike needed to coordinate their efforts, but Reginald strictly enforced the idea of the chain of command. One electrician would power on the generator and announce it, Generators running. Another electrician would relay this to Barry: Generators running. Barry would relay that to Reginald. Generators on. Reginald, finally, would tell Mike.
At 1PM, the electric company cut the power to the factory. The lights went out, but the computers kept humming along, running off battery power. A few minutes later, and a few games of telephone between electricians and Reginald, the lights came back on.
Mike stopped holding a breath that he didnt know hed been holding. Maybe hed been too worried. Maybe he was jumping at shadows. Everything was going well so far.
Tell the computer guy to switch back to mains power, called one of the electricians.
Tell the computer guy to switch back to the mains, Barry repeated.
Mike, switch back to the mains, Reginald ordered.
Mike threw the switch.
BOOOOOOOOOOOOOOMMMMMM
The computer room shook so violently that Mike briefly thought the generator had exploded. But it wasnt the generator- it was the hard drives. They didnt literally explode, but 85lbs of platter spinning at about 3,000 RPMs had a lot of momentum. The motor that drove the spindle depended on properly sequenced three-phase power. The electricans had wired the power backwards, and when Mike switched to mains power, the electric motor suddenly reversed direction. Angular momentum won. The lucky drives just broke the belt which drove the spindle, but a few of them actually shrugged their platters from the spindle, sending the heavy metal disks slamming into the sides of the enclosure with a lot of energy.
For the first and only time in his career, Mike slammed a fist into the emergency stop button, cutting all power from the computer room.
Year end closing got delayed. It took the better part of a month for Mike to recover from the disaster. While he focused on recovering data, the rest of the organization kept playing their chain-of-command telephone.
The electricians couldnt be at fault, because they took their orders from Barry. Barry couldnt be at fault, because he took his orders from Reginald. Reginald couldnt be at fault, because he followed the chain of command. Mike hadnt always followed the chain of command. Therefore, this must be Mikes fault.
Once the data recovery was finished, he was fired.
[Advertisement]
Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.
|
Метки: Feature Articles |
CodeSOD: Keeping Regular |
Regular expressions can create new problems. Like an industrial drill, theyre extremely powerful- and potentially destructive. Theyre expensive, theyre cryptic, but can be extremely concise.
For example, Jessica is reimplementing some C# code written by another developer. This developer was never interested in being concise, and instead favored being clever. For example, this developer had an array of strings, and needed to remove any non-word-characters from each string.
A regex-based solution might include something like [^\w] which is obviously incomprehensible nonsense that no one could be expected to understand without piles and piles of documentation.
Jessicas co-worker wrote something far more… elegant.
for (int i = 0; i <= name.Length - 1; i++) {
String sTemp = "";
for (int j = 0; j <= name[i].Length - 1; j++)
{
if ("QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789_".Contains(name[i][j]))
{
sTemp += name[i][j];
}
}
name[i] = sTemp;
}
Heres a fun question. Given this input array (Malcolm,Ermelinda,Annika,Jesusa,Honey,Romelia,Dorene,Alvaro,Charmaine,Georgann,Troy), how many String instances does this code construct and throw away for concatenation?
Jessicas co-worker had a problem, so he avoided regexes. He still has problems.
[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 |
Just Check The Notepad |
As the last deployment script ran to completion, Michael sat back in his chair and let out a small sigh of relief.
He knew nothing could go wrong. After all, he'd rehearsed every step of the process hundreds of times during the last six months. But deploying his projects to production always made him as nervous as a highschooler before a drama club premiere.
However, the rollout was nearly complete, and Initech's Hyderabad branch was all set up and ready to enjoy their new, polished and improved inventory management system. All that was left was to log into the application for the last sanity check and celebrate the success with his team.
Michael opened the browser, typed in the server address and hit Enter, expecting to see the familiar portal.
Instead, a standard, white-and-red ASP.NET error page stared back at him.
A few minutes of digging around the Hyderabad servers exposed the problem. While all the local applications were configured to use Windows logins to connect to the database, the overseas branch used simple SQL Server authentication with a constant login and password. After a bit of back and forth, Michael was armed with contact information to Hyderabad's database administrator, and set off to resolve the issue.
Hi, it's Michael from Initech Seattle, he typed into his Lync window. Can I get a database username and password for the inventory management application?
A few minutes later, the reply arrived. Expecting just the username and password, Michael was ready to say thanks and get back to fixing his problem ... but the DBA had a different idea.
Sure, just check the Notepad on the server.
You mean a text file? Michael responded, somewhat confused.
Yes, it's open now, just check your screen.
Michael went through all his open Remote Desktop sessions, but none of them had a single text file open. The only programs running were the ones he'd started himself.
I don't see it, can you tell me the filename and the directory? He decided to play along. After all, maybe there was some security-related reason why the DBA couldn't send the credentials over IM.
It's in the Notepad, the DBA responded. Just check it.
No, it's not! Michael was growing a bit irritated. He took the screenshots of both the database and application servers' desktops and attached them to the message, hoping that would finally convince the DBA he wasn't going crazy.
After a long while, the DBA finally wrote back. You're on Remote Desktop. That's different. Can you just use TeamViewer?
"Are you serious?" Michael asked out loud, but the will to resolve the issue as soon as possible overcame the urge to chew out the clueless administrator. He downloaded the software, sat through the installation process, then typed in the TeamViewer ID.
A connection could not be established.
"Of course," Michael muttered.
A quick call to system administrators confirmed Michael's fears: the company firewall blocked all TeamViewer connections. Gaining access meant submitting an exemption request and letting the bureaucracy take its time to process it. The process usually required several days, and the rollout couldn't wait that long.
Facing a dead end, he tried to explain the situation to the DBA.
I can't get on TeamViewer. Can you please just tell me the username and password for the SQL Server? It would really save us a lot of time!!
He sat back in his chair and waited, eyes glued to the IM window. His hopes weren't high, but maybe he'd at least get an excuse to present to his boss.
Instead, the reply came:
Username: dba, password: rosebud. Let me know if I can be of any further help.
It was all Michael could do not to slam his head against his desk. After careful consideration, he decided to pass on the DBA's kind offer.
[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!
|
Метки: Feature Articles |
Error'd: An Unusually Childish Debate |
"Hilarity ensued when, during a recent political debate, the subtitles used by the Swedish state television came, not from authorized subtitlers of the debate, but rather the neighboring children's channel," Jonas writes.
"By providing the option to 'Give up', I sense they are at least being honest with me about the state of their web site," writes John Z.
"While I don't doubt that it's portable, it does seem inconvenient to have to gas up a signal generator," wrote Nathaniel M.
Alaks M. wrote, "Thanks Apple for your amazing error report. I didn't even have anything open."
"I mean, sure, music tastes vary, but come on!" writes Bruce R.
Chris M. wrote, "Well ReSharper, the test is green, but I'm not so sure if I should check it in."
Chris D. wrote, "The Perimeter Institute for Theoretical Physics is in denial about the 100+ seminars that they just returned matching my search criteria."
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an
impressively-featured free edition, too!
http://thedailywtf.com/articles/an-unusually-childish-debate
|
Метки: Error'd |
CodeSOD: Log of String |
The English language contains words with multiple and often contradictory meanings. A dress, for example, is only one of many items you could put on while dressing yourself. Meanwhile, if you want to wear pants instead, you should avoid pantsing yourself, as that would be counter-productive.
These shades of meaning come into play frequently in programming. Writing a .NET application to manage school schedules requires some contortions to avoid using the reserved word class, and writing one to hold Dungeons and Dragons character sheets requires you to spell out the attribute Intelligence instead of using the far more common abbreviation int.
Dimitris, however, wasn't thinking about the many interesting tidbits to be found in the English language as he went about tracing an error message through the stack his formula engine application had unraveled. Instead, he was thinking about logging. Not the act of felling trees and preparing their corpses for use by humans, but the act of writing messages to a central location so that debugging an application would be easier.
Logging has a fascinating etymology, by the way. It originally had to do with a bit of wood that was designed to float upward when a ship sank, making it easier for someone to discover what had befallen the ship by reading its log. In the same manner, Dimitris wanted to discover what had happened to the application—but he got distracted along the way.
/**
* override xxLog as it writes unnecessarily to database syslog
*/
function xxLog( tag, s )
{
if (sbDebugEnabled) {
text_write( prx_debug_file, str(tag) + "|" + (( is_na(s)) ? "NA" : str(s) ));
}
if (sbDebugPrintEnabled) {
print( str(tag) + " : " + (( is_na(s)) ? "NA" : str(s) ));
}
}
Demetris found the exact same snippet at the top of every system class, across hundreds of files. Why had the code's previous maintainer continually overridden the base log functionality like this? What use case was the base logger written for? Why hadn't the original function xxLog(), whatever it was, simply been rewritten to meet that more common need?
Curiosity piqued, he pulled up the base xxLog() function in the standard library the system files were using:
/**
* Calculate a natural logarithm
*/
function xxLog(float num) {
if (num == $NA) {
return $NA;
}
return first(first(sql("select log("+string(num)+")")));
}
Logarithm, from the Greek "Logos" meaning ratio or reckoning and "Arithmos" meaning number, is a numerical operation that can be performed on a number to determine the number to which a given base (e, for a "natural logarithm") must be raised to achieve the number given as the input. It's certainly not an operation that can be performed on a string—and because the formula engine used the backing database's mathematical library to calculate the result, it would log errors in the database, probably along the lines of "Invalid input."
Which is all a roundabout way of saying: Words are hard.
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an
impressively-featured free edition, too!
|
Метки: CodeSOD |
Announcements: The Abstractions Conference: Pittsburgh |
Back when we were setting up The Daily WTF: Live, I gave a shout-out to the Pittsburgh tech community group, Code & Supply. Theyve been a great way to network with local developers, dev-opsers, designers, and more, ranging from the seasoned vets to those just cutting their teeth on IT. Im a huge fan of their events, and I only wish I could make it to more of them.
But theres one event Im not going to miss, and if you can get to Pittsburgh, you shouldnt miss it either. Code & Supply is launching their new conference, Abstractions. Abstractions, like Code & Supply, is a cross-techology, multi-skillset event, dedicated to bringing some of the best speakers in a variety of technologies together for one of the best conference lineups Ive seen.
Im just going to give you a taste of some of the big names:
Maybe that was more of a nibble than a taste, but its a great list of top-tier presenters. I am excited to see this kind of crowd coming into Pittsburgh, and Im looking forward to attending this conference- this incredibly affordable conference. This is a three day conference which costs $250, and theyll also be offering scholarships and sending out a call-for-proposals. The conference runs from August 1820, at the David L. Lawrence Convention Center in Pittsburgh, and tickets can be punchased through Abstractions.io. I will be there as an attendee (and possibly a few other members of our TDWTF staff as well) with a backpack full of buttons and stickers for site fans. If you plan to attend, drop a line to our inbox. If enough readers are in the area that weekend, well arrange a reader meetup outside of conference hours one evening.
[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/the-abstractions-conference-pittsburgh
|
Метки: Announcements |
Freelanced |
Being a freelancer is hard. Being a freelancer during the downturn after the Dot-Com bust was even harder. Jorge was in that position, scrambling from small job to small job, fighting to make ends meet, when one of his freelance clients offered him a full-time gig.
Carol, the customer, said Jorge, were really short-handed and need help. Wed like you to start on Monday. You know PHP, right?
Jorge didnt know PHP, but he knew plenty of other languages. He said yes, crash-coursed over the weekend, and was confident he could learn the rest on the job. When he showed up on Monday, Carol introduced him to Luke- who will mentor you on our application.
Hey! Luke grabbed Jorges hand, started shaking, and kept at it for far longer than comfortable. Its great to have you here, really great, youre really going to like our code, its really really great. Weve got a lot of great customers, and theyre really really happy with our great software. Do you like encryption? I built our encryption layer. Its really really great. And I hope you like getting things done, because weve got a really really great environment with no obstacles.
Jorge recovered his hand, wiped it on his pants, and tried to smile to cover the internal panic that was taking over his thought processes. That internal panic got louder and louder as Luke showed him the ropes.
They had a few dozen tiny applications, and the code for those applications lived in one place: the production server. Server, singular. There was no dev environment, there was no source control server. Their issue tracking was, When theres an issue, a customer will call you, and youll fix it. Luke explained, I like to work on it while Im on the phone with them, so I can just edit the code and have them refresh the page right there.
Jorge nearly quit, but Carol had been a great customer in the past, and he really wanted a steady gig. He ignored his gut, and instead tried to convince himself, This is an opportunity. I can help them get really up to speed.
He found an ancient Cobalt RaQ in a closet, with a 366MHz processor (with MMX!) and 64MB of RAM. Jorge hammered on that whenever he had a spare moment, setting it up as a dev environment, a CVS server and Bugzilla. This took weeks, because Jorge didnt have a lot of spare moments. Luke kept him busy on a deep dive into the code.
Jorge was largely ignorant of PHPs details and nuances, but Luke was massively ignorant. Lukes indentation was so chaotic it could double as a cryptographically secure random number generator. Wherever possible, Luke reinvented wheels. Instead of using a server-side redirect, he instead injected a
|
Метки: Feature Articles |
CodeSOD: High Performance Memory Allocation |
Jamie has a co-worker who subscribes to the malloc is slow school of thought. Now, for most programs, its fine, but Jamie works on a high-performance computing system operating in a massively parallel configuration, so there are portions of their application where that philosophy is completely valid.
In this case, however, the code Jamies co-worker wrote is in their message handling layer. Theres really no reason to pool buffers there, as the performance gain is practically non-existent based on the frequency of buffer allocation. That doesnt change Jamies co-workers opinion though- malloc is slow.
void *buf_mem;
int *big_int_buf;
double *big_double_buf;
double **double_in, **double_out;
int **int_in, **int_out;
int num_connections, max_num_in, max_num_out;
/**
* Names have been changed to protect the guilty.
*/
int reallocate_buffers( void )
{
free( buf_mem );
buf_mem = malloc( (max_num_in + max_num_out) * 64 * 10000 * num_connections );
big_int_buf = buf_mem;
big_double_buf = buf_mem;
for( int i = 0; i < num_connections; i++ )
{
int_in[i] = ((int *)buf_mem) [max_num_in * i ];
int_out[i] = ((int *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
double_in[i] = ((double *)buf_mem) [max_num_in * i ];
double_out[i] = ((double *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
long_in[i] = ((double *)buf_mem) [max_num_in * i ];
long_out[i] = ((double *)buf_mem) [max_num_in * num_connections + i * max_num_out ];
}
return 0;
}
Now, there are few treats in here. First, this buffer implementation is a header included in every C file in their code base, even files that never need a buffer. The number 10,000 is a magic number- magic in that the developer had no idea how big the buffer needed to be, and just kept throwing successively larger numbers at it until it stopped crashing.
But what makes this a pi`ece de resistance are the variables big_int_buf and big_double_buf- both of which point to the same buf_mem memory address. I hope you didnt try and use both of those variables to store different types of data at the same time, because if you did, youre going to have one heck of a time figuring out the resulting bugs. Sadly, Jamie did- and spent more time than healthy untangling strange and inexplicable bugs.
[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!
http://thedailywtf.com/articles/high-performance-memory-allocation
|
Метки: CodeSOD |
Dude, Where's My Hard Drive? |
What, again? Michael stared at the Explorer window in disbelief. The free disk space bar was glowing red, and the text underneath reported that his half-terabyte system partition had a measly few gigs left before filling up.
When it had first happened, he hadn't thought twice about it. In fact, he'd been rather glad; at least he'd had the motivation to finally discard all the games and software he would never use again. But when the disk space ran out again the next month, and again the month after, he started getting more and more worried. Was he really using that much space, or was something else going on?
Curious, he decided to finally investigate the issue. A cursory look at his hard drive with WinDirStat confirmed his suspicions. With over 80 percent of his hard drive space labelled as "unknown", something was definitely amiss. He kept searching, manually scouring through his folders and files, until finally he managed to pinpoint the culprit: an innocuously named "C:\Windows\System32\Config" folder filled with hundreds of thousands of files, taking up 420 gigabytes in size.
A quick trip to Google and a bit of playing with Process Monitor revealed the answer to the mystery. As it turned out, every modification to Windows Registry—the oft-derided database of all the Windows and Windows application settings—generated a transaction log file to ensure the data integrity, prevent corruption, and allow rollback of changes. Usually those small 512KB files weren't much of an issue. They got deleted after a clean reboot, and most software only modified the registry during installation or after a configuration change.
However, some applications and drivers—among them, Nvidia's 3D service—didn't play nice with the registry, shuffling the values around every few seconds or minutes. That, together with Michael's habit of not turning the computer off too often, resulted in cluttering the disk with more and more files until it filled up completely.
The solution, luckily, was rather simple. Michael purged the folder of all but the most recent log files, then uninstalled all the unnecessary bloatware from Nvidia, hoping it was the last thing he'd be deleting for a long while.
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an
impressively-featured free edition, too!
|
Метки: Feature Articles |
Error'd: Who Needs an Interface when you have Tape? |
"We spent a good deal of time developing our customer information display software, to make it easy for our users to update the daily menu screen outside our restaurant," Steve M. wrote, "Someone, however, noticed that the price of the Fish Steak Crunch was wrong, and decided to take a more hardware-based approach to doing the update."
"I was expecting an in depth article about the pitfalls of MongoDB, but it seems the author is still failing," writes Gary S.
"Speedtest.net's new non-flash site isn't just great, it's off the charts!" wrote Kevin C.
Wouter wrote, "If anybody needs me, I'll be entering my PIN for the next few days."
"If the formula wasn't broken before, it sure is now," writes Mike.
"Maybe this is just a clever anti-VLC ad?" writes Ben M.
Adam wrote, "Recieved this status message recently from switch monitoring software I did."
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an
impressively-featured free edition, too!
http://thedailywtf.com/articles/who-needs-an-interface-when-you-have-tape
|
Метки: Error'd |