> -----Original Message-----
> From: Martin Sebor [mailto:[EMAIL PROTECTED]
> Sent: Friday, July 14, 2006 12:07 AM
> To: [email protected]
> Subject: Re: Environment for the test of the string functions
> memory overrun with example
>
[...]
>
> Okay, this version is closer to what I have in mind :) There
> are a few minor tweaks that I would still make but I think
> it's ready to commit as is (please go ahead and have Anton do
> it). We can make the tweaks later (we will also need a test
> to exercise this).
[...]

  I have updated the rw_alloc.h and alloc.cpp according to your comments.

Anton commited this version (http://svn.apache.org/viewvc?rev=421918&view=rev).

Also I wrote the test to exercise the rw_alloc() function (tests/self/0.alloc.cpp). The test is attached.

Farid.
/************************************************************************
*
* 0.alloc.cpp - test exercising the rw_alloc() and rw_free() functions
*
* $Id: 0.alloc.cpp
*
************************************************************************
*
* Copyright 2006 The Apache Software Foundation or its licensors,
* as applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**************************************************************************/

#include <signal.h>      // for signal
#include <setjmp.h>      // for setjmp, longjmp

#include <rw_alloc.h>    // for rw_alloc, rw_free
#include <rw_printf.h>   // for rw_printf
#include <driver.h>

#ifdef __CYGWIN__
// use the Windows API on Cygwin
#  define _WIN32
#endif

static jmp_buf mark;

static void sig_handler (int)
{
    longjmp (mark, -1);
}

#ifdef sigsetjmp
#define SETJMP(env) sigsetjmp (env, 1)
#else
#define SETJMP(env) setjmp (env)
#endif

#define BEGIN_TEST_OVERRUN()       \
    signal (SIGSEGV, sig_handler), \
    (0 == SETJMP (mark))

struct TestCase
{
    size_t       size_;
    int          index_;
    int          prot_;
    const char*  file_;
    int          line_;
};

void test (const TestCase& tcase)
{
    if (void* buf = rw_alloc (tcase.size_, tcase.prot_)) {

        char* str = _RWSTD_STATIC_CAST (char*, buf);

        bool protbelow = 0 != (tcase.prot_ & RW_PROT_BELOW);

        bool canread = (tcase.prot_ &
#if defined (_WIN32) || defined (_WIN64)
               (RW_PROT_READ | RW_PROT_WRITE | RW_PROT_EXEC))
#else
               (RW_PROT_READ | RW_PROT_EXEC))
#endif
            && (
                (protbelow && 0 <= tcase.index_)
             || (!protbelow && tcase.index_ < int (tcase.size_))
            );

        bool canwrite = (tcase.prot_ & RW_PROT_WRITE)
            && (
                (protbelow && 0 <= tcase.index_)
             || (!protbelow && tcase.index_ < int (tcase.size_))
            );

        char c = 'a';

        if (BEGIN_TEST_OVERRUN ()) {
            c = str[tcase.index_];
            rw_assert (canread, tcase.file_, tcase.line_,
                "expected no read access, got read access");
        } else
            rw_assert (!canread, tcase.file_, tcase.line_,
            "expected read access, got no read access");

        if (BEGIN_TEST_OVERRUN ()) {
            str[tcase.index_] = c;
            rw_assert (canwrite, tcase.file_, tcase.line_,
                "expected no write access, got write access");
        } else
            rw_assert (!canwrite, tcase.file_, tcase.line_,
                "expected write access, got no write access");

        rw_free (buf);
    }
}

static int
run_test (int, char**)
{
    const size_t BUF_SIZE = 10;

    static const TestCase tcases[] = {

#ifdef TEST
#undef TEST
#endif
#define TEST(size, index, prot) \
    { size, index, prot, __FILE__, __LINE__ }

        TEST(BUF_SIZE, -1, RW_PROT_NONE),
        TEST(BUF_SIZE, -1, RW_PROT_READ),
        TEST(BUF_SIZE, -1, RW_PROT_WRITE),
        TEST(BUF_SIZE, -1, RW_PROT_EXEC),

        TEST(BUF_SIZE, -1, RW_PROT_NONE | RW_PROT_BELOW),
        TEST(BUF_SIZE, -1, RW_PROT_READ | RW_PROT_BELOW),
        TEST(BUF_SIZE, -1, RW_PROT_WRITE | RW_PROT_BELOW),
        TEST(BUF_SIZE, -1, RW_PROT_EXEC | RW_PROT_BELOW),

        TEST(BUF_SIZE, 0, RW_PROT_NONE),
        TEST(BUF_SIZE, 0, RW_PROT_READ),
        TEST(BUF_SIZE, 0, RW_PROT_WRITE),
        TEST(BUF_SIZE, 0, RW_PROT_EXEC),

        TEST(BUF_SIZE, 0, RW_PROT_NONE | RW_PROT_BELOW),
        TEST(BUF_SIZE, 0, RW_PROT_READ | RW_PROT_BELOW),
        TEST(BUF_SIZE, 0, RW_PROT_WRITE | RW_PROT_BELOW),
        TEST(BUF_SIZE, 0, RW_PROT_EXEC | RW_PROT_BELOW),

        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_EXEC | RW_PROT_BELOW),

        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE),
        TEST(BUF_SIZE, BUF_SIZE, RW_PROT_EXEC),

        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE | RW_PROT_BELOW),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_EXEC | RW_PROT_BELOW),

        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE),
        TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_EXEC)
    };

    for (size_t i = 0; i < sizeof (tcases) / sizeof (tcases[0]); ++i)
        test (tcases [i]);

    return 0;
}

/***********************************************************************/

int main (int argc, char *argv[])
{
    return rw_test (argc, argv, __FILE__,
        "",
        0,
        run_test,
        "",
        (void*)0 /* sentinel */);
}

Reply via email to