Software Construction: Assignment 3 (Worth 100 Points)

profilefarzadbigz
DefensiveProgramming1.pptx

NDSU CSCI 717 Software Construction

Defensive Programming

Textbook

Steve McConnell. Code Complete: A Practical Handbook of Software Construction. 2nd Edition. Microsoft Press, 2004. Chapter 8.

2

Protecting from Invalid Inputs

Garbage in, garbage out?

Mark of sloppy nonsecure program

Garbage in, nothing/error message out

No garbage allowed in

Defensive programming

If a routine is passed bad data, it won’t be hurt, even if the bad data is another routine’s fault.

Check values of all data from external sources

Sources: file, user, network

Allowable range: String vs security problem

Check values of all routine input parameters

Decide how to handle bad inputs

4

Assertions

To document assumptions made in the code and to flush out unexpected conditions

An input/output parameter in its expected range

A file/stream is open (or closed) when a routine begins (or ends) executing

A file/stream is at the beginning

A file/stream is open for read-only, write-only, etc.

An input-only variable is not changed

A pointer is non-null

A container is empty (or full) when a routine begins (or ends) executing

Match two results

5

Assertion Mechanism

Java assertions

Assert denominator!=0 : “denominator is 0”

Define your own

#define ASSERT(condition, message) {

if (!(condition)) {

LogError(“Assertion failed: ”, #condition, message);

exit(EXIT_FAILURE);

}

}

6

Using Assertions: Guidelines

Use error-handling for conditions you expect to occur; use assertions for condition that should never occur

Error handling typically checks for bad input

Assertions check for bugs in the code

Avoid putting executable code into assertions

The compiler will eliminate the code when the assertions are turned off

Use assertions to document/verify pre/postconds

For highly robust code, assert and then handle the error anyway.

E.g. change an invalid input to the closest legal value

7

Error-Handling Techniques

Return a neutral value (known to be harmless)

Examples: 0, empty string, default color

Substitute the next place of valid data

Encounter a corrupted record when reading from a DB

Return the same answer as the previous time

Thermometer-reading code does not get a reading one time

Substitute the closest legal value

Log a warning message to a file

Return an error code

8

Error-Handling Techniques

Call an error processing routine/object

Centralize error handling in a global routine/object

Display an error message wherever the error is encountered

Handle the error in whatever way works best locally

Individual developers have the flexibility

Risky: spread UI code throughout the system

Shut down

Safety critical applications

9

Using Exceptions: Suggestions

Use exceptions to notify other parts about errors that should not be ignored

Throw an exception only for conditions that are truly exceptional

Cannot be addressed by other coding practices

Don’t throw an uncaught exception if you can handle the error locally

Avoid throwing exceptions in constructors /destructors unless you catch them in the same place

The rule for how exceptions are processed become very complicated

C++: destructors are not called unless an object is fully constructed

10

Using Exceptions: Suggestions - cont

Throw exceptions at the right level of abstraction

The exceptions thrown are part of the interface

Class Employee {

public TaxId GetTaxId() throws EOFException

public TaxId GetTaxId() throws EmployeeDataNotAvailable

}

Include in the exception message all info that led to the exception

Avoid empty catch blocks

Know the exceptions your library code throws

Consider building a centralized exception reporter

Standardize your project’s use of exceptions

Consider alternatives to exceptions

11

Barricade/Firewall Your Program

A building’s firewall prevents fire from spreading from one part of the building to another part

Barricade your program to contain the damage caused by errors

Designate certain interfaces as boundaries to safe areas

Check data crossing the boundaries of a safe area for validity, and respond sensibly if the data is invalid

Class Level

Public methods assume the data is unsafe

Private methods can assume the data is safe

12

Debugging Aids

Introduce debugging aids early

Don’t automatically apply production constraints to the development version

Differences: speed, resource, etc

Use offensive programming

Exceptional cases should be handled in a way that makes them obvious during development and recoverable when production code is running. (Howard & Leblanc 2003, Writing secure code)

Default clause of case statement

Development - warning: “hey, another case here! Fix it”

Production - something more graceful, e.g. error-log

Plan to remove debugging aids

13

Programming Offensively

Make sure asserts abort the program

Don’t allow programmers to get into the habit of just hitting the Enter key to bypass a known problem

Completely fill any memory allocated to detect memory allocation errors

Completely fill any files/streams allocated to flush out any file-format errors

Be sure the code of default/else clause fails hard (aborts the program) or is o.w. impossible to overlook

Fill an object with junk data just before it is deleted

14

Be Defensive about Defensive Prog.

Think about where you need to be defensive.

Set you defensive programming priorities accordingly.

15