Secure Coding mailing list archives

Coding with errors in mind - a solution?


From: pmeunier at cerias.net (Pascal Meunier)
Date: Fri, 01 Sep 2006 10:41:23 -0400




On 8/31/06 8:05 PM, "mikeiscool" <michaelslists at gmail.com> wrote:

On 9/1/06, Pascal Meunier <pmeunier at cerias.net> wrote:



On 8/30/06 3:46 PM, "Tim Hollebeek" <tholleb at teknowledge.com> wrote:


What you've proposed are exceptions.  They do help (some) in separating
the normal logic from error handling, but:

(1) they often leave the job "half done" which has its own risks.
    writing exception safe code can be more of a nightmare than error
checking.

I can't help noticing...  In Ruby there's an "ensure" clause that allows you
to bring closure to half-done operations.  Perhaps your point is that some
languages have poor exception support, just like some languages don't
provide safe string handling functions?

His point, I think, is that if you wrap a series of statements in an
try/catch block, you might not roll back every statement you needed
to, or checked appropriate conditions.

For example:
try {
 openFile();
 getData();
 writeToFile();
 setSomeFlag()
 moveFile();
 deleteTempThings();
} catch(Exception e){
 ...
}

Now obviously that's a statement that could be written far better, but
the point is that with the lazy/bad/accidental-bug-producing
programmer it might be common.

Ah, yes, I can see a bad (or under pressure) programmer lumping together the
handling of exceptions that should be handled separately, or making just one
giant try block so when there's an exception, even if you specify the type
there's still ambiguity as to where it came from and therefore can't handle
it properly.  That could be quite a mess.  Thanks.

Exceptions simplify the code? I don't think so. They also don't reduce
code duplication [per se] you need to add extra functions, etc, to do
that.

They can simplify the code because
-as previously mentioned by Tim, they separate error handling from normal
logic, so the code is easier to read (it is simpler from a human reader's
perspective).  I have found bugs in my own code by going from error handling
to exceptions -- it made the mistake plain to see.

-if an exception is handled several call layers above, you don't have to
copy/translate and relay the error at each layer, with the attached loss of
context and possible translation mistakes (error #3 in one layer/module may
mean something different in another...).  So, there's less (duplicated)
code.

-It is common (and bad, IMO) practice for errors to be signified to callers
by returning an out of range or different type (or null) value when
something else is semantically expected.  The result is that if the caller
forgets to check for errors, a bad value is used by the remaining code.  If
the caller checks for errors, an often used way to do this is to tuck the
assignment inside an if statement.  Then, even if the error is checked for,
subsequent code may assume that the assigned variable still contains a
semantically correct value (e.g., the previous value) which causes bugs and
possibly vulnerabilities (I remember seeing an instance of this).  So (and
for additional reasons that could be chalked up to coding style
preferences), a good practice is to decouple the error channel from the data
channel (e.g., pass additional variables by reference or use exceptions as
the error channel).  By passing a variable by reference, its value can be
left intact if there's an error in the called function (I *really* like to
have variables that always contain a semantically correct, or valid, range
and type).  Obviously passing additional variables by reference up and down
calling chains complicates the code, whereas exceptions are transparent.

As with most everything else, all this (simplifying the code and reducing
code duplication) depends on having a programmer with coding style and
skills that can take advantage of the provided opportunities.

Pascal




Current thread: