-Поиск по дневнику

Поиск сообщений в rss_thedaily_wtf

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 06.04.2008
Записей:
Комментариев:
Написано: 0

The Daily WTF





Curious Perversions in Information Technology


Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://thedailywtf.com/.
Данный дневник сформирован из открытого RSS-источника по адресу http://syndication.thedailywtf.com/thedailywtf, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Crappy Wiring

Четверг, 07 Июля 2022 г. 09:30 + в цитатник

Ellen had just finished washing her hands when her phone buzzed. It vibrated itself off the sink, so there was a clumsy moment when it clattered to the restroom floor, and Ellen tried to pick it up with wet hands.

After retrieving it and having another round of hand washing, Ellen read the alert: the UPS was in overload.

That wasn't good. Their power supply was scaled for future growth- there was more than enough capacity to run all their servers off the UPS. So that meant something was very wrong. Ellen dashed out of the bathroom, conveniently located just off the server room, expecting to see something shorting out and sparking and an ugly cloud of smoke.

But everything was fine. Everything in the server room continued to hum along nicely. Barry, the other server room tech, had already checked the UPS management console: something was drawing 2000W above the baseline load. "Something in here must be drawing extra power," Ellen said. Barry agreed, and they went off searching.

While they searched, their phones pinged again: the UPS was no longer in overload.

"Weird," Barry said. "Do you think it's the health monitoring going off?"

"I mean, it could be," Ellen admitted. "But reporting an overload? I suppose we should open a ticket with the manufacturer."

So Ellen did that, while Barry trotted off to make his trip to the restroom. A few hours later, the UPS manufacturer sent their reply, which in short was something like: "You clearly have misconfigured it. Check this wiki article on how to set alert thresholds. Closing this ticket."

Frustrated, and full of coffee, Ellen traipsed back to the restroom to relieve herself. This time, she was halfway out the restroom door when her phone buzzed. The UPS was in overload again.

Once again, there was nothing obvious going wrong, but the management console reported that something was drawing 2000W above the normal load. "Some device in here has to be going wildly wrong," Ellen said. "Did somebody plug in a fridge, or a space heater or something?"

"I dunno," Barry said. "Do you think we're going to need to do an inventory?"

"I suppose so," Ellen said. She checked her phone. "There are a few hours left in the day, let's see if there's some device we don't expect, or something."

"Sure, but ah, gotta hit the head first," Barry said. He went to the restroom while Ellen pulled up the inventory of the server room and started walking the racks, looking for anything out of place.

That's how they spent the rest of the day, searching through the server room, trying to figure out what might be drawing a whopping 2000W of power off the UPS. There was nothing unusual or out of place, however.

Frustrated and annoyed, Ellen took one last trip through the restroom before she left for the day. And, like clockwork, she was just drying her hands on a paper towel when her phone pinged. The UPS was in overload again.

Once is chance. Twice is coincidence. Three times is a pattern. When Ellen used the bathroom, the alert went off. When Barry used it, it didn't.

Ellen looked around the bathroom. It was a spartan, functional room, without much in it. Lights. Exhaust fan. Sink. Sink. The sink used hot water. On the wall, under the sink, was a petite five liter instant-on hot water heater.

"Oh, they didn't."

The next morning, they got an electrician in. Within a few minutes, Ellen was able to confirm that they, in fact, had: they had wired the bathroom circuit to the server room UPS, not building mains. Every time Ellen washed her hands, the UPS went into overload.

The electrician was able to rewire the bathroom, which lifted that additional load off the UPS. That solved the obvious problem, and made everyone happy.

Nothing could fix the other problem, however. Ellen couldn't bring herself to shake Barry's hands anymore. Maybe he just used cold water… maybe.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/crappy-wiring


Метки:  

CodeSOD: Stuttering Strings

Среда, 06 Июля 2022 г. 09:30 + в цитатник

Mario's team had a nasty stutter in the UI of their web application. Frequently, when going back to the server for data, the UI would just hang. The requests themselves were happening asynchronously, and it wasn't just network lag anyway- the server was able to serve up large JSON responses well within any reasonable timelines. Certainly nothing in the timing justified such a nasty UI hang. So what was going on?

Well, in many of the places where they were handling JSON responses, specifically large JSON responses, this code was copy-pasted in multiple places:

// Note: Use group key as directory name to allow loadUploads to reconstruct the correct payload structure let uploadGroups = JSON.parse(JSON.stringify(payload)); for (let group of Object.keys(uploadGroups)) { Object.entries(uploadGroups[group]).map(([key, value]) => { … } }

payload, at this point, is already parsed into a JavaScript object. So this code takes an actual object, serializes it back out to a JSON string, and then parses that string one more time to turn it back into an object.

All of these choices are wrong.

Why was this being done? No one knows, not even the developer responsible. Since it's copy/pasted, it's likely someone made the mistake once, and then it just reproduced its way through the codebase.

Mario adds: "Suffice to say, most of the stutters and hanging disappeared after we just used the object."

The fact that there are other things in this code causing stutters hints at many more bad choices to be uncovered.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

https://thedailywtf.com/articles/stuttering-strings


Метки:  

CodeSOD: All the Single Objects

Вторник, 05 Июля 2022 г. 09:30 + в цитатник

I have a bit of a vendetta against the Singleton pattern. It's not to say that I won't use it, it's just that it's a pattern that gets overused and misapplied. The result is, instead of guaranteeing that only one instance of an object exists (because there can be only one), and just reinvent global variables.

Today, George sends us some code that is in a Java factory class that constructs thread pools. In this case, the thread pool itself is returned as a singleton. I've got some questions about the logic of why that's the case, but that's what it is.

And then there's this method/comment combination which is just… perfect.

/** * @return Returns true always. */ public boolean isSingleton() { return false; }

That's the funniest part of the object, by far, and the part George wanted to draw to our attention. I will add, though, that it has a unique calling convention. You see, if you just call getObject or the factory, it throws an exception. To properly construct the factory to return its singleton you must do something like this:

ThreadPoolExecutorFactoryBean tpb = new ThreadPoolExecutorFactoryBean(); tpb.setCorePoolSize(10); tpb.setKeepAliveTime(5); //a dozen more of these tpb.afterPropertiesSet(); pool = tpb.getObject();

It's like the worst possible attempt at creating a fluent API (each of the setter methods returns void). Plus, there's no way for other callers to detect if the object is initialized.

And of course, it changes our interpretation of the isSingleton method- because this very much isn't a singleton. So the method is correct, the comment is wrong, and everything about this should be thrown in the wood chipper and used to fertilize a pumpkin patch.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/all-the-single-objects


Метки:  

Classic WTF: Very, Very Well Documented

Понедельник, 04 Июля 2022 г. 09:30 + в цитатник
It's Independence Day in the US, but today, let's instead celebrate our dependence on good quality documentation. It matters. Even when we measure the size of that documentation in meters, instead of freedom units. Original -- Remy

Just about all of the systems I’ve written about here share quite a few things in common: they are poorly designed, poorly coded, and even more poorly documented. Today, I’m happy to share with you a system that doesn’t quite fit in with all the rest. It’s actually very sound software and, most of all, it’s well documented. Very, very well documented.

George Nacht is a software engineer in certain a Post-Communist European country. In the mid-1990’s, his government decided that it was time to replace their foreign, Soviet-era fighter jets with modern, less expensive aircrafts of domestic design. And since they were modernizing their fleet, they decided to modernize their pilot training as well. This meant that new, interactive flight-simulator software needed to be developed.

Instead of going with an incredibly expensive, all-encompassing defense contractor, the Air Force decided to try something new. They awarded the contract to the small game development company that George worked for. Though it was their first government contract, they were confident that they’d be able to deliver the project on time and within budget. After all, the software required was actually less advanced than the flight simulator they had developed earlier: no “high score” tables, flashy animations, or anything like that. Just the basics.

George’s contact at the Air Force was a gruff, old general with a vast knowledge of aerial warfare and forty years experience in the service. Naturally, he was very skeptical of the new guys’ ability to develop a “military grade” product.  After all, they hadn’t spent a single day in uniform. But George’s team quickly won him with a demonstration: one month after being awarded the contract, they had fully replicated the prototype plane’s specifications in their software.

In less than a year, they completed the adaptation of their flight simulator to work with the fancy training hardware. And by fancy I mean a full-sized cockpit with six display screens, sixteen force-feedback motors, and an absurd amount of buttons and controls. Everyone loved it. Pilots said it flew like the real thing and the general was thrilled to be able to experience flight (albeit, simulated) once again.

“Gentlemen,” the general started during one of their wrap-up meetings, “you have done very well. I am very impressed. There is, however, one problem. You did not provide nearly enough documentation.”

George’s boss nervously chuckled, unsure whether the general was being sarcastic or not. After all, they did deliver nearly 500 printed pages of diagrams specifications. An awkward silence ensued.

“You see gentlemen,” the general continued, “for such expensive program, we require at least eight meters of documentation.” He stretched his arms as far as he could to illustrate. Clearly, he was not joking.

George’s team had no idea how to meet this requirement, so they just started printing. Everything. Source code, screenshots, log files, hexadecimal dumps, emails, resumes. And they found out that –  even with big fonts, think paper, and double spacing – it’s pretty damn hard to fill eight meters (that’s nearly two stories, twenty-six feet, or 320-inches) with paper.

After a few weeks of printing and binding, they were finally ready to deliver the documentation. Arriving at the archive facility with a small truck, they unloaded the boxes of paper and met the general. With an approving nod and smile, he led them through a labyrinth of shelves and cabinets. They stopped at one with exactly eight meters of free space and labeled with the name of the flight simulator project. It was right between the shelves containing “Section F” of the T-72 battle tank specifications and a series of old tomes labeled List of Suitable Locations for Auxiliary Cemeteries.

They loaded box after box onto the free shelf. Without opening a single book, the general thanked them for creating such extensive documentation. Although those boxes will never be opened again, George and his team went home happy to have contributed a flight simulator for their country’s defense program.  And, of course, eight meters of documentation on it.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

https://thedailywtf.com/articles/classic-wtf-very-very-well-documented


Метки:  

Error'd: Anabelly

Пятница, 01 Июля 2022 г. 09:30 + в цитатник

Knock knock.

Matthew shared a classic catch-22 that didn't catch any, explaining "Redditstatus.com is in the middle of a Reddit outage (actually, after the outage has been "restored" and we are "monitoring the situation"). The whole point of hosting a status page separately is so that it does not share common failure mechanism with the site being monitored!"

reddit

 

And a different sort of no-win situation from Michael R. should be called a "catch-0"? As he says, "You just cannot win in this one."

pxl

 

Stephen D. "I was never too impressed with Goodreads' ability to suggest books, but I'm now wondering if I should seek out short stories that combine horror and system administration. Wait, that's the same thing!"

nevermore

 

Horror villain Slashee the Cow coincidentally obliges with a plot summary "I was afraid this external hard drive was failing, but I guess I have nothing to worry about! Shame I just ordered a replacement though."

success

 

And regular reader Pascal nails the denoument "Now I just need to find the feedback form for the feedback form."

moment

 

Fin.
[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/anabelly


Метки:  

CodeSOD: Fizzy

Четверг, 30 Июня 2022 г. 09:30 + в цитатник

Suri was about to add some new functionality to an existing application, and since it was a relatively big change, she spent a few hours tidying up the codebase. Sitting in there, in the code actually running in production, she found this:

/** * The VehicleConfigurationModel class. */ public class VehicleConfigurationModel { public static void main(String[] args) { for (int counter = 0; counter <= 20; counter++) { if(counter % 3 == 0){ System.out.print("Fizz"); } if (counter % 5 == 0){ System.out.print("Buzz"); } else { System.out.print(counter); } System.out.println(""); } } }

This is the entire class. Its main is never called, rendering this class a complete do-nothing class. But it's also got some of the other fun features of bad code: meaningless comments, misaligned braces, and then of course, the most important thing: it's wrong.

It's a FizzBuzz implementation, but as written, it would output the number on anything that's divisible by three and not five- 1 2 Fizz3 4….

Clearly, someone was trying to learn something by writing this code. But, as Suri points out: "Maybe something was learned, but maybe there's a few more lessons left here."

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/fizzy


Метки:  

CodeSOD: If You Switch

Среда, 29 Июня 2022 г. 09:30 + в цитатник

Switches are great. Given a value, you can switch to different code paths based on that value. The problem is… what if you have other conditions too?

Well, Hubert's co-worker found a way around that. Here's a heavily anonymized version of the pattern.

switch(someValue) { case A: if (boolX) { case B: doStuff(); } else if (boolB) { case C: doOtherStuff(); } else { doYetMoreStuff(); } break; case D: // blah, blah }

In C++, and probably several similar languages, this compiles. Whether it should or not is irrelevant, it does. Our syntax highlighter doesn't like it, though. The truth-table for this particular statement is… odd. I whipped up a little playground for you to try it out, yourselves, but here's a quick summary:

Branch 0: A,1,1, doStuff() Branch 0: A,1,0, doStuff() Branch 1: A,0,1, doOtherStuff() Branch 2: A,0,0, doYetMoreStuff() Branch 0: B,1,1, doStuff() Branch 0: B,1,0, doStuff() Branch 0: B,0,1, doStuff() Branch 0: B,0,0, doStuff() Branch 1: C,1,1, doOtherStuff() Branch 1: C,1,0, doOtherStuff() Branch 1: C,0,1, doOtherStuff() Branch 1: C,0,0, doOtherStuff()

Seeing it printed out makes it easier to understand what this code is doing. Case A can sometimes go down any possible branch. Cases B and C only behave like traditional switch statements. Even without the heavy anonymization, though, this would be hard to follow.

Hubert found this in existing production code during a code review. Discussion were had about the whys and wherefores.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/if-you-switch


Метки:  

CodeSOD: By Template

Вторник, 28 Июня 2022 г. 09:30 + в цитатник

Kimberly L sends us an example of what is clearly template-generated code, so I think this is an opportunity to go on a rant.

Now, the important thing to note here is that this code was in a packaged library that they were considering using.

if ("development" !== 'production') { deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: 'adjacency'}', 'graph/sankey'); } option.emphasis.focus = 'adjacency';

Clearly, the two terms are never going to be equal. But just as clearly, no human wrote this code- at least I hope not. Someplace on the server side, in some language or another, there's something like:

let env = "development"; let template = `if ("${env}" !== 'production') { … }`; println(template);

Now, that this got released as a library and isn't just some server-side rendered JavaScript is absolutely the big WTF. But generating JavaScript via templates, this way is a bigger WTF that we usually give it credit for. I'm annoyed by this, so let's talk about how to do templates-generated executable code well and how developers frequently mess it up.

One of the core things we need to think about in terms of designing software modules are the interfaces which connect them. This is true whether we're talking object oriented design or functional design. A code interface is like a user interface, and should specify the knobs and buttons we can push to accomplish things. Broadly speaking, we could think of our interface as the listing of expected inputs, expected outputs, and potential side effects.

Now, someplace in their templating engine, they might have that definition. "These variables exist for use by the template," may be defined on the server side. So people writing templates know they can use ${env} in those templates.

That much is fine, honestly. Okay, not fine, but we'll come back to why it's not fine in a moment. But assuming we're template-generating code, there are two problems with spamming variables around the template.

First, it makes the template potentially harder to read. The content of the template is now a mixture of two layers of our application: the server side variables and the client-side code we're generating. (This applies to any code generation system, not just code generation for client-side code, but that's the example we're looking at.)

The second is that the output artifact- the generated code- is frequently stuffed with nonsense like if ("development" !== 'production'). The artifact is not readable or easy to understand, because the connection to the inputs is not readable or easy to understand.

So, with that said, I want to suggest an easy fix to generating code via a template. This is a minimal effort thing that will mean we'll never see ugly, confusing template-generated code ever again. If you're using templates to generate code, use this one weird trick: variables.

let env = "development"; let template = ` //inputs let activeEnv = "${env}"; //body if (activeEnv !== 'production') {…} `; println(template);

This gives us an interface. We have a clear definition of what the inputs to this module are (populated via a template), and we have a clear picture of which part is the behavior. Plus, the output artifact is easy to understand- we understand that activeEnv is populated or generated elsewhere, and what the role of the variable is in the name, and all of that. It's significantly better.

If you're template-generating code, please do this. It's easy, it's cheap, and it makes the output more readable, but it also makes the template more readable.

And once you're looking at all these templates with clearly defined inputs and clearly defined outputs, you can move on to the next step: stop using templates to generate code. You now have a clear sense of what the interface to this code should be, so build an actual interface where you can call this code as a module, passing parameters as appropriate.

Because, honestly, executable code should not be generated by templates. Oh, yes, there are literal C++ templates, or macro systems, which technically do that, but these systems generally aren't operating on data as stringly typed. I'm talking about specifically template engines, a thing I see too damn much of.

Look, I understand, sometimes it's faster and easier to just populate a template with variables and then execute the code. I've done it myself. I've done it with OpenGL Shaders, even, which have a clear and well defined specification for how you should populate their variables from outside the shader program itself (spoilers: template generation is not the right tool).

But while it's a fine quick-and-dirty hack to get something done, I'm going to make the controversial statement that *any template expansion to generate code is a code-smell, and a sign that you've gone down a bad path and need to refactor this at some point.

In any case, this is my rant about template generated code. Sometimes they make a WTF. Sometimes I see just one too many examples and I have my own, extreme, WTF reaction.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/by-template


Метки:  

The Next Version

Понедельник, 27 Июня 2022 г. 09:30 + в цитатник

Frequent contributor Argle (previous) is mildly famous, and not just around here. He writes:

Someone once remarked that they were jealous that I had two Wikipedia articles written about projects I created. This is about one of them.

This particular product started its life on Windows 3.11, and entered the market in an extended beta which ran for three years. Even in its pre-release state, it counted as a hit. Pre-release sales paid the bills. Computing magazines (actual printed paper magazines you had to subscribe to or buy in the book store) named it one of the best Windows programs of all times. Everyone from tech-celebrities to notorious pornographers sung their praises of this application.

Since things were going well, Argle went and constructed an API for the application which let other developers write addons, making it even more useful. Sales continued, and Argle and his business partner lived well.

And that's when Windows 95 came out. Now, Windows 95 opened up a lot of opportunities, in terms of what OS features the application could potentially leverage, but that would require a substantial effort. By this time, they had been in beta for three years, so Argle and his partner officially launched their version one release, with a big splash and fanfare. And then they quietly started work on version 2.

After the release of version 1, all those trade magazines came back, wanting to know the answer to the big question: "what's next?" As Argle's business partner was the face of the team, he was going to do a round of interviews.

"But," he asked, "what do I tell people about what's coming next?"

Argle wasn't sure, but knew what the wrong answer was: "Whatever you do, don't tell them that we're working on version 2."

"But what do I tell them?"

Argle thought about that question. "There's the addon API. Tell them that we're working on an addon package for retail."

So business partner went off to do the circuit of interviews, and Argle went off to program version 2, quietly. A few days later, they checked in.

"How'd the interviews go?" Argle asked.

"Um, good. They went good."

A few weeks later Argle saw how well they went, when every trade magazine was running headlines announcing that V2 was coming any day now.

It had been the one question everyone had: "When is version 2, and what is going to be in it?" The business partner had tried to dodge the question and hide behind the addon pack, but also had the willpower of a victim of Willy Wonka's factory. He caved in about six seconds and started sharing information about what the plans for V2 were.

There was no putting the toothpaste back in that tube. Sales dropped off a cliff, because nobody wanted to buy a product that was going to expire sometime soon. The money dried up faster than it had come in. Argle and his partner had a gigantic fight, Argle walked away from the company and that was that. Version 2 never happened, and the company vanished into the dustbin of early personal computing.

Argle writes: "It was a good run while it lasted."

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/the-next-version


Метки:  

Error'd: Anno Domini

Пятница, 24 Июня 2022 г. 09:30 + в цитатник

Buffalo, New York is a recovering Rust Belt city which has given the world several notable achievements. First, a fairly forgettable sliced meat sandwich au jus more known for its barely edible stale roll than for the entirely unremarkable beef entombed within. Second, an innovative repurposing of a castoff fowl appendage into a drunkard's delicacy (and Mlle Simpson's famed befuddlement). Most of all, it's indispensable for the construction of a lighthearted linguistic shibboleth: Buffalo buffalo buffalo buffalo... and so on. Unfortunately, the city also brings us bad news this week.

But first, Tony H. reminds us of a famously scandal-ridden bank. Theirs might not have been the worst fraud in 2016 (or 2017, or 2018, or 2019) but apparently they're now tightening down the screws on consumer lending. Tony observes, frostily, "a credit card with a limit below zero is alarming even for Wells Fargo."

limit

 

Sleepless David Green puns breathlessly "My Philips CPAP machine was recalled and I am waiting for a replacement machine. I'm concerned about the possible harm my existing machine could do, and I'm hoping that the new machine is better, but if it's anything like their string formatting for reference numbers, I'm not exactly inspired with confidence." Nyuk.

ppap

 

Job-hunter Pawel serves up a short cup. "I've heard there have been staffing shortages recently, but didn't realize the bar would be so low!" Nivel, for los analfabetos, means degree in this argot.

nivel

 

An anonymous HBO Max viewer surnamed B. reached out for help, asking "This is my second time watching this film and I still don't know what happened to Peter and Vera." I'm sorry, Mx. B. I read the book, and I couldn't figure it out either. (we probably should have a special column just for the "bad online shopping data" since there's So. Damned. Much of it. And it's kind of a special case of WTFery that doesn't quite rise to the level of endless NaNs.)

vera

 

And finally, Buffalonian (it's a word!) Chris N. previews our column of bad online journalism data and our column of troubled timestamps with this ripped straight from the breaking news: "Trusted since year 40 -- is that AD or BC? Better ask Meredith." ISO 8601 OR ELSE!

xxxx

 

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/anno-domini


Метки:  

Submit Your Vacation

Четверг, 23 Июня 2022 г. 09:30 + в цитатник

"We have an internal website that shows, among other things, the daily availability of my coworkers for the next three months to help with scheduling, especially when planning vacations," writes Alexander.

"This vacation planner data is represented as a table. An image of a table to be more precise."

Displaying data as images is already a WTF. It's certainly not user friendly, it's definitely not accessible, and it makes one wonder whyyyy. That, however, is the least of the WTFs Alexander has in store for us.

First, the front-end sent its HTTP requests to a single end-point. Every request went to the same URL. When the user clicked the button to show the vacation planner, the browser would submit a form- yes a form, creating a body which looked like:

-----WebKitFormBoundary9lVf1utJmbYdQuZm Content-Disposition: form-data; name="mode" vacationplannerimage ------WebKitFormBoundary9lVf1utJmbYdQuZm Content-Disposition: form-data; name="imgpath" images/vacationplanner/July 1 2022.jpg ------WebKitFormBoundary9lVf1utJmbYdQuZm--

"Why," you might ask, "couldn't they just use an tag pointing at the correct URL?" Then you remember what site you're reading this on, and realize there isn't a good answer to that question.

So, what does the API endpoint do with that request? It feeds it through a gigantic C# switch:

switch (mode) { case "dosomething": Response.Write(DoSomething()); break; case "dosomethingdifferent": Response.Write(DoSomethingDifferent()); break; // ...more cases case "vacationplannerimage": Response.Write(VacationPlannerImage()); break; // ...even more cases but no default case }

Note the comment: there's no default case. So if a client sends an invalid request, we get back an empty response, not an error. So that's fun, and definitely not a recipe for future confusion. Especially because there's no documentation for what mode flags are valid- the only way to know is to read the gigantic switch block.

So how does the VacationPlannerImage get fetched?

public string VacationPlannerImage() { string file = Server.MapPath(Request.Form["imgpath"]); try { if (File.Exists(file)) return $"{{\"isok\": true, \"message\": \"ok\", \"data\": {{\"idx\":{Request.Form["arridx"]}, \"img\":\"data:image/jpeg;charset=utf-8;base64,{Convert.ToBase64String(File.ReadAllBytes(file), Base64FormattingOptions.None)}\"}}}}"; else return $"{{\"isok\": false, \"message\": \"No data to display!\"}}"; } catch (Exception ex) { return $"{{\"isok\": false, \"message\": \"{ex.Message}\"}}"; } }

Ahh, now that's the stuff. Hand-crafted, artisinal JSON through string interpolation. The image served up as a field in the response, encoded in Base64, wrapped up in status fields which are handily re-inventing things that HTTP just already does for free.

Or, to let Alexander sum up:

Instead of a GET to an image URL, maybe handling security stuff in the server and returning an image this project takes a detour around every imaginable web standard to do its thing.

And this isn't some ancient, legacy project- the first commit to the project was in 2016.

Alexander closes:

Feel free to reach out if you have any questions or comforting words.

I have a lot of questions, but I don't think there are any good answers. As for comforting words, I don't think there are any that are sufficient.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/submit-your-vacation


Метки:  

CodeSOD: Heading On Out

Среда, 22 Июня 2022 г. 09:30 + в цитатник

Madeline inherited some Python 2.7 code, with an eye towards upgrading it to a more modern Python version. This code generates CSV files, and it's opted to do this by cramming everything into a 2D array in memory and then dumping the array out with some join operations, and that's the real WTF, because that's a guaranteed way to generate invalid CSV files. Like so many things, the CSV files are actually way more complicated than people think.

But we're going to focus in on a smaller subset of this pile of WTFs. I'll lead with the caveat from Madeline: "I've changed some of the variable names around, for a bit of anonymity, but couldn't get variable names quite as terrible as the original ones."

columns = [] headColumns = "Record ID, Record Category, CITY,Restrictions,UNIQUE_GENERATED_ID".split( "," ) for currentColumn in headColumns: columns.append(currentColumn)

This code tracks the column names as a comma separated string. It splits the string into a list. Then it iterates across that list and appends each item into… a list. headColumns is never referenced again.

This could have just been… a list of column names. No splits. No appends. Just… have a list of column names.

That's annoying, but then there's all the hinted at details here. The column names will all contain an abritrary number of spaces. There's a mix of conventions- spaces and underscores in names, Title Case and ALL CAPS. Two columns, "Record ID" and "UNIQUE_GENERATED_ID" both suggest that they're unique identifiers. Madeline says that the CSV file ends up containing three different identifier columns, and says "I think that's likely due to an improperly designed database schema.

Yes, I suspect Madeline is right about that.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

https://thedailywtf.com/articles/heading-on-out


Метки:  

CodeSOD: Show Thumbnails?

Вторник, 21 Июня 2022 г. 09:30 + в цитатник

Christopher Walker continues to struggle against ancient PHP applications in the automotive industry. With the point system behind him, there was a whole pile of internal applications for handling information about laws, misconceptions about the law, and other driver services.

One, a home-grown CMS, was useful for publishing blog-style content about changes in the law. There was just one problem: if a post was published without a thumbnail, attempts to view that post failed with an error. It wasn't hard to find the offending line.

class="col-12{{ $show_image == 1 ? ' col-md-8' : '' }}">

This was actually a pretty simple mistake. The code assumed that $show_image was set, and that if there was a thumbnail, the value was 1. If there wasn't, it was 0, or false, or an empty string, or some other value. Types didn't really matter, if it was set.

The problem was, if there was no thumbnail, it wasn't set. And that caused the error. The fix was simple: use a null-coalescing operator. Christopher submitted this pull request:

class="col-12{{ $show_image ?? false == 1 ? ' col-md-8' : '' }}">

This isn't the ideal solution. But despite putting forward a good effort, Christopher couldn't figure out where $show_image was actually getting initialized in the code- it was just that much of a mess behind the scenes. But this fixed the crash bug, and at least pointed towards the kind of refactoring that would be needed for a more permanent fix. Ideally they'd abandon the whole 0/1 thing and just use boolean values in the first place.

So it's not great, but it's acceptable given the constraints.

Well, almost acceptable. The problem arises a few weeks later, because while the error went away, a display isssue cropped up. As it turns out, the maintainer of this particular internal project rejected Christopher's pull request. They did, however, see the need and implemented their own version. No, they didn't go and track down the root cause of the problem and try and fix it, they just did the same thing as Christopher… but wrong.

class="col-12{{ $show_image ?? 1 == 1 ? ' col-md-8' : '' }}">

This code continues to work fine if there is a thumbnail set, but if there isn't, it will still reserve the space for a thumbnail. That's because this code does the opposite of what it's supposed to, which is treat an unset $show_image as false.

It's impressive to see the working solution mutate into a non-working one so quickly.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/show-thumbnails


Метки:  

CodeSOD: Spellchucker

Понедельник, 20 Июня 2022 г. 09:30 + в цитатник

There's an old saying in programming: you don't have to spell correctly, you only have to spell consistently. As long as you mispell everything the same way, your language will understand your code. However, most editors and IDEs have spell-check integration, though, because it's hard to get everyone on a team to spell things wrong consistently.

Unless, of course, you know just implement some bonus methods, like John's co-worker. This was frequently spammed in the Java codebase:

public String toStrign() { return super.toString(); }

Don't strign us along.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/spellchucker


Метки:  

CodeSOD: Classic WTF: Pure Eval

Пятница, 17 Июня 2022 г. 09:30 + в цитатник
We close out our week with something evil. Someting… eval. Original. --Remy

When Jeff saw a line like this one, he knew there was something terribly wrong in the code he had inherited.

eval(Application("buildCommon").toString());

He wasn't sure what was more troubling- the way the Application variable was being used, or the fact that C#, as a compiled language, doesn't have an eval statement.

A brief trip to the Googles informed him that yes, some people did in fact wrap eval around the compiler. There were a depressing number of samples demonstrating how it could be done. Someplace, buried in his codebase, there was a function much like that.

Which was bad, but what was worse was how every other function in the application was built and maintained. By storing all of their class definitions as strings and compiling them at runtime, they could have an application that was more "flexible".


Application("commonFunctions") =
    openConnObj.toString() + "\xFF" +
    /***snip about 100 functions***/
    closeConnObj.toString();

Application("buildCommon") =
    "if (typeof(openConnObj) == 'undefined') {"+ "a = Application('commonFunctions').split('\xff');"+
    "for (var nCnt = 0;nCnt < a.length;nCnt++)eval(a[nCnt]);};"; 

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/classic-wtf-pure-eval


Метки:  

Classic WTF: GHOST Busted

Четверг, 16 Июня 2022 г. 09:30 + в цитатник
We're wrapping up our vacation week with a look at something really scary. A GHOST. A spooky GHOST, not the Swedish metal band, which isn't really spooky. Original. --Remy

Some developers look at a problem and say, “Let’s solve it. With code!” Then there are other developers, who say, “This specific problem is a subset of a general class of problem, which, if we solve the general class, will automatically solve the specific class.” The best programmers know when it’s time to keep it simple, and when they really should shoot for the stars.

Chris worked for a startup run by former academics. They wanted to shoot for the stars, some black holes, and maybe, if there was budget left over, the primordial galaxies that formed after the Big Bang. They had an idea for a product which would… well, Chris had no idea what it did.

The vision was codenamed SPRIT. Walter, the wizard behind it, couldn’t explain its purpose in terms anyone else understood. The only thing he could explain was that SPIRIT needed to be implemented in the in-house language, GHOST. “It’s a joke,” Walter explained once, “It stands for ‘Generic Hybrid Script for Transactional Objects’. The acronym is out of order because GHOST is all about parallel processing. It’s funny.”

GHOST wasn’t terribly funny to use. It terrified Chris. The syntax loved short-hand and unusual special characters, which made it read like the demon offspring of MUMPS and APL. Worse, it wasn’t truly a language in its own right- it compiled down into C#. The generated C# code read like Franz Kafka on LSD, and depended on syntax conventions which had been deprecated in 2003, meaning it depended on .NET 1.1.

The language was cluttered with all sorts of things it didn’t need. To demonstrate its “expressive power”, Walter built syntax primitives to do non-primitive things. With a single line of code, you could generate 500 users and add them to the domain, or scan the network for every printer or network drive and map it to the local machine. There was a built-in method named “NPR”, which calculated the nth prime using a brute force (but highly parallelized) algorithm.

GHOST was Walter’s pride and joy. The fact that only the generated C# was debuggable, and not GHOST itself, or that the advanced “transactional primitives” rarely worked did nothing to dull his pride. Like a proud father, Walter wanted every chance to show off his offspring.

The first chance was an upcoming trade show. Walter pulled out all of the stops, bought the best booth their budget allowed, and booked travel for the entire team. The lack of a demo-ready product meant nothing to him. “We’ll just have to go into crunch mode!” Walter led by example and took a week’s vacation.

This left Chris, and his allies Peter and Ray, to slave away late each night. The night before the trade show, they worked in silence. The lights were dimmed, the floor was littered with yesterday’s pizza boxes and tonight’s Chinese take-out. Chris wrestled with his GHOST, trying to get the system to do whatever it was it was supposed to do. He had some tests as his guide, even if he didn’t know what they meant. Peter and Ray scrambled to prepare the other booth materials and printouts.

Shortly before midnight, Chris found his triumph. The inputs he in the spec generated the outputs they were supposed to. Peter and Ray were still scrambling- the main printer had just died, and in a rush, they hooked up a dusty, ancient replacement. Everything seemed fine, until the clock struck midnight.

Something happened, someplace between the hardware, the operating system, and the GHOST software. Ray’s print job finished, and a new one started. Page after page of the arcane, eldritch code of the system spewed forth. GHOSTly code danced across the pages like the gibberings of a mad-man. It was only Chris’s quick thinking that saved their sanity- he tore the printer’s power cable from the wall.

No one knew why it happened. No one wanted to know. Maybe it was the printer, or perhaps it was something stuck in the print queue. Maybe one of them triggered some unknown feature in the application. Maybe… maybe it was the GHOST in the machine. They swore to never discuss it, and agreed to run off the last few print jobs at Kinko’s the next day, and went home for the night.

The first day of the trade show was a mild disaster. Their booth was tucked away in a remote corner, between the trash bins and one of those pushy training companies that promised to turn novices into veteran programmers in six weeks, “Or your money back!” When anyone wandered past, Walter did his best to rope them in, and demo SPIRIT and discuss the power of GHOST. Each demo triggered bugs and crashes, but since no one actually understood the application, only Walter noticed the issues.

They stayed through the day, into the opening night party. The free drinks ran out at 11PM, and so everyone wandered out into the streets of the city, looking for nightlife. This meant only security and the cleanup crew were there at midnight…

The second day opened as a scene of bedlam
. Several acres of forest had been converted into the cracked scrawl of GHOST code. Each and every vendor with a poorly-secured printer on the network (all of them) had been taken over by GHOST. Most ran out of paper early in the evening, although with that many print jobs hitting the network, a number of them were only just starting on their insane quest to print the entirety of SPIRIT’s GHOST code.

Chris pulled the demo machine off the network, which crushed Walter. “Now I can’t demonstrate the great networking features of GHOST!” They never found the underlying cause. Like most hauntings, in cropped up at midnight for a few weeks, then slowly drifted away into a bad memory. SPIRIT never found a market, and when the company folded, they gave up the GHOST.

Chris thought that was the end of the story, until he went to clean out his attic. He found an old, unmarked box. Inside were reams of paper, completely covered with GHOSTs.

Ghost image by Lionel Allorge (Own work) GFDL, CC-BY-SA–3.0 or FAL, via Wikimedia Commons

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/classic-wtf-ghost-busted


Метки:  

Classic WTF: Back That Thang Up

Среда, 15 Июня 2022 г. 09:30 + в цитатник
We're still away for our summer break, skimming our inbox and horrified by all the things you're sending us. Keep doing it. Speaking of horrors, this one's about backups. You know what's about to happen… Original. -- Remy

It ain't easy being number one, especially for R.B.'s company. With €730 million in annual revenues, they're the leader in a relatively small (€1.6 billion) niche market and are constantly struggling to maintain their dominance amongst a handful of vicious competitors. Recently, an executive at the company came up with an astonishingly brilliant plan that would ensure that they stayed on top for many years to come. This plan was named The Convergence.

The Convergence was, in all seriousness, a really good idea. It represented a completely new way of doing business that relied heavily on technology and its ability to integrate the supply chain with the customer experience. It would do nothing short of revolutionizing their entire industry, leaving their competitors struggling just to stay afloat.

Being that it was such a large idea, The Convergence would take a lot of time and money to implement. Just about all departments -- from sales to customer service -- would need to dedicate resources to complete the project. The I.T. budget alone was €2.3 million, which was at least five times larger than any project before it. To make sure that the I.T. portion of the project went smoothly, an Expert Project Manager was brought in.

To the Expert Project Manager, a €2.3 million project was nothing. Chump change. Small potatoes. Nickels and dimes. Chicken feed. Compared to his portfolio, this "tiny little project" would be a cinch to run out.

The first thing the Expert Project Manager requested was Expert Team Collaboration Software. His request was denied: the software was expensive and required dedicated hardware to run. He was, however, authorized to set up a demonstration of it so that others could "experiment on it and see how it works." And that he did: a development server was recommissioned and the Expert Team Collaboration Software was installed.

Time went by and the Expert Project Manager started to use the Expert Team Collaboration Software for a bit more than demo purposes. Agendas, meeting notes, requirements, etc. all started to find a home in the collaboration software and, before everyone realized it, they had all transitioned to using the Expert Team Collaboration Software for everything related to the project.

This was all despite R.B.'s vehement objections. Keep in mind that the setup was on a temporary development server with no security, no backups, and no support from Network Operations. As with some of the other developers, R.B. was shuffled aside and even criticized for being uncooperative. After a while, R.B just gave up and went with the flow.

Fast forward a year and a half and The Convergence plan is getting closer and closer to being implemented. As part of the project, a Terminal Server needed to be setup for development and testing purposes. Over the weekend, the folks in Network Operations recommissioned an unused development server, wiped it clean, and configured a new set up.

The following Monday morning, a business analyst working on The Convergence couldn't find the document she was working on in the Expert Team Collaboration Software. In fact, not only was her document missing, but so were the initial charters, plans, budgets, request for proposals, test scripts, requirements, etc. She asked a developer to help her find out why ...

Developer: What happened to all of our data on the Expert Team Collaboration Software server?
Network Operations Administrator: No idea. Why do you ask, and what is an "Expert Team Collaboration Software Server"?
Dev: Umm ... it was the server we have all the documents for The Convergence on.
Admin: ... the file share? That's up and running just --
Dev: No, no -- the Expert Team Collaboration Software Server, DEVT09 I think.
Admin: Oh that server? We wiped that for the Terminal Server you guys requested.
Dev: ... we need it back ... can you restore it from backup?
Admin: No -- we don't back up your Dev Temp Servers.

The developer reported this in the morning project meeting. The Expert Project Manager didn't find the joke too funny, as the Expert Team Collaboration Software housed over a years worth of work from 28 different people. When it was explained to him that it wasn't a joke, the Expert Project Manager excused himself and headed in the direction of the restrooms. No one has seen him since.

But of course, the real fun came when someone had to sit in for the Expert Project Manager at the Board of Directors status meeting and explain all this. It turns out that the bigwigs weren't too understanding about The Convergence being delayed for a year ... or even about being asked if they saved any hard copies of the project documentation.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/classic-wtf-back-that-thang-up


Метки:  

Classic WTF: The Source Control Shingle

Вторник, 14 Июня 2022 г. 09:30 + в цитатник
It's still a short summer break for a few more days, as always, keep those submissions filling our inbox while we're away. In the meantime, we're also into peak homebuying season. A friend of mine needed a new roof as part of her purchase. Roofs are important, as they provide vital protection for your structure. Unless that structure is your source code… Original. --Remy

The year was 1999 and the dot-com boom was going full-throttle. Companies everywhere were focused on building revolutionary applications using nothing but top-shelf hardware and state-of-the-art software tools. Developers everywhere were trying to figure out if they should play more foosball, more air hockey, or sit back down on their Aeron and write more code. Everywhere, that is, except Boise, Idaho. Or at least, Dave's small corner of it.

At Dave's company, developers worked at a solid pace, using reliable tools, for a stable industry. They were sub-sub-contractors on a giant project commissioned by the U.S. Navy to condense naval vessel documentation. Generally speaking, the complete documentation required for a modern warship-from the GPS calibration instructions to the giant 130-millimeter cannon repair guide-is measured in tons. By condensing the documentation into the electronic equivalent, they could not only save tremendous physical space, but they could make it much easier to navigate.

 

A Simple Plan

Dave's company's small piece of the pie involved writing a very specific application for a particular group of users. Their application needed to track who moved which box of classified documentation from where to where, and why. Given the very simple requirements, the entire application was assigned to Mark.

Mark believed in keeping things simple: he rarely left the command line, his text editor was notepad and his source repository was a few backup folders on a network drive. He didn't need or want more than that. It was a simple task that called for his simple methodologies.

As their app neared completion, a whole new set of requirements came in. Now, they had to add in security and logging. When Dave joined Mark's one-man team to help out with this, the current system of source control -- nothing -- became inconvenient for collaborating.

Dave suggested they set up a source-control repository, but Mark wanted to keep things simple. He devised a solution called the "source-control shingle."

 

Roofing and Revisions

The source-control shingle was literally that: an actual shingle from someone's house that somehow ended up in their office. It acted like a "talking stick," in that only he who possessed the shingle was allowed to edit the common libraries.

As time went on, the project's scope grew immensely. More and more developers came on board, and the source-control shingle was pushed to its limits. Despite not being in possession of the shingle, some developers broke protocol and edited the library files on the share drive. Finally, Mark agreed to use a simple source repository. He wanted to use the only source-control system that guaranteed file locks: Visual Source Safe.

Unfortunately, Source Safe was so painful to license and manage that Mark had no choice but to explore other options, some of which involved a piece of painted wood. After much arguing and cajoling, Mark agreed to try out open source CVS. Things went well for the first few days, but quickly took a turn for the worse.

"What happened to my code?" Mark asked. "I just did a CVS UPDATE and everything I wrote this morning is gone!"

"It's working fine for me," one of the developers replied.

"Same here," another joined in. "I just checked in my changes a few minutes ago, and they're still here."

"Wait," a third one questioned, "did you do an UPDATE before the COMMIT?"

"Did I what?" the second developer replied. "Oh. Crap."

Exasperated, Mark jumped. "That's it! We're going back to the shingle!"

Fortunately, some of the other developers managed to convince Mark to stick with CVS, at least for a little while longer. One of the developers even managed to enforce better source control practices using some server-side scripts. And despite Mark's constant reservations, they ended up staying with CVS throughout the project. But the whole while, Mark kept the shingle handy, just in case.


The Source Control Shingle was originally published in Alex's DevDisasters column in the April 15, 2008 issue of Redmond Developer News. RDN is a free magazine for influential readers and provides insight into Microsoft's plans, and news on the latest happenings and products in the Windows development marketplace.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/classic-wtf-the-source-control-shingle-2


Метки:  

Classic WTF: DATABASE ABNORMALIZATION 101

Понедельник, 13 Июня 2022 г. 09:30 + в цитатник

Метки:  

Error'd: Meat!

Пятница, 10 Июня 2022 г. 09:30 + в цитатник

I remember when gasoline was under a dollar a gallon in the US! And penny candy was only a penny! And a pound sterling could buy you a decent dinner, not just a few ounces of meat product! And the euro! Let me tell you about the euro!!
I mean, um. Yeah. Things have changed, and it seems lately all our consumer goods and services have become suddenly more expensive, or smaller, or inferior in some other way. Have you priced airplane flights, even in middle seats with no luggage or food?
The lead submission this week isn't really a software Error'd. It's not even a wacky product offering from Amazon. But despite what seems an unconscionable price, the manufacturer has discovered a revolutionary method to deliver extra value by (apparently) literally altering the properties of the universe.
Ladies and gentlemen, I give you... MEAT!

Finally free from those awful EU restrictions, Michael R. now has access to 85% over-clocked pork sausages. "Not bad to get 185g meat out of 100g product.", he grunts gluttonously. "I will take 2."

meat

 

Mac user (maybe? Correct me if I'm wrong) Lily might need some of that over-clocked sausage sustenance while trying to make something like full use of her Core i5 heater. "I've never realized my 4 core CPU has such performance! Thank you, Intel!" It really makes you wonder why Apple bothered with new chips at all.

cpu

 

Jonathan Holmes , on the other hand, needs some over-clocked memory. Even in these inflated days, a half-terabyte of RAM is a considerable investment. "To be fair to Samsung, I can rent a 512GB Amazon instance for under $5 an hour if I want to backup my mobile..." Gramps here recalls a product called "RAM Doubler" that might help a bit, especially if you could exploit some of Lily's massive CPU for some really fancy compression algorithms.

samsung

 

Peter C. highlights a pernicious variant on inflation that the mass media are now calling "shrinkflation". If you don't want to raise prices, just reduce your product quantity instead. Seems like FedEx's web supplier has been selling them a bunch of diminished text boxes. "I thought this form gave me 120 characters to work with, but then it cut me off after 35," he raged. "You can hardly say BOO in only 35 characters!!11!"

35

 

In another reminiscence on bygone days, unrelated to inflation, Unsightly P. regales us with a heroic tale. "I was thrilled to log in to my plural sight account, and see a real live NaN! Such sightings were common when the web was young, but civilization has largely relegated them to forgotten myths. The search is on though, for NaN's older brother, the great (K?)null." Ah, me, Mr. P. I assure you the mythical NaN is anything but. We here at Error'd see scores of NaNs with every mailbag. It's only the shocking ubiquity of their existence that discourages more than a fortnightly feature. Next week, perhaps, we'll see a Pnull.

nan

 

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/meat


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 119 118 [117] 116 115 ..
.. 1 Календарь