Python String Immutability Broken!

Hendrik van Rooyen mail at microcorp.co.za
Sun Aug 24 21:49:41 EDT 2008


South Africa. Sunday 24th August 2008.

Our South African correspondent, Waffling Swiftly, reports the
discovery of a corpse in the local cyberspace.

It is reputed to belong to a programmer who was flayed alive
by the C.L.P. group, because he had violated the immutability
of a python string.

Rumour has it that the attack was led, and the killing blow struck,
by the "KILL GIL" girl who left her lair on Irmen "Mr. Pyro"'s blog
at http://www.razorvine.net/frog/user/irmen/article/2005-02-13/45 in
order to perform the hit, using her katana.

When asked to comment, the BDFL shrugged and said:

    The guy had it coming.
    He was the architect of his own misfortune.
    Python strings _are_ immutable.


Here is the evidence:

root at dmp:/tmp/disk/ebox/iotest/lib# python
Python 2.5.2 (r252:60911, Mar  1 2008, 13:52:45)
[GCC 4.2.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = 'The quick brown fox jumps over the lazy dog and now is the time!'
>>> s
'The quick brown fox jumps over the lazy dog and now is the time!'
>>> import ctypes as c
>>> io = c.cdll.LoadLibrary('./lib_gpio.a')
>>> io.io_en()
0
>>> io.read_write(s,len(s))
255
>>> s
'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff
\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff
\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff
\xff\xff\xff\xff\xff\xff\xff'
>>>g = 'boo'
>>> io.read_write(g,len(g))
255
>>> g
'\xff\xff\xff'
>>> 

And here is the incriminating code:

WARNING: Don't do this at home.  It does low level
i/o and unless you run it on a DMP Vortex processor,
it might turn your printer into a pumpkin, or something.

YOU HAVE BEEN WARNED!


</code>

#include <stdlib.h>
#include <stdio.h>
#include <sys/io.h>
#include <unistd.h>

/* We define our read and write routines */

#define write_port(a,b) outb(b,a)
#define read_port(a) inb(a)

/* Then we hard code the port numbers we need */

#define data_0 (0x78)
#define data_1 (0x79)
#define data_2 (0x7a)

#define dir_0 (0x98)
#define dir_1 (0x99)
#define dir_2 (0x9a)


/* Here we organise permission to use the ports*/

 int io_en()
    {
    int rv = 0;
    rv = iopl(3);
    return rv;
    }

/* Then we make some dumb i/o routines for testing */

 /* first we make outputs */

 unsigned char put_0 (char x)
    {
    write_port (dir_0, 0xff);
    write_port (data_0, x);
    return 0x00;
    }

 unsigned char put_1 (char x)
    {
    write_port (dir_1, 0xff);
    write_port (data_1, x);
    return 0x00;
    }

 unsigned char put_2 (char x)
    {
    write_port (dir_2, 0xff);
    write_port (data_2, x);
    return 0x00;
    }

 /* Then we make inputs */

 unsigned char rval = 0x00;

 unsigned char get_0 ()
    {
    write_port (dir_0, 0x00);
    rval = read_port(data_0) & 0xff;
    return rval;
    }

 unsigned char get_1 ()
    {
    write_port (dir_1, 0x00);
    rval = read_port(data_1) & 0xff;
    return rval;
    }

 unsigned char get_2 ()
    {
    write_port (dir_2, 0x00);
    rval = read_port(data_2) & 0xff;
    return rval;
    }

/* This routine outputs and inputs a symmetric block of bytes, writing
   the outputs out and replacing them by the corresponding inputs */

 unsigned char read_write (unsigned char *outputs, int len)
    {
    int i = 0;
    char rv;
    while (i < len)
        {
        rv = put_1(i);          /* put out the addy */
        rv = put_0(outputs[i]); /* put out the char */
        rv = put_2('\x03');     /* make a write strobe */
        rv = put_2('\x02');
        rv = put_2('\x03');
        rv = get_0();           /* turn the bus around */
        rv = put_2('\x05');     /* make a read strobe */
        rv = put_2('\x04');
        outputs[i] = get_0();   /* read the char */
        rv = put_2('\x05');     /* 3-state bus again */
        i++;
        }
    return *outputs;
    }
</end code>

The man's dying words were supposed to be:

    You often see this pattern of inputs replacing
    outputs in DSP serial port code.
    I suppose I should have used array.array...
    aaahhrgh...!!

Flowers, comments, pitfalls, advice and money are welcome!

- Hendrik






More information about the Python-list mailing list