back to article Revealed: The 25 most dangerous software bug types – mem corruption, so hot right now

On Tuesday, the Common Weakness Enumeration (CWE) team from MITRE, a non-profit focused on information security for government, industry and academia, published its list of the CWE Top 25 Most Dangerous Software Errors. These CWEs represent the most common critical weaknesses in software. They're bugs, design flaws, or other …

  1. karlkarl Silver badge

    Ugh with C++ (which is what most the world uses) this should be a solved problem.

    The issue is that so much code still relies on C (which is fair enough) but also ancient broken C++ with raw pointers or some amateur shite developed by a beginner (or python developer out of his element) who doesn't know what a smart pointer is.

    It isn't helped by the fact that a lot of C++ developers don't care about safety. Some libraries such as GLM even started defaulting to no zero initialisation of their math structures just for a little bit extra speed. This is great but should never be the default. GUI libraries are notorious for using raw pointers. Once you get a handle on a Button*, you have no idea if it is valid or not once widgets start to change. You have to rely on your assumptions which are not guaranteed.

    The standard library smart pointers also don't quite cover a lot of typical memory errors. For example it is very easy to get a dangling "this" in a large convoluted codebase. No-one seems to be really interested in fixing it.

    If anyone is interested; I drafted up a "safe" version of shared/weak and vector classes as part of my "sr1" prototype. You can also see a minimal test suite here for an example of some stupid errors that it protects against that C++ developers still make: https://github.com/osen/sr1/tree/master/src/tests

    The library is shite with multi threading. An older version had a global lock which was quite slow. Then I realised multithreading was inherently unsafe anyway so ripped it out and kept mutexes / semaphores as a manual exercise ;)

    1. cbars Bronze badge

      I may get down voted, but this is where Rust is trying to make gains. Sacrifice some techniques in pursuit of memory safety, seems a good tradeoff to me. Not everyone involved in programming has a compsci degree or even a numerate one. To solve a problem, you must frame it in reality: software will be written by people who are not 30 year experts with time and money to ensure fully robust routines. To solve that problem you cant say "dont have that problem", I think the tooling in Rust is top notch but I'm just getting familiar (coming from C++/Java background). Have a look, it's a mind bender at first but seems to be very well thought through. It's much easier to say: "use X", rather than: "use Y but remember a,b,c,d,e......". Rust wont be the final solution, but we've got to make tools and working environments safer, not people; like other industries before IT

      1. _LC_
        Stop

        Unfair C++ bashing

        Yes, you CAN do lots of things wrong in C++. You can even shoot yourself in the foot with BASIC, when POKEing around in memory.

        People seem to always point this out with C++, as if wrong programming practices would result in good code with a different language.

        Unless you are developing a library, hardware driver or writing embedded code, there is NO NEED (and it's deprecated) to access memory locations directly/indirectly. All those buffer overruns and the like come from people writing C code in C++. As stated before, you can do that. You can crap around in pretty much every language.

        It's not helpful that people who "never really got on the green side of C++" are promoting Rust now.

        1. Charlie Clark Silver badge

          Re: Unfair C++ bashing

          People seem to always point this out with C++, as if wrong programming practices would result in good code with a different language.

          Rinse and repeat for several languages. However, it is surprising that some of the problems are more prevalent in some languages than in others. So language design and choice do matter.

          Modern development environments and compilers do make it possible for higher level languages to produce the same compiled code but with fewer of the common, systemic errors.

          1. _LC_

            Re: Unfair C++ bashing

            It comes from people moving from C to C++ without changing their programming much.

            1. Anonymous Coward
              Anonymous Coward

              Re: Unfair C++ bashing

              I'm totally guilty of this, and end up smuggling it in under the guise of C++11 sugar.

              extern "C" {

              struct Foo; // fwd decl

              struct Foo *create_foo();

              void release_foo(struct Foo *pfoo);

              }

              using Foo_t = struct Foo;

              namespace std {

              template <> class default_delete< Foo_t >

              {

              public:

              void operator()(Foo_t* ptr) {

              release_foo(ptr);

              }

              };

              } // std

              std::unique_ptr<Foo_t> pfoo;

              // look ma, no leaks

              pfoo.reset(create_foo());

              pfoo.reset(create_foo()); // calls release_foo implictily

              There is just so much C code that works, has been already debugged, has tests.

              Slowly some of the better C++11 stuff is replacing my libraries, but, some older stuff is linked into code with multi-year uptimes.

              Conflicted.

              1. teknopaul

                Re: Unfair C++ bashing

                Rust seems good for this problem. It allows "unsafe" code to be wrapped with safe code interfaces. This way you can use tried and tested libs write the interface once (carefully reading the manual as you do so) and then forget about it from then on because the rust side of things is safe if it compiles.

                Rust is not comparable to C++, its C-like with a whole bunch of problems moved to compile time.

                1. diodesign (Written by Reg staff) Silver badge

                  "with a whole bunch of problems moved to compile time"

                  s/moved to/solved at/ ;)

                  C.

        2. DrXym

          Re: Unfair C++ bashing

          It's not a case of "you can do that in any language", it's a case of C++ makes it extraordinarily easy to screw up by mistake and won't mention the fact when compiling the code or when you run it. Hence the the reason there are so many CVEs related to NULL pointers, bufferflows, races, etc.

          And yes I suppose some languages might allow the equivalent of POKE (hearkening back to the days of the ZX Spectrum), and some programmer might determinedly go mad and use it but the absurdity of even making the comparison says it all.

          If I overwrite an array in Basic (or Python, Ruby, Javascript, Java etc.) then I would get a runtime error of some kind. The runtime caught the fact that there are no more elements in the array and complained about it and either threw an exception or stopped on the line. Annoying, but surely less so than silently doing nothing while the code becomes corrupted and/or exploitable.

          1. _LC_

            Re: Unfair C++ bashing

            That's why we use containers and iterators in C++. ;-)

            1. AndrueC Silver badge
              Happy

              Re: Unfair C++ bashing

              ..but you aren't forced to nor encouraged to. It's correct to say that you can avoid common errors in C++ by writing safe code. That's also true in assembler. It might be true in all languages. However some languages (like C#) make it difficult to screw up.

              In C++ there are several ways to create strings and to pass them around. 'char *' remains an option and unless things have changed in the last decade the compiler doesn't flag it as bad programming. For sure we'd hope that no currently active C++ developer would use it (or would least go with 'const char *' to signal their intent if not provide actual protection) but it's their choice. And if they are interacting with a third party library or OS API they might have no choice.

              But if you're working in C# you have to go out of your way to pass pointers to arrays around. Even calling third parties and API calls doesn't do that thanks to p/invoke in most cases. You might sometimes have to reach for the Marshal class but no-one does that out of choice.

              This isn't to say that you can't write dangerous code in C# (or other higher level languages) but at least the language and runtime make it a lot more difficult. You generally have to try to be stupid in C# whereas in C++ you just have to be careless, thoughtless or lazy.

              1. _LC_

                Re: Unfair C++ bashing

                This is because you can't write the underlying code (of their libraries) in that language yourself. This limits them very much.

                As stated before: C++ is not for bad programmers. It won't hinder them from doing stoopid things. I can't see that as a downside, however. Advertise Rust as a language for bad programmers then. This would be more honest. ;-)

                1. DrXym

                  Re: Unfair C++ bashing

                  I suggest you try Rust and see if you don't come out as a better C or C++ programmer from the other side. Because you would.

                2. AndrueC Silver badge
                  Happy

                  Re: Unfair C++ bashing

                  This is because you can't write the underlying code (of their libraries) in that language yourself. This limits them very much.

                  Does it? I've been developing software in C# for well over ten years now and I've never been limited. The main focus of the company I work for is capturing digital audio and directing it to someone (or something) that can transcribe it then directing it on to someone else to review it, then on to someone else who can dispatch or file it. We interact extensively with the Windows audio API, third party information providers, web servers (some we wrote ourselves hosted on Azure).

                  Our main product is the market leader and used by more than half of GP surgeries in the UK. I don't feel limited. I feel empowered. A small team (two of us for this particular project) have achieved what we have because of C# not despite it.

                  If you need to talk to the hardware or the operating system from C# there is almost always a Nuget package available that does that. And if not there's always p/invoke. I can call any Windows API function that exists and it's usually pretty easy and safe to do so.

                  C++ is a powerful language and in the hands of a good programmer is great for almost anything. Arguably it underpins a lot of software development around the world. But there's a world-wide shortage of programmers so we have to accept that a significant number of our breed are not good. Frankly some of us are rubbish. But the software needs to be written. C#, Java, Rust, Python all the modern, managed languages are a great way to address this problem.

              2. Baldrickk

                Re: Unfair C++ bashing

                Well... not always stupid to use raw pointers in C# - I once had an over 600% performance improvement.

                No wait. I meant 600x (60,000%)

                Achieved by moving from standard .net functions to raw pointer bashing - albeit in the small, single function that did all the heavy lifting in that application, with all the "unsafe" code being segmented away from the rest of the application.

                getPixel() and setPixel() are horribly inefficient for manipulating entire images, as each call sets up mutexes and similar operations, only to strip them down and make new ones in the next call. Far more efficient to set up a single mutex and do all you need in one go. This was a long time ago now, and there may be better ways of doing it now.

                As with all things, there is a time and a place. I agree that the managed nature of C# makes the usual raw pointer shenanigans almost impossible to do (I had to jump through a number of hoops to make it work).

                Likewise, I love python these days, and it's my go-to for a lot of personal projects. Sometimes though, people write modules in C, to then incorporate into their python programs, for performance reasons.

                Use the correct tool for the job.

                1. Loyal Commenter Silver badge

                  Re: Unfair C++ bashing

                  One would hope that the fact that any sort of pointer arithmetic in C# requires that you do it inside an unsafe{} block would at least make the programmer think about the safety of what they are doing. You can't, however, cure stupid, or indeed rampant copypasta from Stack Overflow without proper understanding.

                  The fact remains that humans are not infallible, even ones that are experienced programmers. After 20+ years in the game, I'm still finding that there are plenty of lessons to learn. The trick, of course, is in actually learning them. As for inexperienced programmers, well who can blame them for not yet having the mindset of "how can this line of code go wrong?" without the benefit of the wisdom that comes from experience.

            2. DrXym

              Re: Unfair C++ bashing

              Except for when people don't use iterators, and the compiler doesn't care. Or when they can't be used for the data being iterated. Or when they're cumbersome for the thing being done. Or when someone uses iterators incorrectly, e.g. two threads modifying the same collection or selectively deleting items from a loop.

              It's especially odd to even labour this point in an article that explicitly lists certain problems that languages C and C++ especially allow to happen as if it ain't no thang. And handwaving away cited issues with variations of "well if you did this other thing then it wouldn't happen". As if that magically makes things that can, do and will continue to do happen go away.

              1. teknopaul

                Re: Unfair C++ bashing

                You have to remeber when these languages were written. They allow things to happen because checking is slow. Not all abstractions are zero cost. Java designers presumed that synchronized would be fast enough in the future and made core classes like Vector synchronized. Many years later perf in a single thread still matters. I think there will always be a place for unsafe code in any language.

                1. DrXym

                  Re: Unfair C++ bashing

                  Concerning Vector, the funny part is that despite the claims it isn't thread safe at all. The individual methods might be thread safe but two threads iterating and modifying it at the same time can still data race it. So it's doubly bad for being slow and not doing what it claims to do. It should have been deprecated as soon as ArrayList was a thing and removed thereafter. I still recall my disgust programming J2ME which only had Vector.

                  Anyway I agree that languages are a reflection of the state of the art when they are created and bad decisions have a tendency to have a long lasting impact. We can see that in languages which have the concept of "null" to this day which is frequently described as a billion dollar mistake. Even though Java and C++ are trying to retrofit optional types into their libraries, the reality is that they will cursed with null issues for as long as they continue to exist.

                  1. _LC_

                    Re: Unfair C++ bashing

                    from: https://embeddedartistry.com/blog/2017/8/2/an-overview-of-c-stl-containers

                    Standard Container Thread Safety

                    I want to share with you some relevant points regarding container thread safety, as many embedded systems will likely require sharing objects across threads. The following general thread-safety rules apply:

                    All container functions are safe to be called concurrently on different objects of the same container type (i.e. it is safe to use two different std::vector instances on two different threads

                    All const member functions can be called concurrently by different threads

                    Containers can be safely read from multiple threads if no thread is making asynchronous writes

                    Different elements in the same container can be modified concurrently, except for the elements of std::vector<bool>.

                    If an object is written to by one thread and read by other threads, the object must be protected

                    In general, iterator operations read from a container, but do not modify it, so they are thread-safe

                    Container operations that invalidate iterators are NOT thread-safe, as they modify the container

                    The most important detail to keep in mind: if you are modifying the container in multiple threads, you will need to protect that container to prevent concurrent access. For more information using containers in a thread-safe way, see Implementing a Thread-Safe Queue using Condition Variable

                    Also, Boost provides a selection of lock-free container alternatives which you can consider for multi-threaded use cases.

                    1. DrXym

                      Re: Unfair C++ bashing

                      Containers in C++ are NOT thread safe. Being able to use separate instances of a container on different threads does not mean they are thread safe. Thread safe means access to the same collection from multiple threads is safe which is rarely the case and certainly not for STL. In fact you are compelled to protect them with a lock, e.g. a guard on a mutex to prevent data races from happening. Except of course C++ doesn't compel the programmer to do anything which is the entire point.

                      And yes there are some lock free containers out there but generally they are for queues where things are being taken off or put on the ends, not for random access for obvious reasons.

                      1. _LC_

                        Re: Unfair C++ bashing

                        That's what it says, doesn't it?

                        In fact, you don't want your containers to use mutexes when you're not multi-threading.

                        I myself, use templates to have even finer access to this. It allows me to choose locking or not, down at a function level.

        3. Anonymous Coward
          Anonymous Coward

          Re: Unfair C++ bashing

          "hardware driver or writing embedded code, there is NO NEED (and it's deprecated) to access memory locations "

          Deprecated by whom? I'm guessing you never done any network programming reading packets off a network device direct into memory to be accessed via pointers or mapped structure fields. In some areas , eg trading, milliseconds matter and traders won't thank you for giving them a load of waffle about streams and serialisation if they've just lost 100K because your code was too slow.

          Also good luck accessing shared memory without pointers.

        4. Tom -1

          @_LC_ Re: Unfair C++ bashing

          Most of the languages I used during my 42 years employed in computing (and those I've used in the 10 years since then) have reference to bounded buffers and don't permit the excercise of pointer arithmetic without automatically enforced bounds. It is simply false to state that pretty much every language allows you to crap around with the freedom delivered by C++.

          The inclusion of uncontrolled pointers from C in the C++ definition was crass idiocy - serious computer scientists at that time were fully aware of the pronblems/vulnerabilities that C++ inherited through this - and either the inventors of the language simply didn't care or were too stupid to realise what a mess they were making.

          1. _LC_

            Re: @_LC_ Unfair C++ bashing

            This simply implies that there are a lot of things you can't do with those languages then. Chances are, what they are capable of doing is only due to underlying C routines.

            This is a silly discussion. Nobody denies that you can shoot yourself in the foot using C++. You don't have to, as there are alternatives and more so - it's deprecated.

    2. Christian Berger

      Well the problem with C++ is...

      ... that people who use it think it's a high level language when it's in fact more of several layers of complexity above plain C. Since C++ is so insanely complex, members of a team will spend most of their time learning new features. The result is typical "beginner" code where someone tried to use a feature for the first time without fully understanding it first. This distracts people from writing good code as the amount of "thinking" they can spend on a given amount of code is constant.

      C has the same intrinsic problems as C++, but it's much simpler and much closer to Assembler. So if you know some Assembler you can spend more of your "thinking" to making sure your code is correct.

      Of course today what we need is a language with about the complexity of C, but with type checking and without the problems of making it to easy to include libraries.

      1. Electronics'R'Us
        Holmes

        Re: Well the problem with C++ is...

        The other problem with C++ is that older code (which may / probably still be in a production environment) would need quite a bit of work to compile under the newer versions.

        Would it be a good thing to update those older instances? Maybe, maybe not.

        I first started using C++ around 1994 and the language has changed so significantly in the intervening years as to apparently resemble each other while in reality it is now a completely different language. The sheer size and complexity of the language is an order of magnitude higher than C++ 2.0 - I will say that modern compilers are much better (very few compilers at the time were fully standard compliant).

        To see just how much has changed, take a look at these books (both by Scott Meyers):

        Effective C++ Second Edition

        Effective Modern C++ (Targets C++ 11 and C++ 14)

        There are a number of reasonable criticisms of C++ and even Stroustrup himself said "Within C++, there is a much smaller and cleaner language struggling to get out"

        I have no problem with many of those evolutionary items, but it is important to realise that many things we take for granted in C++ 11 / 14 / 17 simply did not exist back then and some things that were in the old version no longer exist or are deprecated to the point of effectively not existing.

        I moved to C (in 1982) from assembler (including hand assembled code) as I was doing embedded stuff (and still do). Very few (if any) of the programs I wrote in those days would not compile (albeit with warnings in all likelihood) in a modern C compiler.

        C++ is still a bit of a moving target.

        The power (and pitfall!) of C is pointers to a great extent; abstracting them might be a good idea but there are times where understanding what the code is doing at the hardware level is essential (and is one of the reasons that my bare metal code is written largely in C as it explicitly shows the pointers).

        I use C++ where it makes sense to do so; bare metal is not one of them.

        1. _LC_

          Re: Well the problem with C++ is...

          Even worse is the C casting. This is being(/has to be) used a lot in C. It's completely blind. If the type of the target changes (for whatever reasons), nobody will complain.

          This has been cleaned up greatly in C++. Most casts in C are not required in C++. The few you need are usually type safe and checked at compile time.

          1. Anonymous Coward
            Anonymous Coward

            Re: Well the problem with C++ is...

            The thing is, it's quite rare that you cast in C++, it's normally some bug if you need to cast.

            With the exception of a cheeky const_cast, most of my casts are static_cast as I declare conversion constructors as explicit.

            I think the uglier syntax of the C++ casts, does make it more visible that something is going on.

    3. Anonymous Coward
      Anonymous Coward

      You're right. One of the biggest issues in C was the lack of a native sting type properly managed. The resulting mess of manual buffer allocations and pointer operations just to print "Hello World!" lead to a lot of hidden bugs. Any language with a sting type reduces a lot the need to use pointers but for very specific operations many applications don't need.

      Yet, C++ with its ill-designed resource de-allocation method, which didn't took into account the needs of actual applications but look designed for far older ones, forces developers to play with "smart" pointers in the attempt to work around that, with the result many developers return to square one or face unexpected issues.

      Being able to allocate and manage memory manually can be very useful when it's the simplest and quickest path for a very specific task, but shouldn't be the norm and should be reserved only when using other methods becomes quickly very cumbersome and slow. In any other situation, the language should offer safer ways to manipulate data.

      1. Anonymous Coward
        Anonymous Coward

        But what happens when you need performance, too, because it's going to be used heavily? That's one reason for C's "to-the-metal" approach, IIRC, as garbage collection necessarily eats into performance in a world where it can be at a premium.

        1. _LC_

          Re: But what happens when you need performance

          You have the same issues in every language. For that you will then need a (thoroughly tested) library, which does that "magic" while being fool-proof to use.

          C++ has the advantage of having "templates" here. This means that you can use thoroughly tested code WITHOUT any negative performance impacts.

          1. Rich 2 Silver badge

            Re: But what happens when you need performance

            "...For that you will then need a (thoroughly tested) library..."

            And where do you get such a library when what you are writing is unique to your application? Before you know it, you'll end up importing zillions of libraries just so you can use a little bit of something from each of them. You'll end up with a massive executable, which consumes enormous resources.

            If you're not careful, you'll end up in the realm of scripting languages like perl and python, which while useful, can quickly become very resource hungry.

            1. _LC_

              Re: But what happens when you need performance

              Not having such libraries is even more likely for other languages. In fact, when it comes to high performance the air becomes very thin.

      2. Christian Berger

        The de-allocation method wouldn't be a problem as such... if they didn't have weird stuff like implicit object copies which can, if you aren't super carefull, cause 2 "copies" of an object have their members point to the same memory locations, paving the way to use after free and double free.

        Pascal, for example, doesn't have that, the destructive assignment operator := does not copy objects, at best it copies references to objects.

        1. Rich 2 Silver badge

          "...if you aren't super carefull, cause 2 "copies" of an object have their members point to the same memory locations..."

          That's where custom copy constructors and custom copy assignment operators are for!

          1. AndrueC Silver badge
            Happy

            ..true. If know about them and how to write them.

            With languages like C# and Java it's a lot harder to write bad code. If code compiles it's almost certainly safe to run. As long as programmers are human and prone to human mistakes there will be value in languages that protect them from themselves.

            1. Anonymous Coward
              Anonymous Coward

              That's simply incorrect.

              What we are doing is elevating memory handling as some special resource.

              The lack of destructors or deterministic finalisation causes all kinds of awkward code.

              Probably the best feature of C++ is the support for RAII, and the resulting ability to make life-cycle management declarative, or vanish entirely.

              Swapping that for GC, is not a good trade off.

              Have GC, but enable RAII or be doomed to reinvent it for every application.

              Also, if I don't care about memory, why do I have to specify how my gc works as part of deploying my application to the JVM.

              1. AndrueC Silver badge
                Meh

                Re: That's simply incorrect.

                I'll agree about RAII although I've got used to not having it now. C# has using{} which is almost RAII. It's not needed often but at least it avoids any ugliness where hierarchical init/teardown is needed. I haven't given any thought to GC or memory use for a long time. Of course that might mean that all the applications I work on fall over eventually but that appears not to be the case. Least-wise we have web servers that have been running uninterrupted for months and our desktop applications seem able to stay up for a couple of a days. We don't really need them to be 24/7/52 as for most of our customers if our application will survive the working day that's plenty good enough.

                1. Anonymous Coward
                  Anonymous Coward

                  Re: That's simply incorrect.

                  I actually think that memory usage is less important now, as even if you are leaking, it's reclaimed on process exit by OS.

                  The issue I have is that using / try finally and analogues, require you to remember to use them.

                  You can of course forget to release something in a destructor, but generally speaking you can't force the destructor not to run [1].

                  [1] It's c++ of course, you can force the destructor to not run, as you need to invoke it directly when writing custom allocation strategies (e.g. placement new, or generalised unions), but if you are writing that code, you *should* know what you are doing.

                  1. AndrueC Silver badge
                    Boffin

                    Re: That's simply incorrect.

                    The issue I have is that using / try finally and analogues, require you to remember to use them.

                    Absolutely, that's why I don't consider C# using{} to be true RAII. Looking at our main code base of just over 4,000 files and nearly 17MB of source we've used finally 24 times. We've apparently used using{} 365 times (which seems surprisingly low).

                    I fell in love with RAII when I was a C++ developer and still miss it for complex resources. However what I do like about C# is the way I can pass classes into and out of methods without having to worry about who owns them or will dispose of them.

                    C++ has boost::share_ptr but now it's the C++ programmer who has to remember/choose to do something extra. There's no way I can search our source for all the places where we throw classes around but I bet it's a lot more than 365 times so on balance we've gained more from being able to do that than we've lost in having to remember to use using{} or finally{}.

                    But it's all swings and roundabouts. This is why we don't have (and shouldn't have) one language to rule them all. In other post someone replied to me pointing out that the .NET framework was probably written in C++. And that would be an excellent choice for such a project. It's efficient, powerful and performant. The people writing that code will be highly skilled and knowledgeable C++ developers and are thus a lot more likely to do things properly and safely.

                    It bothers me that some of the posters here seem to be thinking in terms of either/or. As if praising a feature of C# means that C++ should be dropped. I certainly mean no such thing. I'm simply highlighting one aspect of a certain class of language (managed) that I feel is a significant advantage over another class of language (unmanaged).

                    That doesn't mean that C# is on average better than C++. That's a pointless and dangerous way of thinking. It just means that if you are planning a new software project you should be aware that different languages have different strengths and you should feel free to pick the most suitable language for the task and for the staff you have available.

                    One thing I miss from C++ is the templates. C# has generics but it's a different way of thinking. In some ways they are better because we get full type checking. But in other ways they are worse because they require that you're working with a common 'ancestor'.

                    In C++ a template can be defined to call Wibble() on its specialisation and it will work with anything that has a Wibble() method. C# generics don't allow that unless you resort to reflection in which case a pox on you. Reflection is powerful and good but not as a way to implement a 'template' :)

                    1. Anonymous Coward
                      Anonymous Coward

                      Re: That's simply incorrect.

                      I agree different tools for different jobs.

                      If I'm going to throw together LoB applications to front a DB on windows. C# is an excellent choice for that.

                      But for software that is going to be long lived, bolting oneself to the .NET/CLR is troubling.

                      In terms of ownership, that's a design issue. The truth is that not all sw needs to be efficient, bug free, or be capable of running without crashing for more than 24 hours.

                      For that class of sw, which frankly includes a lot of glue code / build scripts, LoB applications etc.

                      I don't see much advantage to doing development in a statically compiled system programming language. I personally (showing my age now) thought that being able to slap a VB GUI on a C DLL was a great improvement over writing everything in C using Petzold as a reference.

                      1. AndrueC Silver badge

                        Re: That's simply incorrect.

                        But for software that is going to be long lived, bolting oneself to the .NET/CLR is troubling.

                        Somewhat, yes. Right now I'm still struggling to get my head around the .NET Core, .NET Standard mess. We've had to move a couple of projects twice. To be fair the moves weren't particularly onerous but it does my 'ead in.

                        https://www.infoq.com/news/2017/10/dotnet-core-standard-difference/

                        1. Anonymous Coward
                          Anonymous Coward

                          Re: That's simply incorrect.

                          Take comfort it's not as bad as the web ecosystem.

                          I present rails diff, yes, you literally have to diff the framework to figure out how it broke your code *this time*.

                          http://railsdiff.org/

        2. Anonymous Coward
          Anonymous Coward

          It's not weird, it makes sense, eventually.

          There is a system model provided by the language, so that people have a chance of writing a conformant compiler and runtime libraries.

          In that model, a copy should never be implicit, you either intend that copy to be safe, or you prohibit that copy.

          e.g. class Foo: public boost::non-copyable {};

      3. DrXym

        I should point out C++ doesn't have a string type either. It has a string class in the C++ library (plus a gazillion other string types in other libs) but it isn't intrinsic to the language. It's just a wrapper around a char * or another char type.

        The biggest issue with strings in C (or C++), is they are terminated with a null byte. Way back in time this seemed like a great idea because it simplified pointer arithmetic and issues in Pascal using strings with a length byte. But you can overwrite that terminator byte or neglect to append it and then you can run into trouble.

        If you forget to zero out your buffer before strcpy'ing a string, or forget to make the buffer big enough for the extra byte then you can run into trouble. I wonder how many issues were caused by allocating space for strlen(s) instead of strlen(s)+1... C++ mitigates to a large extent by emphasizing using the std::string but it's still very common to need to use the raw pointer from one of those, and the type itself can thrash heap if you're not aware of how it stores a string internally.

        1. Jim Mitchell

          It is not like string implementations in other languages don't use pointers. In the end all code is pointers to data and pointers to itext. It is all just bits in a bucket. Some buckets have lids, some don't, some have holes in the bottom, some have plugs that fall out...

          1. DrXym

            Try trashing strings in Java and see how far you can get with attempts to crash it. Oops you can't because strings in Java are immutable. The point being some languages shut the door on potential programming errors in their design while others don't.

            1. teknopaul

              The door is a-jar (gedit)

              Java has jni. You can trash a String easily. I found such a bug in Google's Snappy compression lib.

              I thought I'd get bug bounty since it was an out of bounds read. They refused to even fix it, with an RTFM in the close comment.

              1. DrXym

                Re: The door is a-jar (gedit)

                By definition if you're using JNI then you're throwing the safety switches on the language. Same deal if you call C bindings from Perl, Python, Ruby, NodeJS, Rust etc. Even C++ if you hand the contents of a std::string() to some random C function - you're trusting yourself to be passing the right buffer to the thing on the other end and for the thing on the other end to abide by the contract of its interface.

                Interestingly enough the only ever crash I had while developing in Rust was for the same reason. I called OpenSSL specifying the wrong length on a param and it blew up. A single crash in three years.

        2. _LC_

          The std::string class can return a null-terminated string for you. This is guaranteed to work (no memory allocation). You can test the string for emptiness in various ways. The string class stores the length.

          You are basically criticizing C and blaming this on C++, as you are talking about C interfaces. You have to feed those interfaces the same way from Pascal; no difference there.

          Since C++17, there's also the std::string_view class, which is a "low cost" wrapper to keep arrays safe, even C strings.

          Again, you can do things wrong if you want, but only if you ignore all advises.

          1. Anonymous Coward
            Anonymous Coward

            std::spaceship

            Have you come across std::spaceship, I'm not sure if it's an argument for or against c++

            https://en.cppreference.com/w/cpp/language/default_comparisons

            1. _LC_

              Re: std::spaceship

              It's one for. This is for writing containers and not duplicating all the comparison operators. As a user you will not come in contact with it.

              1. Anonymous Coward
                Anonymous Coward

                Re: std::spaceship

                Was tougue in cheek question, I think it's a good thing.

                But I'm mostly on 11/14 at $GIG, so filesystem is still boost, as not std from cpp17.

                Why would I not come into contact with it as a "user", rather than "stl developer?"

                It's about reducing the boilerplate from having all the relational operations back onto an underlying compare. Surely I'll use it every time, I need a custom comparison operator?

                Am I being dense?

                1. Anonymous Coward
                  Anonymous Coward

                  Re: std::spaceship

                  Lucky you. At my ${GIG}, we aren't even up to C++11. Arrgh.

                  1. Anonymous Coward
                    Anonymous Coward

                    Re: std::spaceship

                    Oh that's painful.

                    03 is like pushing rope, okay quite a bit I can get from boost (smart ptr/thread/filesystem/bind)

                    But 11/14 is so much nicer.

      4. Anonymous Coward
        Anonymous Coward

        " The resulting mess of manual buffer allocations and pointer operations just to print "Hello World!" "

        Really?

        int main()

        {

        puts("Hello world");

        return 0;

        }

        Where are the pointers and memory allocations exactly?

    4. Lee D Silver badge

      If you have a program written by someone who can't count, index an array or stay within memory bounds, then the language really isn't the problem.

      It's a good fail-safe. A barrier to hit while testing. Something to safeguard completely accidental escapes. But if you're allocating 1000 bytes and then putting 2000 bytes of data into it, without properly checking, then the problem lies with the programmer - maybe not their inability to be infallible, we all are, but certainly their ability to use tools available to them, to properly factor out their code so that sizing/allocation/etc. is always tested for bounds checks, to program in a safe way, audit their code etc.

      I'm not at all sure "just use a language that doesn't have that" fixes that problem - you can still off-by-one on an array index and splat some guy's details to some other customer, while staying completely within bounds, for example. If you had a check that the row index was as expected and correlated to the web session / customer accessing it, then it wouldn't matter if you messed up. It would flag and get fixed.

      When you have a programmer who doesn't have, or isn't allowed to use, tools that prevent such occurrences in the first place, then the language is only one failsafe that you've inserted. They are still liable to fail because of their operational procedures.

      When you have a programmer who has their own tools, bounds checks, macros, sanitisers, code-checkers, whatever, and it goes through him and others, and testing, and bug-reporting, etc. then the language is irrespective and just "another" tool in the armoury.

      Writing stuff in another language which cannot express "this memory byte" doesn't solve the problems with a sloppy programmer who isn't checking, designing their entire method safely, or not verifying their work.

      Sure, he won't get a memory buffer overflow. But it also means that he's just as likely to miss other things because he doesn't have to worry about memory buffer overflows, so he's just not as careful.

      More usually, you then see things like huge memory over-use because they just want everything in a memory-safe object permanently in memory all the time and let the computer worry about when to get rid of it (if it ever safely can!). I'm pretty sure that explains a lot of the "drag" of the memory-safe languages - a complete lack of understanding of the memory size/usage/management.

      Like every Java program I've ever seen, .NET, etc.

      1. Aitor 1

        Airbags

        We put airbags, pretensioner seatbelts, and crumpling zones in cars because we humans make mistakes. A car with active and passive security deatures is safer, even if it weights more and burns more fuel.

        For the same reason, using programking languages without safety features seems.. well, dangerous, and statistics are clear about the results of such practices.

        We would certainly need some low level programming, but we should try to balance the risks.

        1. DrXym

          Re: Airbags

          Exactly.

          Even in C++, the use of safe(r) types or programming practices is entirely optional and even someone knowledgable and striving for safety can still screw up and the compiler really doesn't care. Often the safe(r) code is so hideously clunky, complex and/or nuanced that people take shortcuts in their code to avoid it which has the same effect.

          And programming skills are across the spectrum. So the reality is that many bugs slip through and part of the blame lies with C++.

          That's the reason that Rust is getting such attention at the moment. Things like null pointers, double frees, buffer overflows, data races etc. are caught at compile time or runtime before they develop into exploitable attack surfaces and without compromising on runtime performance.

          1. technovelist

            Re: Airbags

            C++ is not to blame for the fact that a lot of people are unable to write good C++ programs. It is certainly possible to do so, and it can provide performance that is unavailable in "safe" programming languages.

            So if you aren't a very good programmer, maybe you should use another language... or learn to be a better programmer. But blaming C++ isn't going to help.

            1. This post has been deleted by its author

          2. Anonymous Coward
            Anonymous Coward

            Re: Airbags

            Things like null pointers, double frees, buffer overflows, data races etc. are caught at compile time or runtime before they develop into exploitable attack surfaces.

            The pointer related ones are failure to use smart pointers, double free is just not something that happens in correct code.

            The data races, is a flaw in design, and as such is language independent.

            The only correct thing in concurrent code, is do modification off to the side, and atomically swap into place. That will work in every language, even if you have to contort the "swap into place" part.

            The buffer overflow, is failure to use an appropriate container, e.g. a std::vector<char>

            I think that using system programming languages for general purpose programming is unwise.

            Write in a scripting language, plugs small part of the system via an RPC transport into native code.

            Alternatively if you need a systems program, then every piece of control you give up, makes it less likely that people will avoid C and assembler.

        2. NickHolland

          Re: Airbags

          Some time back, I remember seeing an article somewhere which indicated that when airbags first became standard, auto injuries and fatalities fell off. And then people started feeling immortal and protected by airbags, and started driving more like idiots ("The airbags will save me!"), and the injury and fatality rate went back up.

          Programming languages with a high barrier to entry demand skilled programmers. But they make stupid mistakes. Programming languages which protect against mistakes seem to lower the barrier to entry so that everyone thinks they are a programmer, and we get modern software.

          I don't know what the answer is. But I'm pretty sure it's not simple.

      2. AndrueC Silver badge
        Meh

        If you have a program written by someone who can't count, index an array or stay within memory bounds, then the language really isn't the problem.

        Meanwhile, back on planet Earth.

        These are extremely common problems and if you are trying to imply that no-one should employ a programmer that has or can fall victim to such a mistake then you're going to severely limit the pool of potential employees. Given that the world has a long-standing shortage of programmers of all abilities that doesn't bode well.

        I'd also suggest that if you're attitude to a problem is 'we shouldn't employ stupid people' then you have a management problem. When you write code I /assume/ you include safeguards. Code that detects when things are not right and that acts to protect the system. Well that's what managed languages are doing.

        And they are doing it more cheaply. There's a maxim in software development (all forms of engineering probably) that the sooner you catch an error the cheaper it is to fix it. Well you write code to detect and guard against out of range errors. Good. But some of us are using languages that don't let us (or discourage us) from making such mistakes in the first place. That's better because it's cheaper not to make a mistake than to detect and correct it.

        More usually, you then see things like huge memory over-use because they just want everything in a memory-safe object permanently in memory all the time and let the computer worry about when to get rid of it (if it ever safely can!). I'm pretty sure that explains a lot of the "drag" of the memory-safe languages - a complete lack of understanding of the memory size/usage/management.

        Memory is cheap and modern OSes page to disk anyway. For most applications the fact that a program would eventually die from memory mismanagement after a week is unimportant. Most applications rarely run longer than the working day anyway. And if developed with a managed language if the application crashes..meh. The users swears cracks a joke with their colleague and starts it up again. No real harm done.

        Most applications don't have to be particularly robust, nor particular performant. They just have to not corrupt themselves or increase security risks to the system. Writing all software to the kinds of standards you advocate would cripple the industry. There aren't enough programmers of a high enough calibre so you'd just slow down the pace of innovation to a crawl.

        1. Anonymous Coward
          Anonymous Coward

          C++ will protect you from errors if you use it correctly.

          std::vector<char> foo;

          foo[0] = '1'; // segfault as out of bounds index.

          foo.at(0) = '1'; throws std::out_of_range_exception as out of bounds.

          How is that unsafe, you chose to use the unchecked variant, to save a whole three chars '.at'.

          You get the speedup, but it assumed you did the check already.

          Or you don't check and you call the checked variant, e.g. vector::at()

          What am I missing?

          1. AndrueC Silver badge
            Boffin

            C++ will protect you from errors if you use it correctly.

            Yes, we know. But the point some of us are trying to make is that other languages protect you either if/when you don't use them correctly or by simply not allowing you to do stupid stuff. And programmers are human. We don't always do things correctly and we sometimes do stupid stuff.

            In C++ it is easy to copy data off the end of an array. You might not notice you're doing that for a long time since most RTLs sub-allocate large blocks and running off the end of one array might not cause an access violation if the addresses lie within an allocated block of memory. You are free to trample on any areas of memory that belong to your process.

            And std::vector doesn't prevent you using memcpy. You can memcpy() with a std::vector as the source and/or target without any comment from the compiler or RTL,

            But in C# for instance if you supply Array.Copy() with bad ranges you'll get an exception and the code will safely stop. There are ways to do an unsafe array copy in C# but they are esoteric and by design are a pain in the bum.

            As I've written elsewhere: I'm not trying to bash C++. But its proponents ought at least to understand that other languages have better protection and therefore they should consider using those languages where the efficiency and performance of C++ is not a requirement.

            1. _LC_
              Facepalm

              Consequently, your vision for an optimal programming language corresponds to a set case for toddlers.

              "In C++ it is easy to copy data off the end of an array."

              That's like saying that it's easy to stick the fork into your eyes. Not the common use, I reckon.

              "You can memcpy() with a std::vector as the source and/or target without any comment from the compiler or RTL."

              No kidding, it's a C function. ;-)

              "There are ways to do an unsafe array copy in C# but they are esoteric"

              Ah, stoopid people are not into esoteric, I get it...

              Besides, instead of doing array2 = array1, using memcpy for copying arrays is not crazy???

              "other languages have better protection"

              And there we are again in the crawling box. Consequently, the code your language calls "behind the scenes" is typically written in C/C++.

              1. AndrueC Silver badge

                Consequently, your vision for an optimal programming language corresponds to a set case for toddlers.

                No! The optimal language is the one that is best suited for the task in hand. I will make my choice based on the requirements and the staff available to me. You appear to be blindly tied into C++ and that's not good.

                1. _LC_

                  I can do "everything" with it.

                  I see others starting of with a project and that very project becoming bigger and more versatile, until they hit a barrier. Then they - all of a sudden - have to stitch up something terrible, just to keep their project going. Those solutions are often "a turd" out of the horror-cabinet of programming, falling apart when an atom shifts in the wrong direction...

  2. Anonymous Coward
    Anonymous Coward

    These are basically all old hat

    I remember all the same bugs in the 90s. Back then it was internet daemons like sendmail that had the issues. After years of painful work they fixed all[*] those bugs, but every internet/smartphone user 'touches' orders of magnitude more lines of code every day than they did in the mid 90s so even if the security hole per line of code ratio is better today (and I'm not convinced it is, but even IF) we are in much worse shape now than we were then. We'd basically have to halt all software progress for five years just to fix everything they way they did with sendmail, and what then? Start writing new stuff and making the same old mistakes again, no doubt.

    [*] well at least I haven't heard about a sendmail exploit in a long time, but let's just say it is WAY better than it was in the early 90s.

  3. Michael H.F. Wilkinson Silver badge

    Not at all surprised to see CWE-119 at the top. Many modern languages have proper bounds checks, but a lot of old C code won't have that in place. Alternatively, people switch on bounds checking during the testing phase of code, and once the bugs have "all" been ironed out, switch it off in the production version, to increase performance. All well and good, until someone makes some "harmless" change in another piece of code in the package, or fails to set up the right preconditions when calling the code, and you are back to square one. Safety and speed of the code (both in development and run time) are often at odds with each other.

    1. Primus Secundus Tertius

      @MHFW

      You are spot on about 'some "harmless" change in another piece of code'. I had to deal with some free() statements that had been a long way away from the original malloc() statements. Then some 'upgrade' removed the malloc code but forgot the free code.

      I concluded that a lot of programmers never really understood pointers.

      1. Baldrickk

        I go out of my way to try and keep any memory allocation tied to the relevant deallocation for this reason.

        I try and avoid it entirely where possible too - at least when I need to manage it. Scoped variables, RAII, smart pointers and container libraries are all your friends.

        1. technovelist

          My rule is never to use raw pointers other than in library classes that manage the data and lifetimes thereof. Application code should not use them.

          1. Anonymous Coward
            Anonymous Coward

            Raw pointers

            If you religiously use smart pointers, then a raw pointer becomes a "non-owning weak pointer"

    2. Baldrickk

      OOF. Always build two versions, debug version with all the checking turned on for testing, and a release version with optimisations enabled for actually running.

      Just because you may want it removed for performance in the product that ships isn't an excuse for not doing the testing.

      1. Anonymous Coward
        Anonymous Coward

        Isn't that the worst of both worlds because now you have to continually sync between them (because say you forgot to port something important), where something can get lost? It should be better to keep them all in one package but with debug-only/production-only code kept in conditional precompiler blocks? At least here it's only one block of code to peruse.

        1. _LC_

          Sometimes it is as simple as setting different linker options (which you do anyhow). There are debug versions of the std libraries. Among other things, they spit out garrulous warnings when you access elements out of bounds and such.

  4. RichardB

    In short...

    be careful what you stick in it.

    be careful what you stick it in.

    respect boundaries and limits.

    somethings aren't what you think they are.

    1. Anonymous Coward
      Anonymous Coward

      And some environments can't be planned: such as trying to process a raw datastream with no predictable bounds.

      1. _LC_
        Alert

        Oh but it can

        Oh but it can, by letting it being handled by a process with limited access. You then only take a "clean" (= well-defined) return and operate on that. Thus, even if your input manages to corrupt the process that is processing it, it will find itself in a cage, unable to escape or do anything harmful.

        This is common programming practice in high security environments.

        1. Anonymous Coward
          Anonymous Coward

          Re: Oh but it can

          But even high-security environments require a certain level of trust; otherwise, Things Don't Get Done. What happens when you MUST have higher access as part of the work process?

          1. _LC_

            Re: Oh but it can

            You delegate the work to an unprivileged process and retrieve a "clean" result in the privileged one.

  5. This post has been deleted by its author

  6. Raedwald Bretwalda
    Boffin

    Several of those top problems can be completely avoided by using a better programming language or third party libraries.

    The "Improper Input Validation" problem, however, is tougher. Coding proper input validation for non trivial cases (such as string to integer) is tough. There might be only one correct format for an input, but there are many ways it can be incorrect. When I write (TDD) test cases for input validation code, in almost all cases I need considerably more (an order of magnitude more) test cases for the classes (equivalence partitions) of incorrect inputs. Getting junior, less disciplined or rushed developers to put that effort in is not easy.

    1. _LC_

      See my post (reply) somewhat above this

      ^

      |

      there

    2. Aitor 1

      re inventing the weel.

      What aboit using well known and understood libraries/frameworks for this? I a quite keen on using standards for these things, as more people have looked at the problem, and if there are problems, it has greayer chances of being detected.

      So, essentially, the same reason you should not use your own random number generator or cryptography.

      1. Richard 12 Silver badge

        Re: re inventing the weel.

        A lot of input validation is domain-specific.

        "Enter an integer between X and Y" will have a validation library you can use, but not "except if $other_field$ is Z" and many others don't.

        "Enter a valid string" doesn't have a general solution, thus no general libraries. The permitted codepoints and sequences vary greatly depending on the purpose and current system state, and being "too strict" can cause further problems too. (esp. if there are multiple places to enter the same data.)

        Eg "Enter surname" fields often refuse to accept spaces or even anything outside Latin1, despite the fact many surnames do contain spaces and non-Latin1 characters. And some people don't have surnames at all...

  7. Cuddles

    Not all that different

    Although they split them into different categories, an awful lot of these boil down to simply checking your input properly. Are "Input validation on a website", "Input validation with SQL" and "Input validation" really different types of bug (and there are more of the same in the full list? Quite a few of the others seem to be just different ways of saying "Privilege management" as well. Sure, there can be different ways of making these mistakes depending on the systems involved, but in a general list of the kinds of mistakes people make it doesn't make much sense to split them all up.

    1. Charlie Clark Silver badge

      Re: Not all that different

      Splitting them up does make sense because they're very likely to occur in different contexts.

      Validation on a website is really important UX for the user who needs to be told as quickly as possible if they've missed something important out or got something wrong. Ideally, this is done client-side before a screen refreshes and this has been impoved significantly by HTML5. It's just such a pity that browsers took so long to properly implement the new controls.

      You do then need to do sanity and sanitary checks: is this a bot.

      SQL injection itself should really never happen as a result of client code. Parameters should always be passed separately. This is not to say that things don't go wrong, because they do, not least because passsing the parameters separately simply makes it the DB's job to do the checking. But any code that hands data off to another system: DB, network, app, also needs to make sure it follows the API correctly as this is where errors are likely to be most serious, leading to the privelege escalation you mention.

      In many situations it's possible to find that the code itself was all correct but exploits were still possible. Hard to think of a better way of learning about this than seeing it happen to your own stuff.

      1. Loyal Commenter Silver badge

        Re: Not all that different

        SQL injection itself should really never happen as a result of client code. Parameters should always be passed separately.

        Indeed this. I can think of only three situations where SQL injection may occur:

        1) The programmer is inexperienced and doesn't know that (s)he should use parameters. Solution: get them some training and fire their manager.

        2) The programmer knows they should use parameters but is not (possibly due to laziness or general ineptness). Solution: fire the programmer.

        3) The RDBMS in use doesn't allow parameters in the SQL statements. Solution: stop being a cheapskate and use a proper RDBMS that was written this century*. Also, fire the manager, AND the programmer for not doing things properly in the first place.

        *I accept that there may be situations where for complicated reasons, it is necessary to support legacy software that doesn't have modern features, or allow for them. In this case, consider firing the company directors as well.

        1. Charlie Clark Silver badge

          Re: Not all that different

          And even if there are situations where you can't pass parameters separately, not come across this personally, sanitisation and quoting should be handled by a separate, testable and tested library, preferably from the relevant DB.

          If you do write your own sanisation code you must assume it is broken because it's axiomatic that you'll never be able to dream up the crap that users will enter and that's before the hackers even get started.

          1. Loyal Commenter Silver badge

            Re: Not all that different

            It's worth pointing out, that for MS SQL Server at least, there is only one character you need to escape in strings to sanitise the input (the single quote, ', escaped as a double single quote, ''), so writing a library to sanitise thm isn't the hardest thing in the world.

            Of course, this only sorts out SQL injection via strings. Depending on the langauge you are using, it may be possible for strings to be passed in palce of numeric data, and you'll still need to make sure the strings you're given fit into the columns you're trying to squeeze them into, not to mention be careful about how you use the data once it's in the database, but the point here is that SQL strings are easier to sanitise than things like format strings, or things that have more exotic escape sequences like XML.

            If you're tempted to think, "OK, well, I'll just sanitise my strings and not use parameters", however, stop right there. There's a definite performance hit to doing so (calling a subroutine to process every string before interpolating it into a SQL statement). Use parameters. It's what they're for.

  8. Tom Paine
    FAIL

    Which is it?

    [MITRE published] its list of the CWE Top 25 Most Dangerous Software Errors.

    These CWEs represent the most common critical weaknesses [..]

    Most dangerous, or most common? And should we be alarmed that MITRE apparently don't know the difference?

    1. Aitor 1

      Re: Which is it?

      Most dangerous I would say are side channel attacks.. as I dont think they have a reliable way of detecting most dangerous I would think it is most common.

    2. Baldrickk

      Re: Which is it?

      Despite being different, I'm fairly certain that there is a correlation.

      Severity being a measure of both impact and frequency. Low impact but often can be as bad as a single catastrophic instance.

    3. Loyal Commenter Silver badge

      Re: Which is it?

      There is a difference between risks and hazards.

      A hazard is something bad that can happen, such as, for instance, your data centre catching fire (a big hazard).

      A risk is the chance something will happen, such as, for instance, the probability of your data centre catching fire (hopefully, a tiny risk).

      The danger (or impact) is the product of the two. Note that humans tend to overemphasize the impact of rare hazards and underemphasise the impact of common hazards (the classic example is deaths from terrorism vs deaths from road traffic accidents).

      Given that with software bugs, the severtiy of the hazards are all pretty much the same (compromise of a computer, or compromise of data), then the impact is going to reflect the frequency quite closely.

  9. Will Godfrey Silver badge
    Facepalm

    A steep learing curve

    That's what I had quite some time back when writing a timetabling program for a local primary school. It wasn't the kids trying to mess up the program, it was the clueless teachers who were typing all sorts of rubbish, and even trying commands from a quite different piece of software.

  10. Anonymous Coward
    Anonymous Coward

    And, yet, in 2019...

    I'm asked to participate in user acceptance testing of a new corporate web tool to automate some sort of ERP crap, like maybe sanitizing phones.

    I'm bored waiting for the roomful of people to log in, so I mouse over to the first input field and hold down the space bar for a minute plus. BOOM. Back end crashed. Bounds check?Anyone? I don't know who was more shocked- me that it was so easy or the developer rep who suddenly had a lot of talking ahead of him

    1. Jens Goerke

      Re: And, yet, in 2019...

      BTDT back in the 90s when testing a new web chat system that didn't crop/constrain the user's input and promptly crashed the user's session with error messages in every HTML-frame it had open.

      PHB's reaction was: "Nobody types that much text!", so it went into production.

      Same thing happened with the next version, so I didn't participate in further testing - no use reporting a bug that won't be fixed.

  11. Crazy Operations Guy

    We need the time to do it right

    In my experience, the vast majority of code bugs come not from incompetent programmers or problems with the languages, but programmers forced to ship code as soon as it does what is needed of it, rather than doing what is correct. Like most of the buggy code I've encountered has been from competent programmers under unreasonable deadlines being forced to ship less-than-acceptable code. Thats not to say there aren't incompetent programmers, just that they aren't the only source of bugs.

    I used to be a developer in a company that made industrial / office automation systems, but then shifted to home automation. Before the shift, we would write quick-and-dirty code that technically worked, but we'd take the time to go back over it 5-6 times, making it better and cleaner each time. After the shift, the new management started reducing the number of iterations until one day we were just shipping our first draft versions. Our development cycle became longer and longer with each version we shipped because more and more of our time was spent trying to write new stuff -and- fix/work around flaws we made in the previous version. But, management kept imposing the same deadlines on us (Prototype for CES, release for Black Friday). We went from shipping the rare patch to deal with other manufacturers' devices not following their released specs to issuing monthly batches of patches with some emergency patches thrown in as well.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like