Protective programming does not mean protecting your code with the words: “It works that way!” His idea coincides with the idea of careful driving, in which you are ready for any antics of other drivers: you will not suffer, even if they do something dangerous. You take responsibility for your own protection and in cases where the other driver is at fault.
In defensive programming, the main idea is that if incorrect data is passed to a method, then its operation will not be disturbed, even if this data is corrupted due to the fault of another program. Summarizing, we can say that there will always be problems in programs, programs will always be modified and a reasonable programmer will always take this into account when developing code.
This chapter tells you how to defend yourself from the merciless world of incorrect data, events that “never” can happen, and other programmer errors. If you are an experienced programmer, you can skip the next section on input processing and go to section 8.2, which will tell you about assertions.
8.1. Protect the program from incorrect input data.
You may have heard the expression: “Garbage at the entrance is garbage out” (“Garbage in, garbage out”). This is a warning to consumers from software developers: let the user beware.
For industrial software, the principle of “trash at the entrance - trash at the exit” is not very suitable. A good program will never give out trash no matter what it had at the entrance. Instead, it uses the principles: “garbage on entry - nothing on exit”, “garbage on entry - error message on exit” or “garbage on entry is not allowed”. By today's standards, “input garbage is output garbage” is a sign of a careless, unsafe code.
There are three main ways to handle input junk data listed below.
Check all data from external sources
After receiving data from a file, from a user, from a network, or any other external interface, make sure that all values fall within a valid interval. Verify that numeric data is valid, and strings are short enough to process. If the line should contain a specific set of values (say, a financial transaction identifier or something like that), check that this value is valid in this case, but if not, reject it. If you are working on an application that requires security, be especially careful with the data that can attack your system: buffer overflow attempts, embedded SQL commands, embedded HTML or XML code, integer overflows, data transferred to system calls, etc. P.
Check the value of all method input parameters.
Checking the values of the input parameters of a method is practically the same as checking data from an external source, except that all data comes from a different method, and not from an external interface. In section 8.5, you will learn how to determine which methods should check your input.
Decide how to handle the wrong input.
What to do if you find the wrong parameter? Depending on the situation, you can choose from a dozen approaches, described in detail in section 8.3.
Defensive programming is a useful addition to other ways to improve the quality of programs described in this book. The best way to protect coding is to not make mistakes initially. Iterative design, writing pseudo-code and tests before coding begins, and low-level project compliance checking is all that helps to avoid adding defects.