From: "Luka Marčetić" <paxcoder@gmail.com>
To: musl@lists.openwall.com
Subject: Re: Simple testing task - string functions
Date: Thu, 14 Apr 2011 19:59:33 +0200 [thread overview]
Message-ID: <4DA73605.9080107@gmail.com> (raw)
In-Reply-To: <20110410044515.GB13185@brightrain.aerifal.cx>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: multipart/mixed;, Size: 5545 bytes --]
This is a multi-part message in MIME format.
--------------080500010007030902050509
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Hello again.
Attached is the solution to the task. The program seems to preform as
expected, but may still need double-checking.
The tests therein fail where expected when linked with various old
versions of musl. Note that although the program is designed to allow
tests to fail gracefully as suggested, this does not happen due to bugs
in function implementations in said old versions that the program
depends on. Rich and Chris have confirmed a bug in 0.7.6 that causes a
segfault in the siglongjmp (longjmp to be exact). I'm still waiting for
confirmation of inability of version 0.7.5 to dispose the same signal to
a specified handler properly.
Thanks.
Luka Marčetić
--------------080500010007030902050509
Content-Type: text/x-csrc;
name="memory_access.c"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment;
filename="memory_access.c"
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <setjmp.h>
/**
** \file depends: sysconf, mmap, mprotect, open, signal, sigsetjmp, siglongjmp, fprintf
** \author Luka Marčetić, 2011
**/
//necessary to detect errors, and resume afterwards:
int next; ///< number of the currently executing test, or greater on failure
sigjmp_buf env; ///< will store the signal mask and stack context/environment
void bridge_sig_jmp(int sig);
void print_result(int done, char *name);
/**
** Tests string/memory functions for invalid memory access
** and for correctnes when handling 'high' vs 'low' bytes.
**
** tests: strchr, strlen, strspn, strcspn, memchr
**/
int main()
{
int i, j, k, fd, tmpi, pg_size=sysconf(_SC_PAGESIZE);
char *tmp, *m;
char low=' ', high=128+low, string[]="\x20\x40\x60\x80\xA0\xC0\xE0";
fd = open("/dev/zero", O_RDWR);
m = mmap(NULL, pg_size*2, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
mprotect(m+pg_size, pg_size, PROT_NONE);
signal(SIGSEGV, bridge_sig_jmp);
next=0;
switch (sigsetjmp(env, 1))
{
case 0:
//strchr:
fprintf(stdout, " strchr\n");
for (i=0; i<pg_size; ++i)
m[i]=low;
for (i=1; i<=8; ++i)
{
m[pg_size-i] = high;
for (j=i; j<=pg_size; ++j)
{
tmp = strchr(&m[pg_size-j], high);
if (tmp != &m[pg_size-i])
bridge_sig_jmp(0);
}
m[pg_size-i] = low;
}
case 1:
print_result(0, "stopping at a 'high' character");
for (i=0; i<pg_size; ++i)
m[i]=high;
for (i=1; i<=8; ++i)
{
m[pg_size-i] = low;
for (j=i; j<=pg_size; ++j)
{
tmp = strchr(&m[pg_size-j], low);
if (tmp != &m[pg_size-i])
bridge_sig_jmp(0);
}
m[pg_size-i] = high;
}
case 2:
print_result(1, "stopping at a 'low' character");
for (i=0; i<pg_size; ++i)
m[i]=128;
for (i=1; i<=8; ++i)
{
m[pg_size-i] = '\0';
for (j=i; j<=pg_size; ++j)
{
tmp = strchr(&m[pg_size-j], low);
if (tmp != NULL)
bridge_sig_jmp(0);
}
m[pg_size-i] = 128;
}
case 3:
print_result(2, "stopping at a '\\0' character");
//strlen:
fprintf(stdout, " strlen\n");
//still filled with 128s
for (i=1; i<=8; ++i)
{
m[pg_size-i] = '\0';
for (j=i; j<=pg_size; ++j)
{
tmpi = strlen(&m[pg_size-j]);
if (tmpi != (pg_size-i)-(pg_size-j))
bridge_sig_jmp(0);
}
m[pg_size-i] = 128;
}
case 4:
print_result(3, "stopping at a '\\0' character");
//memchr:
fprintf(stdout, " memchr\n");
for (i=0; i<pg_size; ++i)
m[i]=low; //128 would cause an error per standard itself
for (i=1; i<=8; ++i)
{
m[pg_size-i] = '\0';
for (j=i; j<=pg_size; ++j)
tmp = memchr(&m[pg_size-j], '\0', pg_size+1);
m[pg_size-i] = low;
}
case 5:
print_result(4, "stopping at a '\\0' character");
//strspn:
fprintf(stdout, " strspn\n");
for (i=0; i<pg_size; ++i)
m[i]=string[i%7]; //'high' and 'low' chars
for (i=1; i<=8; ++i)
{
m[pg_size-i] = '\0';
for (j=i; j<=pg_size; ++j)
{
tmpi = strspn(&m[pg_size-j], string);
if (tmpi != (pg_size-i)-(pg_size-j))
bridge_sig_jmp(0);
}
m[pg_size-i] = string[(pg_size-i)%7];
}
case 6:
print_result(5, "stopping at a character not found in the set");
//strcspn:
fprintf(stdout, " strcspn\n");
//still filled with 'high' and 'low' chars
for (k=0; k<3; ++k)
{
m[pg_size-i] = '\0';
for (j=i; j<=pg_size; ++j)
{
tmpi = strcspn(&m[pg_size-j], "\x21\0\x21\0\0\x22");
if (tmpi != (pg_size-i)-(pg_size-j))
bridge_sig_jmp(0);
}
m[pg_size-i] = string[(pg_size-i)%7];
}
case 7:
print_result(6, "stopping at any character from the set");
break;
}
return 0;
}
/**
** A bridge function to be passed to signal(), to call siglongjmp().
** A call to this function means that the current test has failed.
**/
void bridge_sig_jmp(int sig)
{
++next;///< indication that there was an error (see print_result)
siglongjmp(env, next);
return;
}
/**
** Prints a success/failure message
** \param done number of the last test executed.
** \param name name of the last test executed.
**/
void print_result(int done, char *name)
{
if (next > done)
fprintf (stderr, " %s: Failure\n", name);
else
{
fprintf (stdout, " %s: Success\n", name);
next = done+1;
}
return;
}
--------------080500010007030902050509--
next prev parent reply other threads:[~2011-04-14 17:59 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-10 4:45 Rich Felker
2011-04-10 12:08 ` Luka Marčetić
2011-04-10 15:25 ` JIghtuse
2011-04-10 15:34 ` Rich Felker
2011-04-10 15:46 ` keep discussion threads separate (was: Simple testing task - string functions) Solar Designer
2011-04-14 17:59 ` Luka Marčetić [this message]
2011-04-14 23:11 ` Simple testing task - string functions Rich Felker
2011-04-18 12:20 ` Luka Marčetić
2011-04-25 19:34 ` Unit tests Luka Marčetić
2011-04-26 19:14 ` Solar Designer
2011-04-27 0:32 ` Rich Felker
2011-04-27 0:42 ` Rich Felker
2011-04-27 6:29 ` Luka Marčetić
2011-04-29 5:36 ` Solar Designer
2011-04-29 11:54 ` Christian Neukirchen
2011-05-01 19:36 ` Solar Designer
2011-05-02 8:51 ` Christian Neukirchen
2011-05-02 12:49 ` Solar Designer
2011-05-02 13:02 ` errno
2011-05-02 13:11 ` Rich Felker
2011-05-02 13:30 ` Solar Designer
2011-05-02 13:32 ` Rich Felker
2011-05-02 13:52 ` Solar Designer
2011-05-02 13:27 ` Solar Designer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DA73605.9080107@gmail.com \
--to=paxcoder@gmail.com \
--cc=musl@lists.openwall.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).