Skip to content

Commit dafc785

Browse files
committed
Check limits when writing fields through python
Note that this code still has little to do with segy_set_field/segy_set_field_int/segy_set_field_[type] functions, which partly check for the same restrictions. Decision about unification/removal of these functions/checks would come later when we reevaluate how much these functions are needed for "Appendix D-8. Stanza For Trace Header Layout" functionality implementation.
1 parent 8bd37dd commit dafc785

1 file changed

Lines changed: 47 additions & 16 deletions

File tree

python/segyio/segyio.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,38 +1744,69 @@ PyObject* putfield( PyObject*, PyObject *args ) {
17441744

17451745
switch ( fd.datatype ) {
17461746
case SEGY_UNSIGNED_INTEGER_8_BYTE:
1747-
fd.value.u64 = PyLong_AsUnsignedLongLong(value_arg);
1747+
{
1748+
unsigned long long val = PyLong_AsUnsignedLongLong( value_arg );
1749+
if (PyErr_Occurred() or val > UINT64_MAX) {
1750+
return ValueError( "Value out of range for unsigned long" );
1751+
}
1752+
fd.value.u64 = val;
1753+
}
17481754
break;
17491755
case SEGY_UNSIGNED_INTEGER_4_BYTE:
1750-
fd.value.u32 = PyLong_AsUnsignedLong(value_arg);
1756+
// currently no fields
1757+
// fd.value.u32 = PyLong_AsUnsignedLong(value_arg);
17511758
break;
17521759
case SEGY_UNSIGNED_SHORT_2_BYTE:
1753-
fd.value.u16 = PyLong_AsUnsignedLong(value_arg);
1760+
{
1761+
unsigned long val = PyLong_AsUnsignedLong( value_arg );
1762+
if( PyErr_Occurred() or val > UINT16_MAX ) {
1763+
return ValueError( "Value out of range for unsigned short" );
1764+
}
1765+
fd.value.u16 = val;
1766+
}
17541767
break;
17551768
case SEGY_UNSIGNED_CHAR_1_BYTE:
1756-
fd.value.u8 = PyLong_AsUnsignedLong(value_arg);
1769+
{
1770+
unsigned long val = PyLong_AsUnsignedLong( value_arg );
1771+
if( PyErr_Occurred() or val > UINT8_MAX ) {
1772+
return ValueError( "Value out of range for unsigned char" );
1773+
}
1774+
fd.value.u8 = val;
1775+
}
17571776
break;
17581777

17591778
case SEGY_SIGNED_INTEGER_8_BYTE:
1760-
fd.value.i64 = PyLong_AsLongLong(value_arg);
1779+
// currently no fields
1780+
// fd.value.i64 = PyLong_AsLongLong(value_arg);
17611781
break;
17621782
case SEGY_SIGNED_INTEGER_4_BYTE:
1763-
fd.value.i32 = PyLong_AsLong(value_arg);
1783+
{
1784+
long val = PyLong_AsLong( value_arg );
1785+
if( PyErr_Occurred() or val > INT32_MAX or val < INT32_MIN ) {
1786+
return ValueError( "Value out of range for signed int" );
1787+
}
1788+
fd.value.i32 = val;
1789+
}
17641790
break;
17651791
case SEGY_SIGNED_SHORT_2_BYTE:
1766-
fd.value.i16 = PyLong_AsLong(value_arg);
1767-
break;
1768-
case SEGY_SIGNED_CHAR_1_BYTE:
1769-
fd.value.i8 = PyLong_AsLong(value_arg);
1792+
{
1793+
long val = PyLong_AsLong( value_arg );
1794+
if( PyErr_Occurred() or val > INT16_MAX or val < INT16_MIN ) {
1795+
return ValueError( "Value out of range for signed short" );
1796+
}
1797+
fd.value.i16 = val;
1798+
}
17701799
break;
17711800

17721801
case SEGY_IEEE_FLOAT_8_BYTE:
1773-
fd.value.f64 = PyFloat_AsDouble(value_arg);
1774-
break;
1775-
case SEGY_IEEE_FLOAT_4_BYTE:
1776-
fd.value.f32 = PyFloat_AsDouble(value_arg);
1777-
break;
1778-
1802+
{
1803+
double val = PyFloat_AsDouble( value_arg );
1804+
if( PyErr_Occurred() ) {
1805+
return ValueError( "Value out of range for double" );
1806+
}
1807+
fd.value.f64 = val;
1808+
break;
1809+
}
17791810
default:
17801811
return KeyError( "Field %d has unknown datatype %d", field, fd.datatype );
17811812
}

0 commit comments

Comments
 (0)