[segyio] 99/376: Remove undefined pointer casts

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:15 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit a936695b2a20f5be70b838f9fd2f972b6e13df7d
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Mon Nov 7 16:06:39 2016 +0100

    Remove undefined pointer casts
    
    Restrict aliasing slightly and remove a source of undefined behaviour by
    casting float pointers to uint32_t. Reimplements the ieee<->ibm
    functions to work on one float at the time without triggering undefined
    behaviour.
---
 python/segyio/_segyio.c |   6 +-
 src/segyio/segy.c       | 178 +++++++++++++++++++++++++-----------------------
 src/segyio/segy.h       |   4 +-
 src/segyio/util.h       |   4 +-
 tests/test_utils.c      |   6 +-
 5 files changed, 102 insertions(+), 96 deletions(-)

diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index 36be7e5..3d2ecc4 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -755,11 +755,11 @@ static PyObject *py_read_trace(PyObject *self, PyObject *args) {
     }
 
     int error = 0;
-    char* buf = buffer.buf;
+    float* buf = buffer.buf;
     Py_ssize_t i;
 
-    for( i = 0; error == 0 && i < length; ++i, buf += trace_bsize ) {
-        error = segy_readtrace(p_FILE, start + (i * step), (float*)buf, trace0, trace_bsize);
+    for( i = 0; error == 0 && i < length; ++i, buf += samples ) {
+        error = segy_readtrace(p_FILE, start + (i * step), buf, trace0, trace_bsize);
     }
 
     int conv_error = segy_to_native(format, length * samples, buffer.buf);
diff --git a/src/segyio/segy.c b/src/segyio/segy.c
index cb8dda6..6814770 100644
--- a/src/segyio/segy.c
+++ b/src/segyio/segy.c
@@ -65,94 +65,92 @@ void ascii2ebcdic( const char* ascii, char* ebcdic ) {
     *ebcdic = '\0';
 }
 
-void ibm2ieee(void* to, const void* from, int len) {
-    register unsigned fr; /* fraction */
+void ibm2ieee( void* to, const void* from ) {
+    uint32_t fr;      /* fraction */
     register int exp; /* exponent */
-    register int sgn; /* sign */
-
-    for (; len-- > 0; to = (char*) to + 4, from = (const char*) from + 4) {
-        /* split into sign, exponent, and fraction */
-        fr = ntohl(*(const int32_t*) from); /* pick up value */
-        sgn = fr >> 31; /* save sign */
-        fr <<= 1; /* shift sign out */
-        exp = fr >> 25; /* save exponent */
-        fr <<= 7; /* shift exponent out */
-
-        if (fr == 0) { /* short-circuit for zero */
-            exp = 0;
-            goto done;
-        }
+    uint32_t sgn;     /* sign */
+
+    memcpy( &fr, from, sizeof( uint32_t ) );
+    /* split into sign, exponent, and fraction */
+    fr = ntohl( fr ); /* pick up value */
+    sgn = fr >> 31; /* save sign */
+    fr <<= 1; /* shift sign out */
+    exp = fr >> 25; /* save exponent */
+    fr <<= 7; /* shift exponent out */
+
+    if (fr == 0) { /* short-circuit for zero */
+        exp = 0;
+        goto done;
+    }
 
-        /* adjust exponent from base 16 offset 64 radix point before first digit
-         * to base 2 offset 127 radix point after first digit
-         * (exp - 64) * 4 + 127 - 1 == exp * 4 - 256 + 126 == (exp << 2) - 130 */
-        exp = (exp << 2) - 130;
+    /* adjust exponent from base 16 offset 64 radix point before first digit
+     * to base 2 offset 127 radix point after first digit
+     * (exp - 64) * 4 + 127 - 1 == exp * 4 - 256 + 126 == (exp << 2) - 130 */
+    exp = (exp << 2) - 130;
 
-        /* (re)normalize */
-        while (fr < 0x80000000) { /* 3 times max for normalized input */
-            --exp;
-            fr <<= 1;
-        }
+    /* (re)normalize */
+    while (fr < 0x80000000) { /* 3 times max for normalized input */
+        --exp;
+        fr <<= 1;
+    }
 
-        if (exp <= 0) { /* underflow */
-            if (exp < -24) /* complete underflow - return properly signed zero */
-                fr = 0;
-            else /* partial underflow - return denormalized number */
-                fr >>= -exp;
-            exp = 0;
-        } else if (exp >= 255) { /* overflow - return infinity */
+    if (exp <= 0) { /* underflow */
+        if (exp < -24) /* complete underflow - return properly signed zero */
             fr = 0;
-            exp = 255;
-        } else { /* just a plain old number - remove the assumed high bit */
-            fr <<= 1;
-        }
-
-        done:
-        /* put the pieces back together and return it */
-        *(unsigned*) to = (fr >> 9) | (exp << 23) | (sgn << 31);
+        else /* partial underflow - return denormalized number */
+            fr >>= -exp;
+        exp = 0;
+    } else if (exp >= 255) { /* overflow - return infinity */
+        fr = 0;
+        exp = 255;
+    } else { /* just a plain old number - remove the assumed high bit */
+        fr <<= 1;
     }
+
+done:
+    /* put the pieces back together and return it */
+    fr = (fr >> 9) | (exp << 23) | (sgn << 31);
+    memcpy( to, &fr, sizeof( uint32_t ) );
 }
 
-void ieee2ibm(void* to, const void* from, int len) {
-    register unsigned fr; /* fraction */
+void ieee2ibm( void* to, const void* from ) {
+    uint32_t fr;      /* fraction */
     register int exp; /* exponent */
-    register int sgn; /* sign */
-
-    for (; len-- > 0; to = (char*) to + 4, from = (const char*) from + 4) {
-        /* split into sign, exponent, and fraction */
-        fr = *(const unsigned*) from; /* pick up value */
-        sgn = fr >> 31; /* save sign */
-        fr <<= 1; /* shift sign out */
-        exp = fr >> 24; /* save exponent */
-        fr <<= 8; /* shift exponent out */
-
-        if (exp == 255) { /* infinity (or NAN) - map to largest */
-            fr = 0xffffff00;
-            exp = 0x7f;
-            goto done;
-        }
-        else if (exp > 0) /* add assumed digit */
-            fr = (fr >> 1) | 0x80000000;
-        else if (fr == 0) /* short-circuit for zero */
-            goto done;
-
-        /* adjust exponent from base 2 offset 127 radix point after first digit
-         * to base 16 offset 64 radix point before first digit */
-        exp += 130;
-        fr >>= -exp & 3;
-        exp = (exp + 3) >> 2;
-
-        /* (re)normalize */
-        while (fr < 0x10000000) { /* never executed for normalized input */
-            --exp;
-            fr <<= 4;
-        }
-
-        done:
-        /* put the pieces back together and return it */
-        fr = (fr >> 8) | (exp << 24) | (sgn << 31);
-        *(unsigned*) to = htonl(fr);
+    uint32_t sgn;     /* sign */
+
+    /* split into sign, exponent, and fraction */
+    memcpy( &fr, from, sizeof( uint32_t ) ); /* pick up value */
+    sgn = fr >> 31; /* save sign */
+    fr <<= 1; /* shift sign out */
+    exp = fr >> 24; /* save exponent */
+    fr <<= 8; /* shift exponent out */
+
+    if (exp == 255) { /* infinity (or NAN) - map to largest */
+        fr = 0xffffff00;
+        exp = 0x7f;
+        goto done;
     }
+    else if (exp > 0) /* add assumed digit */
+        fr = (fr >> 1) | 0x80000000;
+    else if (fr == 0) /* short-circuit for zero */
+        goto done;
+
+    /* adjust exponent from base 2 offset 127 radix point after first digit
+     * to base 16 offset 64 radix point before first digit */
+    exp += 130;
+    fr >>= -exp & 3;
+    exp = (exp + 3) >> 2;
+
+    /* (re)normalize */
+    while (fr < 0x10000000) { /* never executed for normalized input */
+        --exp;
+        fr <<= 4;
+    }
+
+done:
+    /* put the pieces back together and return it */
+    fr = htonl( (fr >> 8) | (exp << 24) | (sgn << 31) );
+    memcpy( to, &fr, sizeof( uint32_t ) );
 }
 
 /* Lookup table for field sizes. All values not explicitly set are 0 */
@@ -888,41 +886,49 @@ int segy_writetrace( FILE* fp,
 }
 
 int segy_to_native( int format,
-                    unsigned int size,
+                    int size,
                     float* buf ) {
 
     assert( sizeof( float ) == sizeof( uint32_t ) );
 
+    uint32_t u;
     if( format == IEEE_FLOAT_4_BYTE ) {
-        uint32_t u;
         while( size-- ) {
             memcpy( &u, buf, sizeof( float ) );
             u = ntohl( u );
             memcpy( buf++, &u, sizeof( float ) );
         }
     }
-    else
-        ibm2ieee( buf, buf, size );
+    else {
+        while( size-- ) {
+            ibm2ieee( &u, buf );
+            memcpy( buf++, &u, sizeof( float ) );
+        }
+    }
 
     return SEGY_OK;
 }
 
 int segy_from_native( int format,
-                      unsigned int size,
+                      int size,
                       float* buf ) {
 
     assert( sizeof( float ) == sizeof( uint32_t ) );
 
+    uint32_t u;
     if( format == IEEE_FLOAT_4_BYTE ) {
-        uint32_t u;
         while( size-- ) {
             memcpy( &u, buf, sizeof( float ) );
             u = htonl( u );
             memcpy( buf++, &u, sizeof( float ) );
         }
     }
-    else
-        ieee2ibm( buf, buf, size );
+    else {
+        while( size-- ) {
+            ieee2ibm( &u, buf );
+            memcpy( buf++, &u, sizeof( float ) );
+        }
+    }
 
     return SEGY_OK;
 }
diff --git a/src/segyio/segy.h b/src/segyio/segy.h
index c9b0baf..3d9a444 100644
--- a/src/segyio/segy.h
+++ b/src/segyio/segy.h
@@ -114,11 +114,11 @@ int segy_writetrace( FILE*,
 
 /* convert to/from native float from segy formats (likely IBM or IEEE) */
 int segy_to_native( int format,
-                    unsigned int size,
+                    int size,
                     float* buf );
 
 int segy_from_native( int format,
-                      unsigned int size,
+                      int size,
                       float* buf );
 
 int segy_read_line( FILE* fp,
diff --git a/src/segyio/util.h b/src/segyio/util.h
index 6292e85..b39e49a 100644
--- a/src/segyio/util.h
+++ b/src/segyio/util.h
@@ -10,8 +10,8 @@
 
 void ebcdic2ascii( const char* ebcdic, char* ascii );
 void ascii2ebcdic( const char* ascii, char* ebcdic );
-void ibm2ieee(void* to, const void* from, int len);
-void ieee2ibm(void* to, const void* from, int len);
+void ibm2ieee(void* to, const void* from);
+void ieee2ibm(void* to, const void* from);
 int segy_seek( FILE*, unsigned int, long, unsigned int );
 
 #endif //SEGYIO_UTILS_H
diff --git a/tests/test_utils.c b/tests/test_utils.c
index ab67663..f1b942c 100644
--- a/tests/test_utils.c
+++ b/tests/test_utils.c
@@ -57,9 +57,9 @@ static void check(float f1, double * epsm) {
     unsigned ibm1, ibm2;
 
     frexp(f1, &exp);
-    ieee2ibm(&ibm1, &f1, 1);
-    ibm2ieee(&f2, &ibm1, 1);
-    ieee2ibm(&ibm2, &f2, 1);
+    ieee2ibm(&ibm1, &f1);
+    ibm2ieee(&f2, &ibm1);
+    ieee2ibm(&ibm2, &f2);
 
     assertTrue(memcmp(&ibm1, &ibm2, sizeof ibm1) == 0, "The content of two memory areas were not identical!");
     //printf("Error: %08x <=> %08x\n", *(unsigned*) &ibm1, *(unsigned*) &ibm2);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list