[reportlab-users] Re: FutureWarnings in ttfonts.py with Python 2.3

Marius Gedminas reportlab-users@reportlab.com
Mon, 5 Apr 2004 22:40:22 +0300

Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Apr 05, 2004 at 01:34:57PM +0100, Robin Becker wrote:
> Marius Gedminas wrote:
> >I spent a few minutes experimenting with various variants of add32 a
> >while ago.  I was quite suprised to find out that using Python's longs
> >with bit shifts/addition modulo 2**32 did not give the desired results
> >when negative numbers came into the picture.
> I'm a bit puzzled as I thought we're supposed to be adding unsigned 32 bi=
> numbers.

The arguments and the result value of add32 are Python's ints, i.e.
signed 32-bit integers.  There's no other reason for them to be signed.

The only operations done when calculating checksums are addition and
subtraction, and at the bitwise level those operations do not
distinguish between signed and unsigned numbers.  (I'm assuming two's
complement arithmetic here.)

I suppose the checksumming code could be changed to always use unsigned
longs and never worry about OverflowErrors on older pythons.  I think
the loss of speed is acceptable, because for speed-conscious uses we
have rlaccel.

> So can we not use
> def add32(x,y): return _L2U32((x+y) & 0xffffffffL)

The unit tests say that you can.  <wink>

> I'm fairly sure the more complex stuff doesn't work with older pythons
> any how.
> I get this in Python-2.1 with the above
> >>> add32(0xfffffffe,1)
> -1
> >>> add32(0xfffffffe,2)
> 0
> >>> add32(0xffffffff,2)
> 1
> >>> add32(-1,1)
> 0
> >>>

but in Python 2.1

  >>> add32(2147483647, 1)
  OverflowError: integer literal too large

(should return -2147483648)

> I get the same in Python-2.3, but have to use long constants to avoid the=
> warnings.

Perhaps it's simpler to just use the old function (with ugly bit shifts)
in Python < 2.3 and the new function on Python >=3D 2.3.

Note that add32 is only used in a couple of places and is never called
in a loop, so it does not have to be very efficient.

calcChecksum is basically add32 in a loop and needs to be efficient.
(That's why it has the code of add32 inlined in the first place.)

Oops.  I think I found a bug in ttfonts.py.  It contains several
instances of code like this to calculate (x - y) mod 2^32:

  checkSum =3D add32(checkSum, -adjustment)

In fact all calls to add32 are used to simulate subtraction.  The
problem is that when adjustment =3D=3D 0x80000000, calculating -adjustment
will raise an OverflowError on older Pythons.  I don't know if it will
work correctly for newer Pythons, but I wouldn't be surprised to find it

Proposal: ditch add32 and introduce sub32 that calculates (x - y) mod

Marius Gedminas
Most security experts REALLY believe in firewalls. The expect that, when th=
die, arrive at the great firewall in the sky where Saint Peter is running a
default policy of REJECT.
		--- Sander Plomp

Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

Version: GnuPG v1.2.4 (GNU/Linux)