Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: GnuPG: gcrypt

Malfunction of gcry_sexp_car

 

 

GnuPG gcrypt RSS feed   Index | Next | Previous | View Threaded


benjamin.pousse at member

Feb 16, 2012, 1:09 PM

Post #1 of 4 (411 views)
Permalink
Malfunction of gcry_sexp_car

Hello,

(This is my first contribution. So I apologize if this is not the right
way to contribute.)

The function gcry_sexp_car seems buggy to me (tested on libgcrypt
version 1.4.6, 1.5.0, 1.6.0-git6078b05): it doesn't return any result on
S-expression starting with a data element.
For example, applied to the S-expression (hello "123"), it returns an
empty S-expression (I expect the S-expression (hello)).

In fact, after some "investigation", the function gcry_sexp_nth appears
unable to return the n-th element of a S-expression when this element is
not a list.
More precisely, in the function gcry_sexp_nth, the code in the first
"if" after the first loop "while" does not construct a valid gcry_sexp.

Please find at the end of this mail my patch to solve this problem (the
patch is large because I apply a regular indentation on the full
function).

Regards,
Benjamin.


diff --git a/src/sexp.c b/src/sexp.c
index 0877773..12b57ba 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -549,73 +549,96 @@ gcry_sexp_nth( const gcry_sexp_t list, int number
)
int level = 0;

if ( !list || list->d[0] != ST_OPEN )
- return NULL;
+ return NULL;
p = list->d;

- while ( number > 0 ) {
- p++;
- if ( *p == ST_DATA ) {
- memcpy ( &n, ++p, sizeof n );
- p += sizeof n + n;
- p--;
- if ( !level )
- number--;
- }
- else if ( *p == ST_OPEN ) {
- level++;
- }
- else if ( *p == ST_CLOSE ) {
- level--;
- if ( !level )
- number--;
- }
- else if ( *p == ST_STOP ) {
- return NULL;
- }
- }
+ while ( number > 0 )
+ {
+ p++;
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ return NULL;
+ }
+ }
p++;

- if ( *p == ST_DATA ) {
- memcpy ( &n, p, sizeof n ); p += sizeof n;
- newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, p + 1, sizeof n );
+ /* Allocate 1 (= sizeof *newlist) byte for ST_OPEN
+ 1 byte for ST_DATA
+ sizeof n byte for n
+ n byte for the data
+ 1 byte for ST_CLOSE
+ 1 byte for ST_STOP*/
+ newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2
);
if (!newlist)
return NULL;
- d = newlist->d;
- memcpy ( d, p, n ); d += n;
- *d++ = ST_STOP;
- }
- else if ( *p == ST_OPEN ) {
- const byte *head = p;
-
- level = 1;
- do {
- p++;
- if ( *p == ST_DATA ) {
- memcpy ( &n, ++p, sizeof n );
- p += sizeof n + n;
- p--;
- }
- else if ( *p == ST_OPEN ) {
- level++;
- }
- else if ( *p == ST_CLOSE ) {
- level--;
- }
- else if ( *p == ST_STOP ) {
- BUG ();
- }
- } while ( level );
- n = p + 1 - head;
+ d = newlist->d;
+ *d = ST_OPEN;
+ d++;
+ memcpy ( d, p, 1 + sizeof n + n ); /* Copy ST_DATA, n and the
data from p to d*/
+ d += 1 + sizeof n + n;
+ *d = ST_CLOSE;
+ d++;
+ *d = ST_STOP;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ const byte *head = p;
+
+ level = 1;
+ do
+ {
+ p++;
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ BUG ();
+ }
+ } while ( level );
+ n = p + 1 - head;

- newlist = gcry_malloc ( sizeof *newlist + n );
+ newlist = gcry_malloc ( sizeof *newlist + n );
if (!newlist)
return NULL;
- d = newlist->d;
- memcpy ( d, head, n ); d += n;
- *d++ = ST_STOP;
- }
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ }
else
- newlist = NULL;
+ newlist = NULL;

return normalize (newlist);
}




_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel [at] gnupg
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel


wk at gnupg

Feb 17, 2012, 8:17 AM

Post #2 of 4 (380 views)
Permalink
Re: Malfunction of gcry_sexp_car [In reply to]

On Thu, 16 Feb 2012 22:09, benjamin.pousse [at] member said:

> Please find at the end of this mail my patch to solve this problem (the
> patch is large because I apply a regular indentation on the full
> function).

Thanks for looking into this.

Can you please send a patch without that indentation change. That makes
it easier to see what you did. A small patch may also be applied
without signing a copyright assignment or a disclaimer.

Indentation changes should be done by a separate patch; it is also best
to let one of the core hackers do that.


Shalom-Salam,

Werner

--
Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz.


_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel [at] gnupg
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel


benjamin.pousse at member

Feb 17, 2012, 9:23 AM

Post #3 of 4 (386 views)
Permalink
Re: Malfunction of gcry_sexp_car [In reply to]

Hello,

Le vendredi 17 février 2012 à 17:17 +0100, Werner Koch a écrit :
> On Thu, 16 Feb 2012 22:09, benjamin.pousse [at] member said:
>
> > Please find at the end of this mail my patch to solve this problem (the
> > patch is large because I apply a regular indentation on the full
> > function).
>
> Thanks for looking into this.
>
> Can you please send a patch without that indentation change. That makes
> it easier to see what you did.
Of course. Here it is.

Regards,
Benjamin.


diff --git a/src/sexp.c b/src/sexp.c
index 0877773..2450c82 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -576,13 +576,24 @@ gcry_sexp_nth( const gcry_sexp_t list, int number
)
p++;

if ( *p == ST_DATA ) {
- memcpy ( &n, p, sizeof n ); p += sizeof n;
- newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ memcpy ( &n, p, sizeof n );
+ /* Allocate 1 (=sizeof *newlist) byte for ST_OPEN
+ 1 byte for ST_DATA
+ sizeof n byte for n
+ n byte for the data
+ 1 byte for ST_CLOSE
+ 1 byte for ST_STOP */
+ newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 );
if (!newlist)
return NULL;
d = newlist->d;
- memcpy ( d, p, n ); d += n;
- *d++ = ST_STOP;
+ *d = ST_OPEN; /* Put the ST_OPEN flag */
+ d++; /* Move forward */
+ memcpy ( d, p, 1 + sizeof n + n ); /* Copy ST_DATA, n and the data
from p to d */
+ d += 1 + sizeof n + n; /* Move after the data copied */
+ *d = ST_CLOSE; /* Put the ST_CLOSE flag */
+ d++; /* Move forward */
+ *d = ST_STOP; /* Put the ST_STOP flag */
}
else if ( *p == ST_OPEN ) {
const byte *head = p;




_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel [at] gnupg
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel


benjamin.pousse at member

Feb 17, 2012, 1:16 PM

Post #4 of 4 (380 views)
Permalink
Re: Malfunction of gcry_sexp_car [In reply to]

2012/2/17 Andre Amorim <andre [at] amorim>:
> I cant read the code, need to USE "TAB" (80, col) format
>

Sorry for this. Looks like my mail manager sends lines of 71 characters.
Let's try with my webmail :


diff --git a/src/sexp.c b/src/sexp.c
index 0877773..380235b 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -576,13 +576,25 @@ gcry_sexp_nth( const gcry_sexp_t list, int number )
p++;

if ( *p == ST_DATA ) {
- memcpy ( &n, p, sizeof n ); p += sizeof n;
- newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ memcpy ( &n, p, sizeof n );
+ /* Allocate 1 (=sizeof *newlist) byte for ST_OPEN
+ 1 byte for ST_DATA
+ sizeof n byte for n
+ n byte for the data
+ 1 byte for ST_CLOSE
+ 1 byte for ST_STOP */
+ newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 );
if (!newlist)
return NULL;
- d = newlist->d;
- memcpy ( d, p, n ); d += n;
- *d++ = ST_STOP;
+ d = newlist->d;
+ *d = ST_OPEN; /* Put the ST_OPEN flag */
+ d++; /* Move forward */
+ /* Copy ST_DATA, n and the data from p to d */
+ memcpy ( d, p, 1 + sizeof n + n );
+ d += 1 + sizeof n + n; /* Move after the data copied */
+ *d = ST_CLOSE; /* Put the ST_CLOSE flag */
+ d++; /* Move forward */
+ *d = ST_STOP; /* Put the ST_STOP flag */
}
else if ( *p == ST_OPEN ) {
const byte *head = p;

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel [at] gnupg
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel

GnuPG gcrypt RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.