Talk:Defensive programming
This article is rated Start-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | |||||||||||
|
Random notes
edit...copied from article, "Please expand this article. These random notes should be changed to a more coherent article." Badanedwa 22:52, May 1, 2004 (UTC)
humm
editThis article its somewhat obsolete-ish, and feel too unix oriented. Maybe sould be edited to leverage this unix oriented style, then adding nowdays-sche stuff. Ok, maybe I am wrong. What other people think about the quality of this article? --Tei 15:09, 19 July 2005 (UTC)
I agree that this article needs cleaned up. - brenneman(t)(c) 05:24, 6 August 2005 (UTC)
Bug Free
editHow does Defensive Programming differ from Standards of Good Software Development? Now I have been a computer programmer for over 40 years and fully agree that there is an enormous volume of crud out there, as we can see with the volume of patches coming from major software suppliers to fix problems that should never have been there in the first place, but most everything I am seeing in this article is talking about standards that most every programmer should adhere to, with variations on how to implement them by actual computer language, but few do. User:AlMac|(talk) 18:11, 18 January 2006 (UTC)
I do NOT adhere to these rules
editI see defensive programming a method that can be used when it is reasonable to both expect and possible to counteract intentional and accidental misuse of the code. The problem is that it is easy to hide the problem without alerting anyone about it. I it a design choice among others. Another approach if defensive programming is not used is to let the application crash, or in some other less drastic way make the call invalid. In other words enforce the correct use of the piece of software in question.
The idea that defensive programming is good programming is wrong, but one way of designing the code. The question is how to define the term properly. —Preceding unsigned comment added by 137.61.234.225 (talk • contribs)
- You didn't specify the programming language you use. In languages where an exception would be thrown and caught, and the traceback would be logged - sure. But in lower-level languages, most notably C, ignoring error returns will often lead to hard-to-debug situations much later in code, having possibly overwritten stack in some situations. Of course it depends on how well thought-out your error handling policy is; I personally consider it easier to drop log a message and attempt to abort the current operation as gracefully as is realistic. I realize the error handling codepaths can much more likely have bugs as they're not tested very often, but it's not a much worse situation. -- intgr 17:14, 3 October 2006 (UTC)
Removed section
editI've removed the "Other examples" section, introduced by Beno1000 on 01:24, 29 September 2008 in this edit, since, besides being rather awkwardly tacked onto the end of the article, it actually contains some factual errors. (In particular, division by zero does not normally produce buffer overruns.) In case someone wants to try making something usable out of it, here's the content of the section as it was when I removed it:
“ | A rather common and infamous programming error is division by zero. Normally, this will cause a buffer overrun as the program tries to calculate to infinity. Some programs will detect this abnormality and quit gracefully, while others will hang or crash outright and others still will continue to run, but abnormally. However, this can be prevented by a simple if statement which will return an error message to the user, as in the pseudocode below.
If inputted data is zero then display an error message saying "Cannot divide by zero" Else Divide the inputted data by the number stored in the number buffer (variable) |
” |
—Ilmari Karonen (talk) 20:37, 3 October 2008 (UTC)
Murphy's Law
editCiting Murphy's Law as justification for defensive programming is ridiculous. It is not a physical law, it's a humourous observation on life. The case can be argued much better using terms like risk. Nczempin (talk) 16:15, 21 October 2008 (UTC)
- I LOL'D. And as of late 2013 it's still here. --Abatishchev (talk) 00:06, 18 December 2013 (UTC)
- Keep it there. Murphy's Law is much easier for most people to understand than The Gambler's Ruin, which boils down to the same thing -- given enough opportunities to go wrong, a system will go wrong. TTK (talk) 23:20, 25 April 2015 (UTC)
When to error out
editI consider the function 'high_quality_programming' worse than 'low_quality_programming' which is very bad too. If the second function is called with a string longer that LENGTH characters, than it will SILENTLY truncate it. I assume here that the function is supposed to work on the complete string and not to just work on the first characters in case the string is too long. If it is allowed to pass a string longer than LENGTH, than the first function has random behavior and a crash somewhere else is hard to track down. The second function does the wrong thing and could have even more subtile changes in your program and with no crash or other symptom is most likely even harder to debug. A real defensive function would error out if it is called with arguments that it cannot handle. Initializing the target is also not necessary. It would be enough to make sure the result string is null terminated. strncpy also would be called with LENGTH+1 to make sure that the terminator is copied for strings of length LENGTH. The result of strncpy can be used to check if the string was null terminated. The function has to error out if truncating is not what the function is specified to do. Sconden (talk) 20:28, 11 October 2010 (UTC)
memset?
editI don't mind the canon strcpy()/strncpy() example (though I think there are much less subtle examples of defensive programming), but does someone mind explaining to me the significance of the obfuscated memset() call versus a much clearer "str[999] = '\0'"? strncpy already pads with null, so memset() is not only vague and obfuscating, it's redundant. Honestly, I think the null bounding could be omitted entirely since it's irrelevant to the example's main point. Jrajav (talk) 03:54, 13 December 2011 (UTC)
Vague and Off-track
editI just came across this article and have some significant problems with it. Though there are some good things about it, in general it is vague and even incorrect in places. Towards the end it just becomes a succession of rambling statements, mostly irrelevant.
Take the first paragraph -- what does "ensure the continuing function" mean exactly? How can you cater for "unforeseeable usage" since by definition you can't foresee it - "unexpected" would be a better word here. The mention of Murphy's Law makes me think that the rest of an article is actually a joke. Emotive words like "mischievously" and "catastrophic" are also inappropriate.
The next bit is even worse. The true definition of defensive programming is open to debate (see below) but it is definitely not about removing bugs (rather about lessening their effect), or making code comprehensible. (Also why mention readable and understandable after the word comprehensible - all three words means the same thing in this context. And what do "code audits" have to do with it?) The last sentence about "making the software behave predictably" is getting closer to the meaning but not really true. Also what is the difference between "inputs" and "user actions"?
The code example is a reasonable example of defensive programming. One confusing thing is why the buffer "str" is declared to be 1001 characters in the first snippet and only 1000 in the second. Also (as pointed out above) the memset is unnecessary since clearing the last byte is sufficient.
I think a simpler example would be a for loop. It also avoids the confusion between defensive programming and secure programming, since buffer overruns are a major aspect of secure programming but not so much in defensive programming.
However, my main problem with the article is that it does not describe the most commonly accepted definition of defensive programmming, which is simply code that recovers from unexpected situations. This can be useful in "secure programming" but more useful for that is input validation.
It also does not mention the problems with defensive programming which is that it tends to hide the presence of bugs. — Preceding unsigned comment added by 203.41.222.1 (talk) 02:36, 27 March 2012 (UTC)
The use of "overly" should be avoided
editI find the use of the word "overly" in the "Overly defensive programming" examples problematic. They might be overly defensive according to the offensive programming principle, but that doesn't necessarily make them "overly" defensive in general.
And even if they are overly defensive even for defensive programming, then they are not very helpful in illustrating the actual difference between normal defensive programming and offensive programming.
The best would be to use perfectly valid "Normal defensive programming" (or "Non-offensive defensive programming") examples and contrast them with their corresponding "Offensive programming" examples, to actually show the difference.
I cannot correct this myself, as I am not enough into the terminology to provide a normal defensive programming example and provide a parallel offensive programming example. (I can see what is wrong, but that doesn't mean I can provide the correction.) --Jhertel (talk) 12:59, 27 October 2018 (UTC)
- I agree to that in 2023: "Overly" is a personal opinion and should be avoided. In fact, I think the "offensive programming" example using assert(0) is a very bad practice and not defensive programming at all. This is because it leaves the function without a defined return value when compiled with NDEBUG. It will even cause a compiler warning. Adding the assert(0) statement before an return statement is a more robust approach. 84.253.48.217 (talk) 09:29, 20 April 2023 (UTC)
Dubious claims
editSeveral of the claims are dubious, and even encourage readers to fall prey to well known CWE's, such as CWE-478 (https://cwe.mitre.org/data/definitions/478.html), by claiming that a default case is "overly defensive". — Preceding unsigned comment added by 67.255.15.19 (talk) 21:37, 18 January 2020 (UTC)
Additions
edit1. Use source code and binaries scanners (e.g., https://www.veracode.com/) 2. Use docker images vulnerability scannners (e.g., docker snyk engine: https://docs.docker.com/engine/scan/ , jfrog xray: https://jfrog.com/integration/xray-docker-security-scanning/