mailing list of musl libc
 help / color / mirror / code / Atom feed
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--


  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).