[ 
https://issues.apache.org/jira/browse/ZOOKEEPER-1906?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Nikita Vetoshkin updated ZOOKEEPER-1906:
----------------------------------------

    Description: 
In python if we ask {{zookeeper.get}} (which translates into {{pyzoo_get}}) for 
empty node we can get trash in result on Python level. Issue is pretty tricky. 
It goes like this:
  * python C extension allocates buffer with malloc (({{buffer = 
malloc(sizeof(char)*buffer_len);}} and calls {{zoo_wget}} providing both 
{{buffer}} and {{buffer_len}}.
  * deserialize_GetDataResponse deserializes empty buffer and sets 
{{buffer_len}} to -1 and {{zoo_wget}} returns.
  * python C extension calls {{Py_BuildValue( "(s#,N)", buffer,buffer_len ...}} 
with {{buffer_len}} set to -1.
  * {{Py_BuildValue}} calls {{do_mkvalue}} to build python string which falls 
back to {{strlen(str)}} in case string length ({{buffer_len < 0}}) - that's our 
case.
  * *usually* strlen returns 0, because e.g. linux uses magic zero filled page 
as result of mmap (which is being copied upon page fault, i.e. when you want to 
write to it)
  * everything works!

But on FreeBSD (not always) we can get random data in {{malloc}} result and 
this trash will be exposed to the user.

Not sure about the right way to fix this, but something like
{noformat}
Index: src/contrib/zkpython/src/c/zookeeper.c
===================================================================
--- src/contrib/zkpython/src/c/zookeeper.c      (revision 1583238)
+++ src/contrib/zkpython/src/c/zookeeper.c      (working copy)
@@ -1223,7 +1223,7 @@
   }
 
   PyObject *stat_dict = build_stat( &stat );
-  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len, stat_dict );
+  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len < 0 ? 0 : 
buffer_len, stat_dict );
   free(buffer);
 
   return ret;
{noformat}
should do the trick

  was:
In python if we ask {{zookeeper.get}} (which translates into {{pyzoo_get}}) for 
empty node we can get trash in result on Python level. Issue is pretty tricky. 
It goes like this:
  * python C extension allocates buffer with malloc (({{buffer = 
malloc(sizeof(char)*buffer_len);}} and calls {{zoo_wget}} providing both 
{{buffer}} and {{buffer_len}}.
  * deserialize_GetDataResponse deserializes empty buffer and sets 
{{buffer_len}} to -1 and {{zoo_wget}} returns.
  * python C extension calls {{Py_BuildValue( "(s#,N)", buffer,buffer_len ...}} 
with {{buffer_len}} set to -1.
  * {{Py_BuildValue}} calls {{do_mkvalue}} to build python string which falls 
back to {{strlen(str)}} in case string length ({{buffer_len < 0}}) - that's our 
case.
  * *usually* strlen returns 0, because e.g. linux uses magic zero filled page 
as result of mmap (which is being copied upon page fault, i.e. when you want to 
right to it)
  * everything works!

But on FreeBSD (not always) we can get random data in {{malloc}} result and 
this trash will be exposed to the user.

Not sure about the right way to fix this, but something like
{noformat}
Index: src/contrib/zkpython/src/c/zookeeper.c
===================================================================
--- src/contrib/zkpython/src/c/zookeeper.c      (revision 1583238)
+++ src/contrib/zkpython/src/c/zookeeper.c      (working copy)
@@ -1223,7 +1223,7 @@
   }
 
   PyObject *stat_dict = build_stat( &stat );
-  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len, stat_dict );
+  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len < 0 ? 0 : 
buffer_len, stat_dict );
   free(buffer);
 
   return ret;
{noformat}
should do the trick


> zkpython: invalid data in GetData for empty node
> ------------------------------------------------
>
>                 Key: ZOOKEEPER-1906
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1906
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: contrib-bindings
>         Environment: FreeBSD
>            Reporter: Nikita Vetoshkin
>
> In python if we ask {{zookeeper.get}} (which translates into {{pyzoo_get}}) 
> for empty node we can get trash in result on Python level. Issue is pretty 
> tricky. It goes like this:
>   * python C extension allocates buffer with malloc (({{buffer = 
> malloc(sizeof(char)*buffer_len);}} and calls {{zoo_wget}} providing both 
> {{buffer}} and {{buffer_len}}.
>   * deserialize_GetDataResponse deserializes empty buffer and sets 
> {{buffer_len}} to -1 and {{zoo_wget}} returns.
>   * python C extension calls {{Py_BuildValue( "(s#,N)", buffer,buffer_len 
> ...}} with {{buffer_len}} set to -1.
>   * {{Py_BuildValue}} calls {{do_mkvalue}} to build python string which falls 
> back to {{strlen(str)}} in case string length ({{buffer_len < 0}}) - that's 
> our case.
>   * *usually* strlen returns 0, because e.g. linux uses magic zero filled 
> page as result of mmap (which is being copied upon page fault, i.e. when you 
> want to write to it)
>   * everything works!
> But on FreeBSD (not always) we can get random data in {{malloc}} result and 
> this trash will be exposed to the user.
> Not sure about the right way to fix this, but something like
> {noformat}
> Index: src/contrib/zkpython/src/c/zookeeper.c
> ===================================================================
> --- src/contrib/zkpython/src/c/zookeeper.c    (revision 1583238)
> +++ src/contrib/zkpython/src/c/zookeeper.c    (working copy)
> @@ -1223,7 +1223,7 @@
>    }
>  
>    PyObject *stat_dict = build_stat( &stat );
> -  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len, stat_dict );
> +  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len < 0 ? 0 : 
> buffer_len, stat_dict );
>    free(buffer);
>  
>    return ret;
> {noformat}
> should do the trick



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to