what i got was:
{"elem" : "html", "children": [ ... {"elem" : "form", "attrs" : {"action": "/an_url", "method" : "post"}, children: [{"input" : {"attrs" : {"type" : "submit", "value" : "..."}}}]} ..., ]}
yes, their json interface was the DOM, serialized as json. but it gets better. to submit my data i had to fill in the actual values in their json struct at the appropriate nodes and send it back.i'm a) pretty sure this "json interface" feature cost the customer more than i make in a year, and b) it probably broke the very instant the customer let a frontend/designer guy change the html code months later.
strncpy(dst, src, strlen(src));
dst[strlen(dst)] = '\0';That line alone is cancerous.
The way a string is terminated in C is by a null character. ‘\0’ is a mnemonic. strlen() returns the length of a strong. It does this by doing a linear scan down the array until it finds the null, and the returns that index as the length.
That line of code does nothing useful. It means, “scan through the array until you find a null, then write a null there.” Which is exactly what you had to start.
So why would someone write this? Well, they were told to make sure that you always terminate your C strings with a null, otherwise you’ll run off the end of the array and corrupt memory. This is true, but this isn’t how you need to find the end of the array. They should have used the number from strlen(src), not strlen(dest). Even worse, strncpy() will put the null terminator in dest in this case.
The line belies any sense that the programmer had any understanding of what the code was actually doing. It’s a amateur mistake.
It has to be the size of dst, which can only be known at the site of allocation in C (except for a non-clean way of looking at heap metadata).
It never makes sense to use strlen() for an argument to strncpy(). Only the size of the destination buffer makes sense for strncpy() (usually sizeof(dst)). For other cases you would probably use memcpy().
I thought the point was that they didn't know if the dest is long enough to copy source, so they copy as much of it as they can.
The reason for the '\0' is in the case that src is shorter than dest.
A more explicit way may be to strlen dest > src then just use lenght(src) otherwise use str(dest).
But this might actually be more efficient.
Edit: And in this case Spolsky doesn't apply because it seems the developer doesn't get to allocate the dest length.
If dst is larger than src, the strcpy* family of functions will also copy over the null byte.
If dst is shorter than src, and if strlen(src) is used as arg for strncpy then the function will overflow in dst and your null byte will also be outside dst buffer. In hardened environments you wouldn't trust strings to contain null byte if it comes from network or user and use strlcpy with known size of dst then append a null byte at end of dst anyway to ensure it is null terminated.
Using strlen to compare buffer sizes is totally wrong and is the source for many bugs (hint, strlen doesn't actually return size of anything but the distance of the first null byte from the address you provide it).
[1] https://www.joelonsoftware.com/2001/12/11/back-to-basics/
This is the real problem. That PM of course wants the work done yesterday and has ego issues so even when the contractor does question it they just double down on what they originally said.
Do we know that the developers were outsourced or which countries they were from?
IBM sold a big outsourcing package to a major European insurance company: they would move ALL their stuff to the IBM Cloud (VMWare with a lot of custom BPM workflows to handle provisioning, etc.). None of this matched their other three big cloud projects, Bluemix, Softlayer, or their OpenStack project (Zenith -- my prior project), so it was all new from the ground up.
They needed to handle mass imports of DNS data from this insurance company (~1 million hosts) and other customers and they brought me in as a senior developer to do the grunt work. Since we were using ISC bind, I assumed we could use features like exporting zones with signed requests and take advantage of all the infrastructure work put into that server to scale up. Our Senior Architect poo-pooed that plan, so I started modeling the DNS records as structured data for consistent and complete import and export. Our senior architect also nixed that idea and said that we're gonna load the DNS structures with REST requests: the support people were gonna have a custom web application to load simple DNS export files (not zonefiles, mind you) into this system, and to make ad-hoc additions and changes. (When we had a new developer join, he had the same questions I had about why we weren't using all the DNS bind features since they were done and tested and perfect for our needs . . . it took a month to get him to stop asking.)
I got about 90% of the way through a solution with a Python Flask REST server at the center, high code coverage through unit tests (because it's Python and I was still finding edge cases that needed fixing to the very end), and Rabbit MQ for enqueuing the changes we've received before writing them out to DNS zone files. It works, but we certainly didn't need to blow April to August building out the architect's vision.
The reward I got was being pulled off the project when it was nearly code complete and would shortly go into production. I got a team based in India to manage in the mornings, while my afternoons and evenings were returned to developing Javascript for the BPM infrastructure jobs.
(When told I was going to leave for another company, IBM's counter-offer was to move me from my remote work-at-home location in Ohio, near family, to the Cloud Managed Services office in Rochester, MN, and then consider a raise.)
This is pure thedailywtf material.
I get that you do need specs but c'mon, if you ask a plumber to fit a pipe from A to B and he uses one made out of cardboard would you think it was reasonable for him to say "well you didn't specify it had to carry water, pay me 3x as much to put it right". And then you find out that this is the first time he's even seen a pipe, but his business card says "senior plumbing expert".
You expect a basic level of competence and familiarity with the problem domain and good faith from any professional whose services you hire.
Also consider that a program is a spec, and if you are going to explicitly specify every little detail then you might as well just write the program yourself, there is literally no sane reason to put an outsourcer in the middle.
A responsible developer is expected to ask insistently until the requirements make sense; whoever delivered the JSON DOM is stealing their pay, even if they did it knowingly as a joke or provocation.
- 2016. Australia decided to run a census, population wide (~22 million people), all online. If you didn't enter your stuff you risked a fine. You had one day to get a good 'snapshot'. The service, built by IBM, went down immediately.
'Census outage could have been prevented by turning router on and off again: IBM' http://www.abc.net.au/news/2016-10-25/turning-router-off-and...
'IBM to pay more than $30m in compensation for census fail, Prime Minister Malcolm Turnbull suggests' http://www.abc.net.au/news/2016-11-25/ibm-to-pay-over-$30m-i... (Have they done this? I don't think so)
They said it was an 'overseas DDOS' but there is no proof for that, personally I think it was Australians accessing the page from overseas.
Interestingly, this is not on IBM's Wikipedia page.
- In Queensland, IBM borked the rollout of a new health payroll system so extremely that the state premier banned the state from outsourcing to IBM (and that was before the census catastrophe!!)
>The commission, headed by former supreme court judge Richard Chesterman, tied a number of IBM employees working on the contract bid to serious ethical transgressions, including using leaked information about competitors to gain advantage and attempting to access tender responses by opposing bidders Logica and Accenture.
https://www.itnews.com.au/news/queenslands-ibm-ban-lives-on-...
In the end, the state had to carry the costs (1.2 billion) https://www.itnews.com.au/news/qld-health-ibm-payroll-court-...
It was supposed to cost less than 10 million.
This is also not on IBM's Wikipedia page.
Of course it was fine 15 years ago but from that time we had quite a lot changes in tax system, many new conditions has been addad and in the result we have unstable deprecated software where maintainability is nowadays near to ZERO.
There are currently no people who knows how it works and who knows Informix 4GL language in 2018... After few years it will be probably replaced but cost of new project will astronomical (...of course).
I am not blaming purely IBM, quite often government officials are incompetent when it comes to software project planning.
This is blatantly corrupt, why the fuck would a government give a company a waiver from their contractual responsibilities on a failed project? That's utterly insane.
The problem is not that they wouldn't be able to parse the cookie, it's that Akamai edge node web server (Nginx or Apache, don't remember) rejects any request with a header that's above a certain size. Your origin server doesn't even get to know that there ever was such a request.
See https://maxchadwick.xyz/blog/http-request-header-size-limits for example.
https://www.youtube.com/watch?v=C5d151lqJsA#t=2m4s
Do you happen to remember what the copy was on that page?
I'm sure it had to be something better than "Hey we made your cookie too big. Can we delete it? Ok thanks sorry about that."
I bet they went with something subtle and vague, make the problem a little unclear and complicated-sounding, maybe take a little credit for Websphere doing a good job in detecting the problem.
Like how I word all my work emails.
"We are unable to process your request due to a problem with your cookie, please click below to delete the cookie"
And then there was just a normal button input.
Their logic around having the user click the button instead of just automatically deleting the cookie and moving on (Something that still shouldn't be necessary if you are using cookies correctly) is that they thought users would be upset at IBM automatically deleting their 'data' without asking. That data just being a bunch of unreadable values for IBMs services.
If I decided I wanted to visit one of our offshore dev teams, I could book a first-class ticket anytime I wanted to with no approval necessary. If I wanted $2m for some dev effort, I could have the necessary approvals in a day or so. But if I wanted to write 50 bytes to a .company.com cookie, that was weeks of meetings where I needed to justify my team's existence, the value of the feature we were building and prove there was no other way to implement it.
Admittedly it is a better practice than continuing to stuff you cookie and direct users to a strange page once in a while.
For example, after a merger in which two company websites should be integrated you might start with one simple cookie, transition quickly to two independent cookies on two domains, then use a cookie with two keys when the two sites have separate backends but the same domain, then eventually a cookie with a single key again after extensive replacements and reimplementations.
If they had a core technology team they could handle things like this more gracefully. Or maybe not, this is IBM after all.
I mean, in the same company you have on one end of the scale lots of teams doing just outsourced IT support ("my corporate word install is broken, pls fix"). And on the other end for instance the IBM Zürich research lab, who have received multiple Nobel prizes in physics and who developed things like Token ring and Trellis code modulation.
- Their PCF solution is deprecated - They were still using a deprecated container management solution instead of kubernetes until recently - If you use Java the for you to use liberty build packs - They push XP and TDD practices from the garage yet many of their consultants don't practice what they preach.
And then they rebranded IBM Spectrum Conductor for Containers (look it up!), a Kubernetes snowflake they came up with, into IBM Cloud Private, because Kubernetes will solve all problems, the issues MUST have been leading with a PaaS and not a CaaS, right?
Other observations are spot on
Disclaimer, I compete with IBM and have to deal with their account team shenanigans, though parts of IBM are better than others and even can be good partners.
If they want to accept the positives of the IBM brand then they need to accept all the negatives that come with it. Unfortunately for them that brand is now toxic.
The problem they were having is that all the various IBM lines of business added so much garbage onto the client's cookie, that eventually their pages would stop loading because they wouldn't be able to parse the cookie.
The 'solution' is to detect when that's about to happen, and redirect the client to a page that warns them that their cookie is too big (because IBM made it too big) and give them a button to delete their cookie. They then continue to start over and stuff more garbage into the fresh cookie.
That kind of problem solving pretty much made me lose faith in them successfully doing much of anything anymore.