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

Поиск сообщений в 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 ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

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

Representative Line: A Test Configuration

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

Tyler Zale's organization is a automation success story of configuration-as-code. Any infrastructure change is scripted, those scripts are tested, and deployments happen at the push of a button.

They'd been running so smoothly that Tyler was shocked when his latest automated pull request for changes to their HAProxy load balancer config triggered a stack of errors long enough to circle the moon and back.

The offending line in the test:

assert File(check_lbconfig).exists and File(check_lbconfig).size == 2884

check_lbconfig points to their load balancer config. Their test asserts that the file exists… and that it's exactly 2884 bytes long. Which, of course, raises its own question: if this worked for years, how on Earth was the file size never changing? I'll let Tyler explain:

To make matters worse, the file being checked is one of the test files, not the actual haproxy config being changed.

As it turns out, at least when it comes to the load balancer, they've never actually tested the live config script. In fact, Tyler is the one who broke their tests by actually changing the test config file and making his own assertions about what it should do.

It was a lot more changes before the tests actually became useful.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

https://thedailywtf.com/articles/a-test-configuration


Метки:  

CodeSOD: A/F Testing

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

A/B testing is a strange beast, to me. I understand the motivations, but to me, it smacks of "I don't know what the requirements should be, so I'll just randomly show users different versions of my software until something 'sticks'". Still, it's a standard practice in modern UI design.

What isn't standard is this little blob of code sent to us anonymously. It was found in a bit of code responsible for A/B testing.

    var getModalGreen = function() {
      d = Math.random() * 100;
      if ((d -= 99.5) < 0) return 1;
      return 2;
    };

You might suspect that this code controls the color of a modal dialog on the page. You'd be wrong. It controls which state of the A/B test this run should use, which has nothing to do with the color green or modal dialogs. Perhaps it started that way, but it isn't used that way. Documentation in code can quickly become outdated as the code changes, and this apparently extends to self documenting code.

The key logic of this is that 0.5% of the time, we want to go down the 2 path. You or I might do a check like Math.random() < 0.005. Perhaps, for "clarity" we might multiply the values by 100, maybe. What we wouldn't do is subtract 99.5. What we definitely wouldn't do is subtract using the assignment operator.

You'll note that d isn't declared with a var or let keyword. JavaScript doesn't particularly care, but it does mean that if the containing scope declared a d variable, this would be touching that variable.

In fact, there did just so happen to be a global variable d, and many functions dropped values there, for no reason.

This A/B test gets a solid D-.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

https://thedailywtf.com/articles/a-f-testing


Метки:  

Error'd: I Beg Your Entschuldigung?

Пятница, 01 Июня 2018 г. 13:30 + в цитатник

"Delta does not seem to be so sure of what language to address me in," writes Pat.

 

"I'm wondering if the person writing the release notes made that typo when their mind was...ahem...somewhere else?" writes Pieter V.

 

Brad W. wrote, "For having "Caterpillar," "Revolver," and "Steel Toe" in the description the shoe seems a bit wimpy...maybe the wearer is expected to have an actual steel toe?"

 

"Tomato...tomahto...potato...potahto...GDPR...GPRD...all the same thing. Right?" writes Paul K.

 

"Apparently installing Ubuntu 18.04 on your laptop comes with free increase of battery capacity by almost 40x! Now that's what I call FREE software!" Jordan D. wrote.

 

Ian O. writes, "I don't know why Putin cares about the NE-2 Democratic primary, but I'm sure he added those eight extra precincts for a good reason."

 

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

https://thedailywtf.com/articles/i-beg-your-entschuldigung


Метки:  

Improv for Programmers: When Harddrives Attack

Четверг, 31 Мая 2018 г. 13:30 + в цитатник

Put on some comfy pants, we're back again with a little something different, brought to you by Raygun. This week's installment starts with exploding hard drives, and only Steve Buscemi can save us. Today's episode contains small quantities of profanity.



Raygun provides a window into how users are really experiencing your software applications.

Unlike traditional logging, Raygun silently monitors applications for issues affecting end users in production, then allows teams to pinpoint the root cause behind a problem with greater speed and accuracy by providing detailed diagnostic information for developers. Raygun makes fixing issues 1000x faster than traditional debugging methods using logs and incomplete information.

Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integrated, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size.

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

https://thedailywtf.com/articles/improv-for-programmers-when-harddrives-attack


Метки:  

Passing Messages

Среда, 30 Мая 2018 г. 13:30 + в цитатник

About 15 years a go, I had this job where I was requested to set up and administer an MQ connection from our company to the Depository Trust & Clearing Corporation (DTCC). Since I had no prior experience with MQ, I picked up the manual, learned a few commands, and in a day or so, had a script to create queue managers, queues, disk backing stores, etc. I got the system analysts (SA's) at both ends on the phone and in ten minutes had connectivity to their test and production environments. Access was applied for and granted to relevant individuals and applications, and application coding could begin.

Pyramid of Caius Cestius exterior, showing the giant wall which blocks everything
By Torquatus - Own work

I didn't know the full and complete way to manage most of the features of MQ, but I had figured out enough to properly support what we needed. Total time was 2.5 man-days of effort.

Fast forward to the next job, where file-drops and cron job checks for file-drops were the way interprocess communication was implemented. At some point, they decided to use a third party vendor to communicate with DTCC via MQ. Since I had done it before, they asked me to set it up. OK, easy enough. All I had to do was install it, set up a queue manager and a couple of queues to test things. Easy peasy. I put MQ on my laptop and created the queue managers and queues. Then I introduced myself to the SA at the vendor (who was in the same position I had been in at my previous job) and explained to him what I had done in the past and that I needed it set up at the current job. He agreed it was a good way to go. I then got our SAs and my counterpart at the vendor on the phone and asked them to hash out the low level connectivity. That's when I hit the wall of bureacracy-run-amok™.

It turns out that our SA's wouldn't talk to SA's outside the firm. That's what the networking team was for. OK, get them in the loop. We won't set up connectivity with outside entities without security approval. The networking team also informed me that they wouldn't support a router with connections outside the firewall, but that they would allow a router physically outside the firewall IF the vendor would support it (that's like saying I want to connect to Google, so I'll pay Google to support a router outside my firewall to connect to them).

The security people wanted to know whether hardware had been purchased yet (is the hardware "appropriate" for connecting to outside entities). The fact that it was just for a test queue to send one message fell on deaf ears; proper hardware must be approved, funded and in-place first!

The hardware people wanted to know if the hardware had been reviewed by the capacity planning team to be sure that it supported future growth (our plans were to replace a task that moved 4 (f-o-u-r) 2MB messages per day, and if successful, add 5-6 subsequent tasks comprising 10-20 similar messages each per day; a ten year old laptop would have been overpowered for this task).

This lunacy continued until we had 33 teams involved in a 342 line project plan comprising multiple man-years of effort - to set up a queue manager and 2 queues from a laptop to a vendor, to send a single test message.

At this point, everybody at the vendor was enraged at the stupidity to which our various departments were subjecting them (e.g.: you must program your firewall rules like xxx, you must provide and support a router outside out firewall, will a message sent from your hardware be able to be received on our hardware (seriously, MQ supported both platforms!), etc.), and ALL of them got on the phone to try and force me to change my mind (it wasn't coming from me: it was the other departments).

I was finally forced to say the stupidest thing I've ever had to say: Yes, I agree that the way you are proposing that we set things up is well understood, redundant, reliable, easy to set up and support, cost effective, efficient, secure, reasonably simple and generally accepted as the right way to do this, and our company will have none of that!

I then had to tell them yet again that it wasn't coming from me, and to beg them to just do it the way the bureaucracy wanted it done, or said bureaucracy would never let it happen.

At that point, I convinced my boss of the stupidity that was being inflicted on this vendor, and so he agreed to sign a five year contract, at premium rates, to get them to do it the way that our company wanted, even though we knew it was idiotic, wasteful and just plain wrong.

This went back and forth for a year. Long story short: we paid the vendor a crapton of money to supply, configure and remotely support a router at our location outside the firewall, we paid them a fortune for five years of capacity to push 10 million messages per day, and we spent more than $750,000 on super high powered redundant hot/standby hardware across dev, test, qa, pre-production, production and DR environments, all before we were allowed to send one test message across a test queue.

Our company then decided not to move to the more modern messaging technology because it was too difficult to set up and that they would continue to use cron job checks for file-drops as message-ready indicators. I pointed out that the difficulty was from the internal bureaucracy and not the vendor or the technology... . They never sent another message down that queue, and left all that iron - dedicated to the cancelled project - unused, fully supported and running in all the environments for five years, after which the process of decommissioning hardware was triggered (I'll leave this for your nightmares to imagine).

I later found out that I was the 5th person (out of 8 over 10 years) hired to perform this same migration. Apparently each of us ran into the same impenetrable wall-o-bureaucracy.

To this day, they are still doing interprocess communication via file-drops and cron jobs to check for the dropped files.

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

https://thedailywtf.com/articles/passing-messages


Метки:  

CodeSOD: Modern Art: The Funnel

Вторник, 29 Мая 2018 г. 13:30 + в цитатник

They say a picture is worth a thousand words, and when it's a picture of code, you could say that it contains a thousand words, too. Especially when it's bad code.

A 35 line enum definition which channels down to a funnel shape, I apologize for not providing the code in textual form, but honestly, this needs to be seen to be believed

Here we have a work of true art. The symmetry hearkens back to the composition of a frame of a Wes Anderson film, and the fact that this snippet starts on line 418 tells us that there's more to this story, something exotic happening just outside of frame. The artist is actively asking questions about what we know is true, with the method calls? &emdash;I think they're method calls&emdash; which take too many parameters, most of which are false. There are hints of an Inner Platform, but they're left for the viewer to discover. And holding it all together are the funnel-like lines which pull the viewer's eyes, straight through the midline, all the way down to the final DataType.STRING, which really says it all, doesn't it? DataType.STRING indeed.

If I ran an art gallery, I would hang this on a wall.

If I ran a programming team, I'd hang the developer instead.

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

https://thedailywtf.com/articles/modern-art-the-funnel


Метки:  

CodeSOD: Classic WTF: Quantum Computering

Понедельник, 28 Мая 2018 г. 13:30 + в цитатник
When does anything but [0-9A-F] equal "2222"? Well, it's a holiday in the US today, so take a look at this classic WTF where that's exactly what happens… -Remy

A little while back, I posted a function that generated random hexadecimal-like strings for a GUID-like string to identify events. At first, I thought it (and the rest of the system that Taka's company purchased) was just bad code. But now that I look at it further, I'm stunned at its unbelievable complexity. I can honestly say that I've never seen code that is actually prepared to run a quantum computer, where binary just isn't as simple as 1's and 0's ...

Function hex2bin(hex)
  Select Case hex
    Case "0"
      hex2bin = "0000"
    Case "1"
      hex2bin = "0001"
    Case "2"
      hex2bin = "0010"
    Case "3"
      hex2bin = "0011"
    Case "4"
      hex2bin = "0100"
    Case "5"
      hex2bin = "0101"
    Case "6"
      hex2bin = "0110"
    Case "7"
      hex2bin = "0111"
    Case "8"
      hex2bin = "1000"
    Case "9"
      hex2bin = "1001"
    Case "A"
      hex2bin = "1010"
    Case "B"
      hex2bin = "1011"
    Case "C"
      hex2bin = "1100"
    Case "D"
      hex2bin = "1101"
    Case "E"
      hex2bin = "1110"
    Case "F"
      hex2bin = "1111"
    Case Else
      hex2bin = "2222"
  End Select
End Function

The library codefiles for this system has plenty of other ultra-advanced functions. We'll have to explore these another day, but I will leave you with this method of handling quantum hexadecimal ...

Function hex2dec(hex)
  Select Case hex
    Case "0"
      hex2dec = 0
    Case "1"
      hex2dec = 1
    Case "2"
      hex2dec = 2
    Case "3"
      hex2dec = 3
    Case "4"
      hex2dec = 4
    Case "5"
      hex2dec = 5
    Case "6"
      hex2dec = 6
    Case "7"
      hex2dec = 7
    Case "8"
      hex2dec = 8
    Case "9"
      hex2dec = 9
    Case "A"
      hex2dec = 10
    Case "B"
      hex2dec = 11
    Case "C"
      hex2dec = 12
    Case "D"
      hex2dec = 13
    Case "E"
      hex2dec = 14
    Case "F"
      hex2dec = 15
    Case Else
      hex2dec = -1
 End Select
End Function
[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!

https://thedailywtf.com/articles/classic-wtf-quantum-computering


Метки:  

Error'd: Go Home Google News, You're Drunk

Пятница, 25 Мая 2018 г. 13:30 + в цитатник

"Well, it looks like Google News was inebriated as well!" Daniel wrote.

 

"(Translation: Given names similar to Otto) One must wonder which distance measure algorithm they used to decide that 'Faseaha' is more similar to Otto than Otto," writes Peter W.

 

Andrei V. writes, "What amazing discounts for rental cars offered by Air Baltic!"

 

"I know that Amazon was trying to tell me something about my Kindle author status, but the message appears to have been lost in translation," Bob wrote.

 

"I tried to sign up for severe weather alerts and I'm 100% sure I'm actually signed up. NOT!" writes, Eric R.

 

Lorens writes, "I think the cryptocurrency bubble may have exploded. Or imploded."

 

[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/go-home-google-news-you-re-drunk


Метки:  

Improv for Programmers: Just for Transformers

Четверг, 24 Мая 2018 г. 13:30 + в цитатник

We're back again with a little something different, brought to you by Raygun. Once again, the cast of "Improv for Programmers" is going to create some comedy on the fly for you, and this time… you could say it's… transformative. Today's episode contains small quantities of profanity.



Raygun provides a window into how users are really experiencing your software applications.

Unlike traditional logging, Raygun silently monitors applications for issues affecting end users in production, then allows teams to pinpoint the root cause behind a problem with greater speed and accuracy by providing detailed diagnostic information for developers. Raygun makes fixing issues 1000x faster than traditional debugging methods using logs and incomplete information.

Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integrated, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size.

[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!

https://thedailywtf.com/articles/improv-for-programmers-just-for-transformers


Метки:  

Business Driven Development

Среда, 23 Мая 2018 г. 13:30 + в цитатник

Every now and then, you come across a special project. You know the sort, where some business user decides that they know exactly what they need and exactly how it should be built. They get the buy-in of some C-level shmoe by making sure that their lips have intimate knowledge of said C-level butt. Once they have funding, they have people hired and begin to bark orders.

Toonces, the Driving Cat

About 8 years ago, I had the privilege experience of being on such a project. When we were given the phase-I specs, all the senior tech people immediately said that there was no way to perform a sane daily backup and data-roll for the next day. The response was "We're not going to worry about backups and daily book-rolls until later". We all just cringed, made like good little HPCs and followed our orders to march onward.

Fast forward about 10 months and the project had a sufficient amount of infrastructure that the business user had no choice but to start thinking about how to close the books each day, and roll things forward for the next day. The solution he came up with was as follows:

   1. Shut down all application servers and the DB
   2. Remove PK/FK relationships and rename all the tables in the database from: xxx to: xxx.yyyymmdd
   3. Create all new empty tables in the database (named: xxx)
   4. Create all the PK/FK relationships, indices, triggers, etc.
   5. Prime the new: xxx tables with data from the: xxx. tables
   6. Run a job to mirror the whole thing to offsite DB servers
   7. Run the nightly backups (to tape)
   8. Fire up the DB and application servers

Naturally, all the tech people groaned, mentioning things like history tables, wasted time regenerating indices, nightmares if errors occurred while renaming tables, etc., but they were ignored.

Then it happened. As is usually the case when non-technical people try to do technical designs, the business user found himself designed into a corner.

The legitimate business-need came up to make adjustments to transactions for the current business day after the table-roll to the next business day had completed.

The business user pondered it for a bit and came up with the following:

    1. Shut down all application servers and the DB
    2. Remove PK/FK relationships and rename the post-roll tables of tomorrow from xxx to xxx.tomorrow
    3. Copy SOME of the xxx.yyyymmdd tables from the pre-roll current day back to: xxx
       (leaving the PK's and indices notably absent)
    4. Restart the DB and application servers (with some tables rolled and some not rolled)
    5. Let the users make changes as needed
    6. Shut down the application and DB servers
    7. Manually run ad-hoc SQL to propagate all changes to the xxx.tomorrow table(s)
    8. Rename the: xxx tables to: xxx.yyyymmdd.1 
       (or 2 or 3, depending upon how many times this happened per day)
    9. Rename the xxx.tomorrow tables back to: xxx
   10. Rebuild all the PK/FK relationships, create new indices and re-associate triggers, etc.
   11. Rerun the mirroring and backup scripts
   12. Restart the whole thing

When we pointed out the insanity of all of this, and the extremely high likelihood of any failure in the table-renaming/moving/manual-updating causing an uncorrectable mess that would result in losing the entire day of transactions, we were summarily terminated as our services were no longer required — because they needed people who knew how to get things done.

I'm the first to admit that there are countless things that I do not know, and the older I get, the more that list seems to grow.

I'm also adamant about not making mistakes I know will absolutely blow up in my face - even if it costs me a job. If you need to see inside of a gas tank, throwing a lit match into it will illuminate the inside, but you probably won't like how it works out for you.

Five of us walked out of there, unemployed and laughing hysterically. We went to our favorite watering hole and decided to keep tabs on the place for the inevitable explosion.

Sure enough, 5 weeks after they had junior offshore developers (who didn't have the spine to say "No") build what they wanted, someone goofed in the rollback, and then goofed again while trying to unroll the rollback.

It took them three days to figure out what to restore and in what sequence, then restore it, rebuild everything and manually re-enter all of the transactions since the last backup. During that time, none of their customers got the data files that they were paying for, and had to find alternate sources for the information.

When they finally got everything restored, rebuilt and updated, they went to their customers and said "We're back". In response, the customers told them that they had found other ways of getting the time-sensitive information and no longer required their data product.

Not only weren't the business users fired, but they got big bonuses for handling the disaster that they had created.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

https://thedailywtf.com/articles/business-driven-development


Метки:  

Representative Line: Aggregation of Concatenation

Вторник, 22 Мая 2018 г. 13:30 + в цитатник

A few years back, JSON crossed the “really good hammer” threshold. It has a good balance of being human readable, relatively compact, and simple to parse. It thus has become the go-to format for everything. “KoHHeKT” inherited a service which generates some JSON from an in-memory tree structure. This is exactly the kind of situation where JSON shines, and it would be trivial to employ one of the many JSON serialization libraries available for C# to generate JSON on demand.

Orrrrr… you could use LINQ aggregations, string formatting and trims…

private static string GetChildrenValue(int childrenCount)
{
        string result = Enumerable.Range(0, childrenCount).Aggregate("", (s, i) => s + $"\"{i}\",");
        return $"[{result.TrimEnd(',')}]";
}

Now, the concatenation and trims and all of that is bad. But I’m mostly stumped by what this method is supposed to accomplish. It’s called GetChildrenValue, but it doesn’t return a value- it returns an array of numbers from 0 to children count. Well, not an array, obviously- a string that can be parsed into an array. And they’re not actually numbers- they’re enclosed in quotes, so it’s actually text, not that any JavaScript client would care about the difference.

Why? How is this consumed? KoHHeKT couldn’t tell us, and we certainly aren’t going to figure it out from this block. But it is representative of the entire JSON constructing library- aggregations and concatenations with minimal exception handling and no way to confirm that it output syntactically valid JSON because nothing sanitizes its inputs.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

https://thedailywtf.com/articles/aggregation-of-concatenation


Метки:  

The New Guy (Part I)

Понедельник, 21 Мая 2018 г. 13:30 + в цитатник

After working mind-numbing warehouse jobs for several years, Jesse was ready for a fresh start in Information Technology. The year 2015 brought him a newly-minted Computer and Networking Systems degree from Totally Legit Technical Institute. It would surely help him find gainful employment, all he had to do was find the right opportunity.

DNS hierarchy Seeking the right opportunity soon turned in to any opportunity. Jesse came across a posting for an IT Systems Administrator that piqued his interest but the requirements and responsibilities left a lot to be desired. They sought someone with C++ and Microsoft Office experience who would perform "General IT Admin Work" and "Other Duties as assigned". None of those things seemed to fit together, but he applied anyway.

During the interview, it became clear that Jesse and this small company were essentially in the same boat. While he was seeking any IT employment, they were seeking any IT Systems admin. Their lone admin recently departed unexpectedly and barely left any documentation of what he actually did. Despite several red flags about the position, he decided to accept anyway. Jesse was assured of little oversight and freedom to do things his way - an extreme rarity for a young IT professional.

Jesse got to work on his first day determined to map out the minefield he was walking in to. The notepad with all the admin passwords his predecessor left behind was useful for logging in to things. Over the next few days, he prodded through the network topology to uncover all the horrors that lie within. Among them:

  • The front-end of their most-used internal application was using Access 97 that interfaced with a SQL Server 2008 machine
  • The desktop computers were all using Windows XP (Half of them upgraded from NT 4.0)
  • The main file server and domain controller were still running on NT 4.0
  • There were two other mystery servers that didn't seem to perform any discernible function. Jesse confirmed this by unplugging them and leaving them off

While sorting through the tangled mess he inherited, Jesse got a high priority email from Ralph, the ancient contracted Networking Admin whom he hadn't yet had the pleasure of meeting. "U need to fix the website. FTP not working." While Ralph wasn't one for details, Jesse did learn something from him - they had a website, it used FTP for something, and it was on him to fix it.

Jesse scanned the magic password notepad and came across something called "Website admin console". He decided to give that a shot, only to be told the password was expired and needed to be reset. Unfortunately the reset email was sent to his predecessor's deactivated account. He replied to Ralph telling him he wasn't able to get to the admin console to fix anything.

All that he got in return was a ticket submitted by a customer explaining the problem and the IP address of the FTP server. It seemed they were expecting to be able to fetch PDF reports from an FTP location and were no longer able to. He went to the FTP server and didn't find anything out of the ordinary, other than the fact that is should really be using SFTP. Despite the lack of security, something was still blocking the client from accessing it.

Jesse suddenly had an idea born of inexperience for how to fix the problem. When he was having connectivity issues on his home WiFi network, all he had to do was reboot the router and it would work! That same logic could surely apply here. After tracking down the router, he found the outlet wasn't easily accessible. So he decided to hit the (factory) Reset button on the back.

Upon returning to his desk, he was greeted by nearly every user in their small office. Nobody's computer worked any more. After turning a deep shade of red, Jesse assured everyone he would fix it. He remembered something from TL Tech Institute called DNS that was supposed to let computers talk to each other. He went around and set everyone's DNS server to 192.168.1.0, the address they always used in school. It didn't help.

Jesse put in a call to Ralph and explained the situation. All he got was a lecture from the gravelly-voiced elder on the other end, "You darn kids! Why don't ye just leave things alone! I've been working networks since before there were networks! Give me a bit, I'll clean up yer dang mess!" Within minutes, Ralph managed to restore connectivity to the office. Jesse checked his DNS settings out of curiosity to find that the proper setting was 2.2.2.0.

The whole router mishap made him completely forget about the original issue - the client's FTP. Before he could start looking at it again, Ralph forwarded him an email from the customer thanking them for getting their reports back. Jesse had no idea how or why that was working now, but he was willing to accept the praise. He solved his first problem, but the fun was just beginning...

To be continued...

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!

https://thedailywtf.com/articles/the-new-guy-part-i


Метки:  

Error'd: Perfectly Technical Difficulties

Пятница, 18 Мая 2018 г. 13:00 + в цитатник

David G. wrote, "For once, I'm glad to see technical issues being presented in a technical way."

 

"Springer has a very interesting pricing algorithm for downloading their books: buy the whole book at some 10% of the sum of all its individual chapters," writes Bernie T.

 

"While browsing PlataGO! forums, I noticed the developers are erasing technical debt...and then some," Dariusz J. writes.

 

Bill K. wrote, "Hooray! It's an 'opposite sale' on Adidas' website!"

 

"A trail camera disguised at a salad bowl? Leave that at an all you can eat buffet and it'll blend right in," wrote Paul T.

 

Brian writes, "Amazon! That's not how you do math!"

 

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!

https://thedailywtf.com/articles/perfectly-technical-difficulties


Метки:  

Improv for Programmers: Inventing the Toaster

Четверг, 17 Мая 2018 г. 13:30 + в цитатник

We always like to change things up a little bit here at TDWTF, and thanks to our sponsor Raygun, we've got a chance to bring you a little treat, or at least something a little different.

We're back with a new podcast, but this one isn't a talk show or storytelling format, or even a radio play. Remy rounded up some of the best comedians in Pittsburgh who were also in IT, and bundled them up to do some improv, using articles from our site and real-world IT news as inspiration. It's… it's gonna get weird.



Thanks to Erin Ross, Ciar'an 'O Conaire, and Josh Cox for lending their time and voices to this project.

Music: "Happy Happy Game Show" Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 3.0 License http://creativecommons.org/licenses/by/3.0/

Raygun gives you a window into the real user-experience for your software. With a few minutes of setup, all the errors, crashes, and performance issues will be identified for you, all in one tool. Not only does it make your applications better, with Raygun APM, it proactively identifies performance issues and builds a workflow for solving them. Raygun APM sorts through the mountains of data for you, surfacing the most important issues so they can be prioritized, triaged and acted on, cutting your Mean Time to Resolution (MTTR) and keeping your users happy.

Now’s the time to sign up. In a few minutes, you can have a build of your app with Raygun integration, and you’ll be surprised at how many issues it can identify. There’s nothing to lose with a 14-day free trial, and there are pricing options available that fit any team size.

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

https://thedailywtf.com/articles/improv-for-programmers-attack-of-the-robots


Метки:  

CodeSOD: Return of the Mask

Среда, 16 Мая 2018 г. 13:30 + в цитатник

Sometimes, you learn something new, and you suddenly start seeing it show up anywhere. The Baader-Meinhof Phenomenon is the name for that. Sometimes, you see one kind of bad code, and the same kind of bad code starts showing up everywhere. Yesterday we saw a nasty attempt to use bitmasks in a loop.

Today, we have Michele’s contribution, of a strange way of interacting with bitmasks. The culprit behind this code was a previous PLC programmer, even if this code wasn’t running straight on the PLC.

public static bool DecodeBitmask(int data, int bitIndex)
{
        var value = data.ToString();
        var padding = value.PadLeft(8, '0');
        return padding[bitIndex] == '1';
}

Take a close look at the parameters there- data is an int. That’s about what you’d expect here… but then we call data.ToString() which is where things start to break down. We pad that string out to 8 characters, and then check and see if a '1' happens to be in the spot we’re checking.

This, of course, defeats the entire purpose and elegance of bit masks, and worse, doesn’t end up being any more readable. Passing a number like 2 isn’t going to return true for any index.

Why does this work this way?

Well, let’s say you wanted a bitmask in the form 0b00000111. You might say, “well, that’s a 7”. What Michele’s predecssor said was, "that’s text… "00000111". But the point of bitmasks is to use an int to pass data around, so this developer went ahead on and turned "00000111" into an integer by simply parsing it, creating the integer 111. But there’s no possibly way to check if a certain digit is 1 or not, so we have to convert it back into a string to check the bitmask.

Unfortunately, the software is so fragile and unreliable that no one is willing to let the developers make any changes beyond “it’s on fire, put it out”.

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!

https://thedailywtf.com/articles/return-of-the-mask


Метки:  

CodeSOD: A Bit Masked

Вторник, 15 Мая 2018 г. 13:30 + в цитатник

The “for-case” or “loop-switch” anti-pattern creates some hard to maintain code. You know the drill: the first time through the loop, do one step, the next time through the loop, do a different step. It’s known as the “Anti-Duff’s Device”, which is a good contrast: Duff’s Device is a clever way to unroll a loop and turn it into a sequential process, while the “loop-switch” takes a sequential process and turns it into a loop.

Ashlea inherited an MFC application. It was worked on by a number of developers in Germany, some of which used English to name identifiers, some which used German, creating a new language called “Deunglish”. Or “Engleutch”? Whatever you call it, Ashlea has helpfully translated all the identifiers into English for us.

Buried deep in a thousand-line “do everything” method, there’s this block:

if(IS_SOMEFORMATNAME()) //Mantis 24426
{
  if(IS_CONDITION("RELEASE_4"))
  {
    m_BAR.m_TLC_FIELDS.DISTRIBUTIONCHANNEL="";
    CString strKey;
    for (unsigned int i=1; i<16; i++) // Test all combinations
    {
      strKey="#W#X#Y#Z";
      if(i & 1)
        strKey.Replace("#W", m_strActualPromo);  // MANTIS 45587: Search with and without promotion code
      if(i & 2)
        strKey.Replace("#X",m_BAR.m_TLC_FIELDS.OBJECTCODE);
      if(i & 4)
        strKey.Replace("#Y",TOKEN(strFoo,H_BAZCODE));
      if(i & 8)
        strKey.Replace("#Z",TOKEN(strFoo,H_CHAIN));

      strKey.Replace("#W","");
      strKey.Replace("#X","");
      strKey.Replace("#Y","");
      strKey.Replace("#Z","");

      if(m_lDistributionchannel.GetFirst(strKey))
      {
        m_BAR.m_TLC_FIELDS.DISTRIBUTIONCHANNEL="R";
        break;
      }
    }
  }
  else
    m_BAR.m_TLC_FIELDS.DISTRIBUTIONCHANNEL=m_lDistributionchannel.GetFirstLine(m_BAR.m_TLC_FIELDS.OBJECTCODE+m_strActualPromo);
}

Here, we see a rather unique approach to using a for-case- by using bitmasks to combine steps on each iteration of the loop. From what I can tell, they have four things which can combine to make an identifier, but might get combined in many different ways. So they try every possible combination, and if it exists, they can set the DISTRIBUTIONCHANNEL field.

That’s ugly and awful, and certainly a WTF, but honestly, that’s not what leapt out to me. It was this line:

if(IS_CONDITION("RELEASE_4"))

It’s quite clear that, as new versions of the software were released, they needed to control which features were enabled and which weren’t. This is probably related to a database, and thus the database may or may not be upgraded to the same release version as the code. So scattered throughtout the code are checks like this, which enable blocks of code at runtime based on which versions match with these flags.

Debugging that must be a joy.

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

https://thedailywtf.com/articles/a-bit-masked


Метки:  

CodeSOD: CONDITION_FAILURE

Понедельник, 14 Мая 2018 г. 13:30 + в цитатник

Oliver Smith sends this representative line:

bool long_name_that_maybe_distracted_someone()
{
  return (execute() ? CONDITION_SUCCESS : CONDITION_FAILURE);
}

Now, we’ve established my feelings on the if (condition) { return true; } else { return false; } pattern. This is just an iteration on that theme, using a ternary, right?

That’s certainly what it looks like. But Oliver was tracking down an unusual corner-case bug and things just weren’t working correctly. As it turns out, CONDITION_SUCCESS and CONDITION_FAILURE were both defined in the StatusCodes enum.

Screenshot of the intellisense which shows CONDITION_FAILURE defined as 2

Yep- CONDITION_FAILURE is defined as 2. The method returns a bool. Guess what happens when you coerce a non-zero integer into a boolean in C++? It turns into true. This method only ever returns true. Ironically, the calling method would then do its own check against the return value, looking to see if it were CONDITION_SUCCESS or CONDITION_FAILURE.

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

https://thedailywtf.com/articles/condition-failure


Метки:  

Error'd: Kind of...but not really

Пятница, 11 Мая 2018 г. 13:00 + в цитатник

"On occasion, SQL Server Management Studio's estimates can be just a little bit off," writes Warrent B.

 

Jay D. wrote, "On the surface, yeah, it looks like a good deal, but you know, pesky laws of physics spoil all the fun."

 

"When opening a new tab in Google Chrome I saw a link near the bottom of the screen that suggested I 'Explore the world's iconic locations in 3D'," writes Josh M., "Unfortunately, Google's API felt differently."

 

Stuart H. wrote, "I think I might have missed out on this deal, the clock was counting up, no I mean down, I mean negative AHHHH!"

 

"Something tells me this site's programmer is learning how to spell the hard(est) way," Carl W. writes.

 

"Why limit yourself with one particular resource of the day when you can substitute any resource you want," wrote Ari S.

 

[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/kind-of-but-not-really


Метки:  

CodeSOD: A Quick Replacement

Четверг, 10 Мая 2018 г. 13:30 + в цитатник

Lucio Crusca was doing a bit of security auditing when he found this pile of code, and it is indeed a pile. It is PHP, which doesn’t automatically make it bad, but it makes use of a feature of PHP so bad that they’ve deprecated it in recent versions: the create_function method.

Before we even dig into this code, the create_function method takes a string, runs eval on it, and returns the name of the newly created anonymous function. Prior to PHP 5.3.0 this was their method of doing lambdas. And while the function is officially deprecated as of PHP 7.2.0… it’s not removed. You can still use it. And I’m sure a lot of code probably still does. Like this block…

        public static function markupToPHP($content) {
                if ($content instanceof phpQueryObject)
                        $content = $content->markupOuter();
                /* ... to )+\\w+\\s*=\\s*)(')([^']*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^']*)'@s',
                        '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^"]*)"@s',
                );
                foreach($regexes as $regex)
                        while (preg_match($regex, $content))
                                $content = preg_replace_callback(
                                        $regex,
                                        create_function('$m',
                                                'return $m[1].$m[2].$m[3]."".$m[5].$m[2];'
                                        ),
                                        $content
                                );
                return $content;
        }

From what I can determine from the comments and the code, this is taking some arbitrary content in the form PHP CODE HERE and converting it to . I don’t know what happens after this function is done with it, but I’m already terrified.

The inner-loop fascinates me. while (preg_match($regex, $content)) implies that we need to call the replace function multiple times, but preg_replace_callback by default replaces all instances of the matching regex, so there’s absolutely no reason fo the while loop. Then, of course, the use of create_function, which is itself a WTF, but it’s also worth noting that there’s no need to do this dynamically- you could just as easily have declared a callback function like they did above with _markupToPHPCallback.

Lucio adds:

I was looking for potential security flaws: well, I’m not sure this is actually exploitable, because even black hats have limited patience!

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

https://thedailywtf.com/articles/a-quick-replacement


Метки:  

Exponential Backup

Среда, 09 Мая 2018 г. 13:30 + в цитатник

The first day of a new job is always an adjustment. There's a fine line between explaining that you're unused to a procedure and constantly saying "At my old company...". After all, nobody wants to be that guy, right? So you proceed with caution, trying to learn before giving advice.

But some things warrant the extra mile. When Samantha started her tenure at a mid-sized firm, it all started out fine. She got a computer right away, which is a nice plus. She met the team, got settled into a desk, and was given a list of passwords and important URLs to get situated. The usual stuff.

After changing her Windows password, she decided to start by browsing the source code repository. This company used Subversion, so she went and downloaded the whole repo so she could see the structure. It took a while, so she got up and got some coffee; when she got back, it had finished, and she was able to see the total size: 300 GB. That's... weird. Really weird. Weirder still, when she glanced over the commit history, it only dated back a year or so.

What could be taking so much space? Were they storing some huge binaries tucked away someplace that the code depended on? She didn't want to make waves, but this just seemed so... inefficiently huge. Now curious, she opened the repo, browsing the folder structure.

Subversion bases everything on folder structure; there is only really one "branch" in Git's thinking, but you can check out any subfolder without taking the whole repository. Inside of each project directory was a layout that is common to SVN repos: a folder called "branches", a folder called "tags", and a folder called "trunk" (Subversion's primary branch). In the branches directory there were folders called "fix" and "feature", and in each of those there were copies of the source code stored under the names of the branches. Under normal work, she'd start her checkout from one of those branch folders, thus only pulling down the code for her branch, and merge into the "trunk" copy when she was all done.

But there was one folder she didn't anticipate: "backups". Backups? But... this is version control. We can revert to an earlier version any time we want. What are the backups for? I must be misunderstanding. She opened one and was promptly horrified to find a series of zip files, dated monthly, all at revision 1.

Now morbidly curious, Samantha opened one of these zips. The top level folder inside the zip was the name of the project; under that, she found branches, tags, trunk. No way. They can't have-- She clicked in, and there it was, plain as day: another backups folder. And inside? Every backup older than the one she'd clicked. Each backup included, presumably, every backup prior to that, meaning that in the backup for October, the backup from January was included nine times, the backup from February eight times, and so on and so forth. Within two years, a floppy disk worth of code would fill a terabyte drive.

Samantha asked her boss, "What will you do when the repo gets too big to be downloaded onto your hard drive?

His response was quick and entirely serious: "Well, we back it up, then we make a new one."

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!

https://thedailywtf.com/articles/exponential-backup


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 65 64 [63] 62 61 ..
.. 1 Календарь