[segyio] 51/376: Sanitise open input; open files in binary mode

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:06 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 65153a98a2b8aa22477a7b10dc6d26390a31c3a6
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Tue Oct 18 16:14:13 2016 +0200

    Sanitise open input; open files in binary mode
    
    Winwdows testing demonstrates the need on non-posix systems to open
    files in binary mode. Sanitises the fopen input which would crash on
    windows (but fail gracefully on posix).
---
 mex/segy_get_header_mex.c       |  2 +-
 mex/segy_get_ntraces_mex.c      |  2 +-
 mex/segy_get_segy_header_mex.c  |  2 +-
 mex/segy_get_trace_header_mex.c |  2 +-
 mex/segy_get_traces_mex.c       |  2 +-
 mex/segy_put_headers_mex.c      |  2 +-
 mex/segy_put_traces_mex.c       |  2 +-
 mex/segy_read_write_line_mex.c  |  4 ++--
 python/segyio/_segyio.c         | 36 +++++++++++++++++++++++++++++++++---
 python/segyio/segy.py           |  1 +
 src/applications/segyinfo.c     |  2 +-
 src/applications/segyinspect.c  |  2 +-
 src/spec/segyspec.c             |  2 +-
 tests/test_segy.c               | 14 +++++++-------
 14 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/mex/segy_get_header_mex.c b/mex/segy_get_header_mex.c
index 8cf3808..37c9780 100644
--- a/mex/segy_get_header_mex.c
+++ b/mex/segy_get_header_mex.c
@@ -16,7 +16,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     int err;
 
     const char* filename = mxArrayToString( prhs[ 0 ] );
-    FILE* fp = segyfopen( prhs[ 0 ], "r" );
+    FILE* fp = segyfopen( prhs[ 0 ], "rb" );
 
     int field = mxGetScalar( prhs[ 1 ] );
 
diff --git a/mex/segy_get_ntraces_mex.c b/mex/segy_get_ntraces_mex.c
index 7f35172..66e8ae2 100644
--- a/mex/segy_get_ntraces_mex.c
+++ b/mex/segy_get_ntraces_mex.c
@@ -6,7 +6,7 @@
 void mexFunction(int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[]) {
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r" );
+    FILE* fp = segyfopen( prhs[ 0 ], "rb" );
     struct segy_file_format fmt = filefmt( fp );
     fclose( fp );
 
diff --git a/mex/segy_get_segy_header_mex.c b/mex/segy_get_segy_header_mex.c
index f8008f9..8ef5f76 100644
--- a/mex/segy_get_segy_header_mex.c
+++ b/mex/segy_get_segy_header_mex.c
@@ -14,7 +14,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     char* msg2;
     int err;
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r" );
+    FILE* fp = segyfopen( prhs[ 0 ], "rb" );
     char* textheader = mxMalloc( segy_textheader_size() );
     err = segy_read_textheader( fp, textheader );
     
diff --git a/mex/segy_get_trace_header_mex.c b/mex/segy_get_trace_header_mex.c
index d46bebd..1d4305a 100644
--- a/mex/segy_get_trace_header_mex.c
+++ b/mex/segy_get_trace_header_mex.c
@@ -14,7 +14,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     char* msg2;
     int err;
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r" );
+    FILE* fp = segyfopen( prhs[ 0 ], "rb" );
     struct segy_file_format fmt = filefmt( fp );
     int traceno = mxGetScalar( prhs[ 1 ] );
 
diff --git a/mex/segy_get_traces_mex.c b/mex/segy_get_traces_mex.c
index 7f04589..10aec29 100644
--- a/mex/segy_get_traces_mex.c
+++ b/mex/segy_get_traces_mex.c
@@ -14,7 +14,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     char* msg2;
     int err;
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r" );
+    FILE* fp = segyfopen( prhs[ 0 ], "rb" );
     int first_trace = mxGetScalar( prhs[ 1 ] );
     int last_trace  = mxGetScalar( prhs[ 2 ] );
     int notype      = mxGetScalar( prhs[ 3 ] );
diff --git a/mex/segy_put_headers_mex.c b/mex/segy_put_headers_mex.c
index abba4db..8835019 100644
--- a/mex/segy_put_headers_mex.c
+++ b/mex/segy_put_headers_mex.c
@@ -14,7 +14,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     char* msg2;
     int err;
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r+" );
+    FILE* fp = segyfopen( prhs[ 0 ], "r+b" );
     double* headers = mxGetPr( prhs[ 1 ] );
     int field = mxGetScalar( prhs[ 2 ] );
 
diff --git a/mex/segy_put_traces_mex.c b/mex/segy_put_traces_mex.c
index df317dd..51acf19 100644
--- a/mex/segy_put_traces_mex.c
+++ b/mex/segy_put_traces_mex.c
@@ -14,7 +14,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     char* msg2;
     int err;
 
-    FILE* fp = segyfopen( prhs[ 0 ], "r+" );
+    FILE* fp = segyfopen( prhs[ 0 ], "r+b" );
     plhs[ 0 ] = mxDuplicateArray( prhs[ 1 ] );
     int first_trace = mxGetScalar( prhs[ 2 ] );
     int last_trace  = mxGetScalar( prhs[ 3 ] );
diff --git a/mex/segy_read_write_line_mex.c b/mex/segy_read_write_line_mex.c
index 5bbf9a2..8ccf929 100644
--- a/mex/segy_read_write_line_mex.c
+++ b/mex/segy_read_write_line_mex.c
@@ -52,7 +52,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
     }
 
     if (read) {
-        fp = fopen( spec.filename, "r" );
+        fp = fopen( spec.filename, "rb" );
         if (fp == NULL) {
             goto CLEANUP;
         }
@@ -71,7 +71,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
         }
     }
     else {
-        fp = fopen( spec.filename, "r+" );
+        fp = fopen( spec.filename, "r+b" );
         if (fp == NULL) {
             goto CLEANUP;
         }
diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index 83a347b..4206ecc 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -1,6 +1,14 @@
-#include <Python.h>
+#if defined(_DEBUG) && defined(_MSC_VER)
+#  define _CRT_NOFORCE_MAINFEST 1
+#  undef _DEBUG
+#  include <Python.h>
+#  define _DEBUG 1
+#else
+#  include <Python.h>
+#endif
 #include "segyio/segy.h"
 #include <assert.h>
+#include <string.h>
 
 // ---------------  FILE Handling ------------
 static FILE *get_FILE_pointer_from_capsule(PyObject *capsule) {
@@ -33,9 +41,31 @@ static void *py_FILE_destructor(PyObject *capsule) {
 static PyObject *py_FILE_open(PyObject *self, PyObject *args) {
     char *filename = NULL;
     char *mode = NULL;
-    PyArg_ParseTuple(args, "ss", &filename, &mode);
+    int mode_len = 0;
+    PyArg_ParseTuple(args, "ss#", &filename, &mode, &mode_len);
+
+    if( mode_len == 0 ) {
+        PyErr_SetString(PyExc_IOError, "Mode string must be non-empty");
+        return NULL;
+    }
+
+    // append a 'b' if it is not passed by the user; not a problem on unix, but
+    // windows and other platforms fail without it
+    // the heap alloc is expensive, but avoids the risk of local stack
+    // smashing and is C++ compatible
+    char* binary_mode = strcpy( calloc( mode_len + 2, sizeof( char ) ), mode );
+    if( binary_mode[ mode_len - 1 ] != 'b' ) binary_mode[ mode_len ] = 'b';
+
+     // Account for invalid mode. On unix this is fine, but windows crashes the
+     // process if mode is invalid
+    if( !strstr( "rb" "wb" "ab" "r+b" "w+b" "a+b", binary_mode ) ) {
+        PyErr_Format( PyExc_IOError, "Invalid mode string '%s'", binary_mode );
+        free( binary_mode );
+        return NULL;
+    }
 
-    FILE *p_FILE = fopen(filename, mode);
+    FILE *p_FILE = fopen( filename, binary_mode );
+    free( binary_mode );
 
     if (p_FILE == NULL) {
         return PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
diff --git a/python/segyio/segy.py b/python/segyio/segy.py
index 77d4cfc..d732147 100644
--- a/python/segyio/segy.py
+++ b/python/segyio/segy.py
@@ -32,6 +32,7 @@ class SegyFile(object):
         """
         Constructor, internal.
         """
+
         self._filename = filename
         self._mode = mode
         self._il = iline
diff --git a/src/applications/segyinfo.c b/src/applications/segyinfo.c
index 514db1f..9efb717 100644
--- a/src/applications/segyinfo.c
+++ b/src/applications/segyinfo.c
@@ -33,7 +33,7 @@ int main(int argc, char* argv[]) {
         exit(1);
     }
 
-    FILE* fp = fopen( argv[ 1 ], "r" );
+    FILE* fp = fopen( argv[ 1 ], "rb" );
     if( !fp ) {
         perror( "fopen():" );
         exit( 3 );
diff --git a/src/applications/segyinspect.c b/src/applications/segyinspect.c
index b2c1b4a..479e645 100644
--- a/src/applications/segyinspect.c
+++ b/src/applications/segyinspect.c
@@ -54,7 +54,7 @@ int main(int argc, char* argv[]) {
 
     clock_t start = clock();
 
-    FILE* fp = fopen( argv[ 1 ], "r" );
+    FILE* fp = fopen( argv[ 1 ], "rb" );
     if( !fp ) {
         perror( "fopen()" );
         exit( SEGY_FOPEN_ERROR );
diff --git a/src/spec/segyspec.c b/src/spec/segyspec.c
index b326d0e..798a7d7 100644
--- a/src/spec/segyspec.c
+++ b/src/spec/segyspec.c
@@ -15,7 +15,7 @@ int segyCreateSpec(SegySpec* spec, const char* file, unsigned int inline_field,
 
     int errc = 0;
 
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
     if (fp == NULL) {
         fprintf(stderr, "Unable to open file: '%s'\n", file);
         return -1;
diff --git a/tests/test_segy.c b/tests/test_segy.c
index b7c4560..ee30999 100644
--- a/tests/test_segy.c
+++ b/tests/test_segy.c
@@ -22,7 +22,7 @@ void test_interpret_file() {
     const int il = INLINE_3D;
     const int xl = CROSSLINE_3D;
 
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
 
     assertTrue( fp != NULL, "Could not open file." );
     err = segy_binheader( fp, header );
@@ -211,7 +211,7 @@ void testReadInLine_4(){
 
     char header[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
     assertTrue( 0 == segy_binheader( fp, header ), "Could not read header" );
     const long trace0 = segy_trace0( header );
     const unsigned int samples = segy_samples( header );
@@ -286,7 +286,7 @@ void testReadCrossLine_22(){
 
     char header[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
     assertTrue( 0 == segy_binheader( fp, header ), "Could not read header" );
     const long trace0 = segy_trace0( header );
     const unsigned int samples = segy_samples( header );
@@ -355,7 +355,7 @@ void test_modify_trace_header() {
     int err;
     char bheader[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "r+" );
+    FILE* fp = fopen( file, "r+b" );
     err = segy_binheader( fp, bheader );
     assertTrue( err == 0, "Could not read header" );
     const long trace0 = segy_trace0( bheader );
@@ -439,7 +439,7 @@ static const char* expected_textheader =
 
 void test_text_header() {
     const char *file = "test-data/text.sgy";
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
 
     char ascii[ SEGY_TEXT_HEADER_SIZE + 1 ] = { 0 };
     int err = segy_read_textheader(fp, ascii);
@@ -451,7 +451,7 @@ void test_text_header() {
 
 void test_trace_header_errors() {
     const char *file = "test-data/small.sgy";
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
     int err;
 
     char binheader[ SEGY_BINARY_HEADER_SIZE ];
@@ -486,7 +486,7 @@ void test_trace_header_errors() {
 
 void test_file_error_codes() {
     const char *file = "test-data/small.sgy";
-    FILE* fp = fopen( file, "r" );
+    FILE* fp = fopen( file, "rb" );
     fclose( fp );
 
     int err;

-- 
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