Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Critical bug in "Pyro 1.3" and another minor bug

Última Actualización: 16 de Octubre de 2.000 - Martes

Pyro es un sistema de híbrido entre llamada a procedimiento remoto y esquemas tipo CORBA, implementado 100% en Python. Los dos errores que se comentan en este mensaje fueron subsanados en la versión 1.4 de Pyro.

From: Jesus Cea Avion <jcea@argo.es>
Newsgroups: comp.lang.python
Subject: Critical bug in "Pyro 1.3" and another minor bug
Date: Fri, 06 Oct 2000 20:23:54 +0200
Organization: Argo Redes y Servicios Telematicos, S.A. - http://www.argo.es/
Message-ID: <39DE18BA.A7576D2E@argo.es>
To: irmen@bigfoot.com

I've just downloaded [Pyro 1.3], but it didn't work. After almost three hours debugging the "name server", I found the following bug. I think that it's a critical one.

In "util.py", you have:

>>>>>
# asc2binGUID converts a string guid to a binary one (16-byte string):
def asc2binGUID(guid):
        try:
                return int2binstr(eval('0x'+guid[:8]+'L')) + \
                        int2binstr(eval('0x'+guid[9:17]+'L')) + \
                        int2binstr(eval('0x'+guid[18:26]+'L')) + \
                        int2binstr(eval('0x'+guid[27:]+'L'))
        except SyntaxError:
                raise ValueError('invalid GUID format')

<<<<<

BUT, the problem is:

>>>>>
def int2binstr(i):
        s=''
        while i>0:
                s=chr(i&0xFF)+s
                i=i>>8
        return s
<<<<<

If i<0x01000000, that is, if i=0x00??????, the resulting string has *LESS* than four bytes.

Let's see:

>>> import util
>>> util.int2binstr(eval('0x'+"01234567"+"L"))
'\001#Eg' <- FOUR BYTES
>>> util.int2binstr(eval('0x'+"00112233"+"L"))
'\021"3' <- ONLY THREE BYTES

So, you can have a GUID length of less than 16 bytes. Such objects can't be found using the "ns"; they are unreachable. If the "nameserver" object had this problem, all the "name service" will be unavailable (that was the problem I was seeing).

The patch is fairly simple:

cvs diff: Diffing .
Index: util.py
===================================================================
RCS file: /opt/src/cvsroot/pyro/Pyro/util.py,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 util.py
*** util.py     2000/10/06 14:40:06     1.1.1.1
--- util.py     2000/10/06 18:16:00
***************
*** 119,127 ****
                        print
  
  
! def int2binstr(i):
        s=''
!       while i>0:
                s=chr(i&0xFF)+s
                i=i>>8
        return s
--- 119,127 ----
                        print
  
  
! def int2binstr(i,l):
        s=''
!       for a in range(l):
                s=chr(i&0xFF)+s
                i=i>>8
        return s
***************
*** 166,172 ****
        r2=(random.randint(0,sys.maxint/2)>>4) & 0xffff
        r3=(random.randint(0,sys.maxint/2)>>5) & 0xff
        rndm = (r2<<8) | r3
!       return int2binstr(networkAddr)+int2binstr(timestamp)+int2binstr(rndm)
  
  # bin2ascGUID converts a binary guid from getBinaryGUID to a readable string:
  # AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC
--- 166,172 ----
        r2=(random.randint(0,sys.maxint/2)>>4) & 0xffff
        r3=(random.randint(0,sys.maxint/2)>>5) & 0xff
        rndm = (r2<<8) | r3
!       return int2binstr(networkAddr,6)+int2binstr(timestamp,7)+int2binstr(rndm,3)
  
  # bin2ascGUID converts a binary guid from getBinaryGUID to a readable string:
  # AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC
***************
*** 180,189 ****
  # asc2binGUID converts a string guid to a binary one (16-byte string):
  def asc2binGUID(guid):
        try:
!               return int2binstr(eval('0x'+guid[:8]+'L')) + \
!                       int2binstr(eval('0x'+guid[9:17]+'L')) + \
!                       int2binstr(eval('0x'+guid[18:26]+'L')) + \
!                       int2binstr(eval('0x'+guid[27:]+'L')) 
        except SyntaxError:
                raise ValueError('invalid GUID format')
  
--- 180,189 ----
  # asc2binGUID converts a string guid to a binary one (16-byte string):
  def asc2binGUID(guid):
        try:
!               return int2binstr(eval('0x'+guid[:8]+'L'),4) + \
!                       int2binstr(eval('0x'+guid[9:17]+'L'),4) + \
!                       int2binstr(eval('0x'+guid[18:26]+'L'),4) + \
!                       int2binstr(eval('0x'+guid[27:]+'L'),4) 
        except SyntaxError:
                raise ValueError('invalid GUID format')

Another aditional problem with the "ns" is that Pyro should do a "set_reuse_addr()" on the listening socket, in order to allow launching a new "ns" just after we stop it. Without "set_reuse_addr()", you must wait several minutes to launch a new "ns" if your previous one dies or it's killed.

-- 
Jesus Cea Avion                         _/_/      _/_/_/        _/_/_/
jcea@argo.es http://www.argo.es/~jcea/ _/_/    _/_/  _/_/    _/_/  _/_/
                                      _/_/    _/_/          _/_/_/_/_/
PGP Key Available at KeyServ   _/_/  _/_/    _/_/          _/_/  _/_/
"Things are not so easy"      _/_/  _/_/    _/_/  _/_/    _/_/  _/_/
"My name is Dump, Core Dump"   _/_/_/        _/_/_/      _/_/  _/_/
"El amor es poner tu felicidad en la felicidad de otro" - Leibniz



Python Zope ©2000 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS