简体   繁体   中英

How often should I check the validity of the arguments?

Very frequently I encounter the similar architectural problem. How often should one check for validity of entered arguments? Let's check the following example (don't care about the code correctness or compileability):

public void DoSth()
{
    context.DbPerform((SQLiteConnection connection) =>
        {
            // *** 1 ***
            if (connection == null)
                throw new ArgumentNullException("connection");
            if (!connection.IsOpen)
                connection.Open();

            try
            {
                Data.Insert(data, connection);
            }
            finally
            {
                connection.Close();
            }
        });
}

// ----

public static void Insert(Data data, SQLiteConnection connection)
{
    // *** 2 ***

    if (data == null)
        throw new ArgumentNullException("data");
    if (connection == null)
        throw new ArgumentNullException("connection");

    if (!connection.IsOpen)
        connection.Open();

    try
    {
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = SQL.InsertData;

            FillParameters(data, connection, cmd);

            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        connection.Close();
    }
}

// ----

public static void FillParameters(Data data,
    SQLiteConnection connection,
    SQLiteCommand cmd)
{
     // *** 3 ***
     if (connection == null)
         throw new ArgumentNullException("connection");

     // And so on, you get the idea
}

In the previous snippet, the connection has been checked for being null or closed for three times. This seems like a little bit of overkill for me - sometimes 50% of the method's body are the security checks. I don't feel like that much security checks are necessary, but on the other hand always someone else could have used these methods and I cannot be sure if he passed valid parameters.

So my questions are:

  • How often should one write security checks regarding passed parameters?
  • What techniques may be used to retain the level of security, but without often security checks?
  • How paranoid should I be while checking for invalid input? Consider another example:
class C
{
    private Obj obj;

    public C (Obj newObj)
    {
        if (newObj == null)
            throw new ArgumentNullException("newObj");

        obj = newObj;
    }

    public void DoSth()
    {
        // Should I check, whether obj is not null?
    }
}

Regarding the first example, the checks in Insert() are a good idea because Insert() is public . It could be called from another context where no checks were done.

In general, always validate at a public interface point. This helps in making your code loosely-coupled and reusable.

And every layer (tier, method) has its own requirements. So validate what you need to do a certain task at the beginning of that task.

I agree with Henk. Moreover try to consider the Code Contracts extension for Visual Studio which provide a way to specify preconditions, postconditions, and object invariants in your code: http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970 . It enforces a very consistent way to secure your code and the tool "Pex" can be used to auto-generate tests based on the contracts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM