Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeale Ferguson <neale@sinenomine.net>2014-09-12 19:19:05 +0400
committerNeale Ferguson <neale@sinenomine.net>2014-09-12 19:25:57 +0400
commit3f740f3d94c00f0edd4f0bb317bd3133ac279da0 (patch)
treec541ee5b396f68426ab2169156348b5128d83c43 /mcs/class/System.Data.OracleClient
parent300876b229fb73f6b6e13bda3081318b43c72971 (diff)
Fixes 19752 -
Users have been complaining about strange errors arising when using the OracleClient classes. I have tracked it down to the OciDefineHandle and OciDefineByPos calls, and OracleParameter handling of amanged objects by unmanaged code. Currently two of the parameters passed to the above OCI call are short variables. They are passed as "ref" fields as Oracle uses their address to put size and indicator data once the data is fetched. However, being defined as short means that they are eligible for being moved during garbage collection. Thus if that field is moved between the OciDefineByPos call and the fetch of the data then what Oracle is pointing to may no longer be variable. I'm thinking it may be better to define these fields as IntPtr and allocate them and retrieve their values via Marshal.ReadInt16. As for OracleParameter, it uses a managed object "indicator" that is also used in a similar way. This reference is replaced by a IntPtr and a get/set method to access the contents.
Diffstat (limited to 'mcs/class/System.Data.OracleClient')
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs56
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs62
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs64
3 files changed, 111 insertions, 71 deletions
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
index 3e1ce930785..e6125bf5c91 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
@@ -95,7 +95,7 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -111,7 +111,7 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -127,7 +127,7 @@ namespace System.Data.OracleClient.Oci
byte[] valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -142,7 +142,7 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -157,7 +157,7 @@ namespace System.Data.OracleClient.Oci
byte[] valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -172,7 +172,7 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -193,8 +193,8 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U4)] OciDataType dty,
- ref short indp,
- ref short rlenp,
+ IntPtr indp,
+ IntPtr rlenp,
IntPtr rcodep,
uint mode);
@@ -206,8 +206,8 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U4)] OciDataType dty,
- ref short indp,
- ref short rlenp,
+ IntPtr indp,
+ IntPtr rlenp,
IntPtr rcodep,
uint mode);
@@ -547,7 +547,7 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -558,7 +558,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI");
#endif
return OciNativeCalls.OCIBindByName (stmtp, out bindpp, errhp, placeholder, placeh_len, valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
internal static int OCIBindByNameRef (IntPtr stmtp,
@@ -569,7 +569,7 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -580,7 +580,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI");
#endif
return OciNativeCalls.OCIBindByNameRef (stmtp, out bindpp, errhp, placeholder, placeh_len, ref valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
internal static int OCIBindByNameBytes (IntPtr stmtp,
@@ -591,7 +591,7 @@ namespace System.Data.OracleClient.Oci
byte[] valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -602,7 +602,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI");
#endif
return OciNativeCalls.OCIBindByNameBytes (stmtp, out bindpp, errhp, placeholder, placeh_len, valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
internal static int OCIBindByPos (IntPtr stmtp,
@@ -612,7 +612,7 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -623,7 +623,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI");
#endif
return OciNativeCalls.OCIBindByPos (stmtp, out bindpp, errhp, position, valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
internal static int OCIBindByPosRef (IntPtr stmtp,
@@ -633,7 +633,7 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -644,7 +644,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI");
#endif
return OciNativeCalls.OCIBindByPosRef (stmtp, out bindpp, errhp, position, ref valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
internal static int OCIBindByPosBytes (IntPtr stmtp,
@@ -654,7 +654,7 @@ namespace System.Data.OracleClient.Oci
byte[] valuep,
int value_sz,
[MarshalAs (UnmanagedType.U2)] OciDataType dty,
- ref short indp,
+ IntPtr indp,
IntPtr alenp,
IntPtr rcodep,
uint maxarr_len,
@@ -665,7 +665,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI");
#endif
return OciNativeCalls.OCIBindByPosBytes (stmtp, out bindpp, errhp, position, valuep,
- value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode);
+ value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode);
}
[DllImport ("oci")]
@@ -723,8 +723,8 @@ namespace System.Data.OracleClient.Oci
IntPtr valuep,
int value_sz,
OciDataType dty,
- ref short indp,
- ref short rlenp,
+ IntPtr indp,
+ IntPtr rlenp,
IntPtr rcodep,
uint mode)
{
@@ -732,7 +732,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIDefineByPos", "OCI");
#endif
return OciNativeCalls.OCIDefineByPos (stmtp, out defnpp, errhp, position, valuep,
- value_sz, dty, ref indp, ref rlenp, rcodep, mode);
+ value_sz, dty, indp, rlenp, rcodep, mode);
}
internal static int OCIDefineByPosPtr (IntPtr stmtp,
@@ -742,8 +742,8 @@ namespace System.Data.OracleClient.Oci
ref IntPtr valuep,
int value_sz,
OciDataType dty,
- ref short indp,
- ref short rlenp,
+ IntPtr indp,
+ IntPtr rlenp,
IntPtr rcodep,
uint mode)
{
@@ -751,7 +751,7 @@ namespace System.Data.OracleClient.Oci
Trace.WriteLineIf(traceOci, "OCIDefineByPosPtr", "OCI");
#endif
return OciNativeCalls.OCIDefineByPosPtr (stmtp, out defnpp, errhp, position, ref valuep,
- value_sz, dty, ref indp, ref rlenp, rcodep, mode);
+ value_sz, dty, indp, rlenp, rcodep, mode);
}
internal static int OCIDescriptorFree (IntPtr hndlp,
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs
index baf90c1865f..9f46f98509b 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs
@@ -32,16 +32,16 @@ namespace System.Data.OracleClient.Oci
//IntPtr handle;
IntPtr value;
- short indicator;
+ IntPtr indicator;
//OracleType type;
OciDataType ociType;
OciDataType definedType;
int definedSize;
- short rlenp = 0;
+ IntPtr rlenp;
//short precision;
short scale;
Type fieldType;
- //string name;
+ string name;
// Oracle defines the LONG VARCHAR and LONG VARRAW to have a size of 2 to the 31 power - 5
// see DefineLongVarChar and DefineLongVarRaw
@@ -70,11 +70,13 @@ namespace System.Data.OracleClient.Oci
{
OciParameterDescriptor parameter = ((OciStatementHandle) Parent).GetParameter (position);
- //name = parameter.GetName ();
+ name = parameter.GetName ();
definedType = parameter.GetDataType ();
definedSize = parameter.GetDataSize ();
//precision = parameter.GetPrecision ();
scale = parameter.GetScale ();
+ rlenp = OciCalls.AllocateClear (sizeof(short));
+ indicator = OciCalls.AllocateClear (sizeof(short));
Define (position, connection);
@@ -103,7 +105,7 @@ namespace System.Data.OracleClient.Oci
}
internal bool IsNull {
- get { return (indicator == -1); }
+ get { return (Indicator == -1); }
}
internal short Scale {
@@ -111,7 +113,13 @@ namespace System.Data.OracleClient.Oci
}
internal short Size {
- get { return rlenp; }
+ get { return(Marshal.ReadInt16(rlenp)); }
+ set { Marshal.WriteInt16(rlenp, value); }
+ }
+
+ internal short Indicator {
+ get { return(Marshal.ReadInt16(indicator)); }
+ set { Marshal.WriteInt16(indicator, value); }
}
internal IntPtr Value {
@@ -192,8 +200,8 @@ namespace System.Data.OracleClient.Oci
ref value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
@@ -222,8 +230,8 @@ namespace System.Data.OracleClient.Oci
value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
@@ -261,11 +269,11 @@ namespace System.Data.OracleClient.Oci
value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero, 0);
- rlenp = (short) definedSize;
+ Size = (short) definedSize;
if (status != 0) {
OciErrorInfo info = ErrorHandle.HandleError ();
@@ -291,8 +299,8 @@ namespace System.Data.OracleClient.Oci
value,
maxByteCount,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
OciErrorHandle.ThrowExceptionIfError (ErrorHandle, status);
@@ -312,10 +320,10 @@ namespace System.Data.OracleClient.Oci
ErrorHandle,
position + 1,
value,
- definedSize * 2,
+ definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
@@ -357,8 +365,8 @@ namespace System.Data.OracleClient.Oci
ref value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
@@ -386,8 +394,8 @@ namespace System.Data.OracleClient.Oci
value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero, 0);
if (status != 0) {
@@ -415,8 +423,8 @@ namespace System.Data.OracleClient.Oci
value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero, 0);
if (status != 0) {
@@ -459,8 +467,8 @@ namespace System.Data.OracleClient.Oci
ref value,
definedSize,
ociType,
- ref indicator,
- ref rlenp,
+ indicator,
+ rlenp,
IntPtr.Zero,
0);
@@ -487,6 +495,8 @@ namespace System.Data.OracleClient.Oci
}
disposed = true;
} finally {
+ Marshal.FreeHGlobal (indicator);
+ Marshal.FreeHGlobal (rlenp);
base.Dispose (disposing);
value = IntPtr.Zero;
}
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
index 6f11d970f0d..ef5eb270207 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
@@ -37,12 +37,13 @@ using System.Text;
namespace System.Data.OracleClient
{
[TypeConverter (typeof(OracleParameter.OracleParameterConverter))]
- public sealed class OracleParameter :
+ public sealed class OracleParameter :
#if NET_2_0
- DbParameter, IDbDataParameter, ICloneable
+ DbParameter, IDbDataParameter, ICloneable,
#else
- MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
+ MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable,
#endif
+ IDisposable
{
#region Fields
@@ -66,6 +67,7 @@ namespace System.Data.OracleClient
object value = DBNull.Value;
OciLobLocator lobLocator; // only if Blob or Clob
IntPtr bindOutValue = IntPtr.Zero;
+ IntPtr indicator = IntPtr.Zero;
OciDateTimeDescriptor dateTimeDesc;
IntPtr cursor = IntPtr.Zero;
@@ -77,7 +79,6 @@ namespace System.Data.OracleClient
bool useRef;
OciDataType bindType;
- short indicator;
int bindSize;
bool sizeManuallySet;
@@ -104,6 +105,7 @@ namespace System.Data.OracleClient
this.value = value.value;
this.lobLocator = value.lobLocator;
this.oracleTypeSet = value.oracleTypeSet;
+ this.indicator = OciCalls.AllocateClear (sizeof(short));
}
public OracleParameter ()
@@ -119,6 +121,7 @@ namespace System.Data.OracleClient
this.srcVersion = DataRowVersion.Current;
this.value = null;
this.oracleTypeSet = false;
+ this.indicator = OciCalls.AllocateClear (sizeof(short));
}
public OracleParameter (string name, object value)
@@ -129,6 +132,7 @@ namespace System.Data.OracleClient
srcColumn = string.Empty;
SourceVersion = DataRowVersion.Current;
InferOracleType (value);
+ this.indicator = OciCalls.AllocateClear (sizeof(short));
#if NET_2_0
// Find the OciType before inferring for the size
if (value != null && value != DBNull.Value) {
@@ -173,6 +177,7 @@ namespace System.Data.OracleClient
OracleType = oracleType;
SourceColumn = sourceColumn;
SourceVersion = sourceVersion;
+ this.indicator = OciCalls.AllocateClear (sizeof(short));
}
#endif
@@ -199,6 +204,12 @@ namespace System.Data.OracleClient
OracleType = oracleType;
SourceColumn = srcColumn;
SourceVersion = srcVersion;
+ this.indicator = OciCalls.AllocateClear (sizeof(short));
+ }
+
+ ~OracleParameter ()
+ {
+ Dispose(false);
}
#endregion // Constructors
@@ -210,6 +221,11 @@ namespace System.Data.OracleClient
set { container = value; }
}
+ internal short Indicator {
+ get { return (Marshal.ReadInt16(indicator)); }
+ set { Marshal.WriteInt16(indicator, value); }
+ }
+
#if !NET_2_0
[Browsable (false)]
[RefreshProperties (RefreshProperties.All)]
@@ -453,7 +469,6 @@ namespace System.Data.OracleClient
}
if (isnull == true && direction == ParameterDirection.Input) {
- indicator = 0;
bindType = OciDataType.VarChar2;
bindSize = 0;
} else {
@@ -465,7 +480,6 @@ namespace System.Data.OracleClient
case OciDataType.CharZ:
case OciDataType.OciString:
bindType = OciDataType.String;
- indicator = 0;
svalue = "\0";
// convert value from managed type to type to marshal
if (direction == ParameterDirection.Input ||
@@ -558,7 +572,7 @@ namespace System.Data.OracleClient
dt = DateTime.MinValue;
sDate = "";
if (isnull)
- indicator = -1;
+ Indicator = -1;
else if (v is String) {
sDate = (string) v;
dt = DateTime.Parse (sDate);
@@ -594,7 +608,7 @@ namespace System.Data.OracleClient
case OciDataType.Float:
case OciDataType.Number:
bindType = OciDataType.String;
- indicator = 0;
+ Indicator = 0;
svalue = "\0";
// convert value from managed type to type to marshal
if (direction == ParameterDirection.Input ||
@@ -638,7 +652,7 @@ namespace System.Data.OracleClient
bindSize = Size + 5; // 4 bytes prepended for length, bytes, 1 byte NUL character
- indicator = 0;
+ Indicator = 0;
svalue = "\0";
// convert value from managed type to type to marshal
if (direction == ParameterDirection.Input ||
@@ -758,7 +772,7 @@ namespace System.Data.OracleClient
case OciDataType.VarRaw:
bindType = OciDataType.VarRaw;
bindSize = Size + 2; // include 2 bytes prepended to hold the length
- indicator = 0;
+ Indicator = 0;
bytes = new byte [bindSize];
if (direction == ParameterDirection.Input ||
direction == ParameterDirection.InputOutput) {
@@ -784,7 +798,7 @@ namespace System.Data.OracleClient
case OciDataType.LongVarRaw:
bindType = OciDataType.LongVarRaw;
bindSize = Size + 4; // include 4 bytes prepended to hold the length
- indicator = 0;
+ Indicator = 0;
bytes = new byte [bindSize];
if (direction == ParameterDirection.Input ||
direction == ParameterDirection.InputOutput) {
@@ -854,7 +868,7 @@ namespace System.Data.OracleClient
ref bindValue,
bindSize,
bindType,
- ref indicator,
+ indicator,
IntPtr.Zero,
IntPtr.Zero,
0,
@@ -870,7 +884,7 @@ namespace System.Data.OracleClient
ref bindValue,
bindSize,
bindType,
- ref indicator,
+ indicator,
IntPtr.Zero,
IntPtr.Zero,
0,
@@ -887,7 +901,7 @@ namespace System.Data.OracleClient
ref cursor,
bindSize,
bindType,
- ref indicator,
+ indicator,
IntPtr.Zero,
IntPtr.Zero,
0,
@@ -903,7 +917,7 @@ namespace System.Data.OracleClient
bytes,
bindSize,
bindType,
- ref indicator,
+ indicator,
IntPtr.Zero,
IntPtr.Zero,
0,
@@ -919,7 +933,7 @@ namespace System.Data.OracleClient
bindValue,
bindSize,
bindType,
- ref indicator,
+ indicator,
IntPtr.Zero,
IntPtr.Zero,
0,
@@ -1251,7 +1265,7 @@ namespace System.Data.OracleClient
// used to update the parameter value
// for Output, the output of InputOutput, and Return parameters
value = DBNull.Value;
- if (indicator == -1)
+ if (Indicator == -1)
return;
int rsize = 0;
@@ -1453,6 +1467,22 @@ namespace System.Data.OracleClient
return buffer;
}
+ public void Dispose ()
+ {
+ Dispose (true);
+ }
+
+ void Dispose (bool disposing)
+ {
+ if (disposing) {
+ GC.SuppressFinalize(this);
+ }
+ if (indicator != IntPtr.Zero) {
+ Marshal.FreeHGlobal (indicator);
+ indicator = IntPtr.Zero;
+ }
+ }
+
#endregion // Methods
internal sealed class OracleParameterConverter : ExpandableObjectConverter