Thread: Hit a annoying bug with my buffer insertion

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Hit a annoying bug with my buffer insertion

    I think the output here is self explanatory in regards the bug, either way I can't think of anything I might need to elaborate on so ask away if you feel you need more
    Code:
    make test
    ...
    Launching Tests...
    Joined buffer did not match expected text
    Wanted: '14636915424238335'
    Actual: '14636915'
    Source: '424238335'
    Program tried to use a bad memory/function pointer
    Compilation finished successfully.
    The relevant code (not uploading project's current state until my unlimited mobile data plan starts, mistimed the end of broadband vs that so on limited data)
    Code:
    /* Positions of end & top are swapped here to provide a '\0' character on
     * both ends of strings using PAWMEM, only the opposing pointer is expected
     * to be set (e.g. sfx->top = pfx, pfx->end = sfx) when not used for the main
     * information */
    struct _PAW_MEMORY
    {
    	pawju end;
    	pawzd cap;
    	pawju top;
    };
    ...
    PAW_API void*	pawCramMemoryX( pawMEM Mem, pawzd pos, pawp dup, pawzd cap, pawzd was )
    {
    	pawhhu const *pfx = dup;
    	pawhhu *top = PawTopOfMemory( Mem );
    	pawvd i = ((pawvd)(pfx - top));
    	if ( cap < 0 )
    		return top;
    	was = PawToRange( 0, was, Mem->cap );
    	top = pawGrowMemoryz( Mem, was + cap );
    	if ( top )
    	{
    		pawzd mov = was - pos;
    		pos = PawToRange( 0, pos, was );
    		paw_mov( top + pos + cap, top + pos, mov );
    		if ( !dup )
    			paw_set( top + pos, 0, cap );
    		else
    		{
    			pawzd did = 0;
    			pawhhu const *sfx = NULL;
    			if ( PawInRange( pos, i, was ) )
    			{
    				paw_cpy( top + pos, top + pos + mov, cap );
    				return top;
    			}
    			if ( !PawInRange( 0, i, pos ) )
    			{
    				paw_cpy( top + pos, dup, cap );
    				return top;
    			}
    			pfx = top + i;
    			did = (i + cap) - pos;
    			if ( did <= 0 )
    			{
    				paw_cpy( top + pos, pfx, cap );
    				return top;
    			}
    			cap -= did;
    			sfx = pfx + pos + mov + cap;
    			paw_cpy( top + pos, pfx, cap );
    			paw_cpy( top + pos + cap, sfx, did );
    		}
    	}
    	return top;
    }
    ...
    struct _PAW_BUFFER
    {
    	pawMEM	Mem;
    	pawzd const div;
    	pawd	num;
    	pawd	got;
    };
    ...
    PAW_API void*	pawCramBufferN( pawBUF Buf, pawzd pos, pawp dup, pawzd cap )
    {
    	if ( Buf->div > 0 )
    	{
    		void *top = pawCramMemoryX
    			( Buf->Mem, pos, dup, cap, Buf->div * Buf->num );
    		if ( top )
    		{
    			Buf->num += PawToUpperDivision( cap, Buf->div );
    			set_buf_values( Buf, top, false );
    		}
    		return top;
    	}
    	return NULL;
    }
    
    PAW_API void*	pawJoinBufferc( pawBUF Buf, pawd num )
    	{ return pawCramBufferc( Buf, Buf->num, num ); }
    PAW_API void*	pawJoinBufferT( pawBUF Buf, PAWBUF Dup )
    	{ return pawJoinBuffern( Buf, PawTopOfMemory(Dup->Mem), Dup->num ); }
    PAW_API void*	pawJoinBuffern( pawBUF Buf, pawp dup, pawd num )
    	{ return pawCramBuffern( Buf, Buf->num, dup, num ); }
    PAW_API void*	pawJoinBufferN( pawBUF Buf, pawp dup, pawzd cap )
    	{ return pawCramBufferN( Buf, Buf->div * Buf->num, dup, cap ); }
    ...
    pawd test_pawJoinBuffern()
    {
    	if ( buftest )
    	{
    		pawc str[bitsof(pawd)] = {0};
    		pawc nxt[bitsof(pawd)*3] = {0};
    		pawc *txt = PawTopOfBuffer( buftest );
    		pawd len = sprintf( str, "%d", rand() );
    		pawd n = sprintf( nxt, "%s%s", txt, str );
    		return test__locstrptr
    		(
    			"Joined buffer", "join buffer",
    			pawJoinBufferN( buftest, str, len ),
    			nxt, n, str, len
    		);
    	}
    	puts("Object does not exist, cannot join buffer");
    	return -1;
    }

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    As it turns out, the bug was not in that code, turns out I had forgotten to stop accounting for the '\0' character now that it was no longer needed, hit a different bug in the process of cleaning that up though, maybe someone here can spot the cause while I'm investigating the 'bad pointer' error I had been ignoring from later tests:
    Code:
    make test
    ...
    Launching Tests...
    Memory failure during 'oust from' action.
    Strings did not match at position 0:
    Expected '428'
    Received '383'
    Buffer failure during 'oust from' action.
    Lengths did not match:
    Expected length 03 for '335'
    Received length 15 for '719885386238335'
    Program tried to use a bad memory/function pointer
    Compilation finished successfully.
    Code (top caller to bottom this time)
    Code:
    pawd test_oust_paws( obj_paws *obj )
    {
    	obj->action = "oust from";
    	if ( obj->ud )
    	{
    		pawd len = obj->leng;
    		pawc *txt = obj->text;
    		pawc *nxt = PawAllocObj( len );
    		if ( nxt )
    		{
    			pawd err = -1;
    			pawd pos = abs(rand() % len);
    			pawc num = sprintf( nxt, "%.*s", pos, txt + pos );
    			obj->oustCB( obj->ud, pos, NULL, len );
    			err = text_testall( obj, txt, nxt, num );
    			PawAlloc( nxt, 0 );
    			return err;
    		}
    		puts("Couldn't allocate memory for temporary string");
    		return -1;
    	}
    	printf("Object does not exist, cannot oust %s\n", obj->type );
    	return -1;
    }
    ...
    void* test__pawMakeMemoryN( void *ud, pawd pos, paws str, pawd dig )
    {
    	(void)pos;
    	pawMEM Mem = pawMakeMemoryN( str, dig );
    	if ( Mem )
    		((obj_paws*)ud)->text = PawTopOfMemory( Mem );
    	return Mem;
    }
    void* test__pawCramMemoryX( void *ud, pawd pos, paws str, pawd len )
    {
    	pawzd was = paws_len(PawTopOfMemory( ud ));
    	return pawCramMemoryX( ud, pos, str, len, was );
    }
    void* test__pawOustMemoryz( void *ud, pawd pos, paws str, pawd len )
    	{ (void)str; pawOustMemoryz( ud, 0, len - pos ); return NULL; }
    void* test__pawJoinMemoryX( void *ud, pawd pos, paws str, pawd dig )
    	{ return pawJoinMemoryX( ud, str, dig, pos ); }
    void*	test__pawVoidMemory( void *ud ) { return pawVoidMemory( ud ); }
    
    void*	test__pawMakeBuffern( void *ud, pawd pos, paws str, pawd dig )
    {
    	(void)pos;
    	pawBUF Buf = pawMakeBuffern( 1, str, dig );
    	if ( Buf )
    		((obj_paws*)ud)->text = PawTopOfBuffer( Buf );
    	return Buf;
    }
    void*	test__pawCramBuffern( void *ud, pawd pos, paws str, pawd dig )
    	{ return pawCramBuffern( ud, pos, str, dig ); }
    void*	test__pawOustBufferc( void *ud, pawd pos, paws str, pawd len )
    	{ (void)str; pawOustBufferc( ud, 0, len - pos ); return NULL; }
    void*	test__pawJoinBuffern( void *ud, pawd pos, paws str, pawd dig )
    	{ (void)pos; return pawJoinBuffern( ud, str, dig ); }
    void*	test__pawVoidBuffer(void*ud) { return pawVoidBuffer(ud); }
    
    pawd test_pawVoidMemory() { return test_void_object( &memtest ); }
    pawd test_pawMakeMemoryN()
    {
    	memtest.voidCB = test__pawVoidMemory;
    	memtest.makeCB = test__pawMakeMemoryN;
    	memtest.cramCB = test__pawCramMemoryX;
    	memtest.oustCB = test__pawOustMemoryz;
    	memtest.joinCB = test__pawJoinMemoryX;
    	return test_make_paws( &memtest );
    }
    pawd test_pawCramMemoryX() { return test_cram_paws( &memtest ); }
    pawd test_pawOustMemoryz() { return test_oust_paws( &memtest ); }
    pawd test_pawJoinMemoryX() { return test_join_paws( &memtest ); }
    
    pawd test_pawVoidBuffer() { return test_void_object( &buftest ); }
    pawd test_pawMakeBuffern()
    {
    	buftest.voidCB = test__pawVoidBuffer;
    	buftest.makeCB = test__pawMakeBuffern;
    	buftest.cramCB = test__pawCramBuffern;
    	buftest.oustCB = test__pawOustBufferc;
    	buftest.joinCB = test__pawJoinBuffern;
    	return test_make_paws( &buftest );
    }
    pawd test_pawCramBuffern() { return test_cram_paws( &buftest ); }
    pawd test_pawOustBufferc() { return test_oust_paws( &buftest ); }
    pawd test_pawJoinBuffern() { return test_join_paws( &buftest ); }
    ...
    PAW_API void pawOustBufferi( pawBUF Buf, pawd pos )
    	{ pawOustBufferr( Buf, pos, pos + 1 ); }
    PAW_API void pawOustBufferc( pawBUF Buf, pawd pos, pawd num )
    	{ pawOustBufferr( Buf, pos, pos + num ); }
    PAW_API void pawOustBufferr( pawBUF Buf, pawd pos, pawd end )
    {
    
    	if
    	(
    		PawInRange( 0, pos, Buf->num )
    		&& PawInRange( pos, end, Buf->num )
    	)
    	{
    		pawOustMemoryr( Buf->Mem, Buf->div * pos, Buf->div * end );
    		Buf->num -= (end - pos);
    	}
    }
    ...
    PAW_API void	pawOustMemoryz( pawMEM Mem, pawzd pos, pawzd cap )
    	{ pawOustMemoryr( Mem, pos, pos + cap ); }
    PAW_API void	pawOustMemoryr( pawMEM Mem, pawzd pos, pawzd end )
    {
    	pawzd cap = Mem->cap;
    	if ( PawInRange( 0, pos, cap ) && PawInRange( pos, end, cap ) )
    	{
    		pawzd mov = cap - end;
    		pawhhu *top = PawTopOfMemory( Mem );
    		paw_mov( top + pos, top + end, mov );
    		paw_set( top + pos + mov, 0, end - pos );
    	}
    }

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Decided to put a bit of effort into printing original text also, code is the same except 'nxt' is now offset from a larger allocation made for copying the text to before changing it so that it can be printed in the error statements. Since the previous output I gave doesn't include that info here's a new one to mull over if you're inclined:
    Code:
    make test
    ...
    Launching Tests...
    Memory failure during 'oust from' action.
    Strings did not match at position 0:
    Expected '428'
    Received '383'
    Begun as '1804289846930886383'
    Buffer failure during 'oust from' action.
    Lengths did not match:
    Expected length 03 with '335'
    Received length 15 with '719885386238335'
    Begun as length 18 with '424719885386238335'
    Program tried to use a bad memory/function pointer
    Compilation finished successfully.

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Never mind, found what I had been doing wrong, my dumbass self started the printf for the expected result but never finished it resulting in unexpected results, with a few fixes (both to the printf and how the values were used in the callbacks) I got it fixed:
    Code:
    pawd test_oust_paws( obj_paws *obj )
    {
    	obj->action = "oust from";
    	if ( obj->ud )
    	{
    		pawd len = obj->leng;
    		pawc *txt = obj->text;
    		/* Leaving a fair bit of leeway */
    		pawd need = (len * 2) + 8;
    		pawc *old = (len >= 0) ? PawAllocObj( need ) : NULL;
    		if ( old )
    		{
    			pawd err = -1;
    			pawc *nxt = old + len + 1;
    			pawd pos = abs(rand() % len);
    			pawd rem = abs(rand() % (len - pos));
    			pawc num = sprintf
    				( nxt, "%.*s%s", pos, txt, txt + pos + rem );
    			paw_cpy( old, txt, len );
    			obj->oustCB( obj->ud, pos, NULL, rem );
    			err = text_testall( obj, txt, nxt, num, old );
    			if ( err )
    			{
    				printf
    				(
    					"Characters from positions %d to %d "
    					"should've been removed, was '%.*s'\n",
    					pos, pos + rem, rem, old + pos
    				);
    			}
    			PawAlloc( old, 0 );
    			return err;
    		}
    		puts("Couldn't allocate memory for temporary string");
    		return -1;
    	}
    	printf("Object does not exist, cannot oust %s\n", obj->type );
    	return -1;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copy the content of buffer to temp buffer
    By Megha Bhirade in forum C Programming
    Replies: 1
    Last Post: 11-12-2018, 07:19 AM
  2. Class for both dynamic allocated buffer and static buffer
    By TotalTurd in forum C++ Programming
    Replies: 3
    Last Post: 01-07-2012, 09:09 PM
  3. Keyboard Buffer Insertion
    By Jamdog in forum C Programming
    Replies: 5
    Last Post: 09-24-2010, 05:42 PM
  4. fgets(buffer,sizeof(buffer),stdin);
    By linuxdude in forum C Programming
    Replies: 2
    Last Post: 10-28-2003, 10:41 AM
  5. annoying lil bug
    By baka1337 in forum C++ Programming
    Replies: 6
    Last Post: 04-23-2003, 12:36 AM

Tags for this Thread