[svn:dbd-oracle] r15334 - in dbd-oracle/trunk: . lib/DBD

[email protected] Sun, 24 Jun 2012 04:34:06 -0700 (PDT)
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
Author: mjevans
Date: Sun Jun 24 04:34:06 2012
New Revision: 15334

Modified:
   dbd-oracle/trunk/Changes
   dbd-oracle/trunk/Oracle.xs
   dbd-oracle/trunk/lib/DBD/Oracle.pm

Log:
RT55028 - stop seg faulting when reading emtpy lobs


Modified: dbd-oracle/trunk/Changes
==============================================================================
--- dbd-oracle/trunk/Changes	(original)
+++ dbd-oracle/trunk/Changes	Sun Jun 24 04:34:06 2012
@@ -4,7 +4,10 @@
 
   [BUG FIXES]
 
-  - fixed redclaration of $len in 31lob.t - (Martin J, Evans)
+  - fixed redeclaration of $len in 31lob.t - (Martin J, Evans)
+
+  - RT55028 - stop segfaulting when attempting to read empty lobs
+    (Martin J. Evans)
 
   [MISCELLANEOUS]
 

Modified: dbd-oracle/trunk/Oracle.xs
==============================================================================
--- dbd-oracle/trunk/Oracle.xs	(original)
+++ dbd-oracle/trunk/Oracle.xs	Sun Jun 24 04:34:06 2012
@@ -557,54 +557,61 @@
 	sword status;
 	ub1 csform;
 	CODE:
+
 	csform = SQLCS_IMPLICIT;
+    /* NOTE, if length is 0 this will create an empty SV of undef
+       see RT55028 */
 	dest_sv = sv_2mortal(newSV(length*4)); /*LAB: crude hack that works... tim did it else where XXX */
-	SvPOK_on(dest_sv);
-	bufp_len = SvLEN(dest_sv);	/* XXX bytes not chars? (lab: yes) */
-	bufp = SvPVX(dest_sv);
-	amtp = length;	/* if utf8 and clob/nclob: in: chars, out: bytes */
-	/* http://www.lc.leidenuniv.nl/awcourse/oracle/appdev.920/a96584/oci16m40.htm#427818 */
-	/* if locator is CLOB and data is UTF8 and not in bytes pragma */
-	/* if (0 && SvUTF8(dest_sv) && !IN_BYTES) { amtp = sv_len_utf8(dest_sv); }  */
-	/* added by lab: */
-	OCILobCharSetForm_log_stat(imp_dbh,  imp_dbh->envhp, imp_dbh->errhp, locator, &csform, status );
-	if (status != OCI_SUCCESS) {
-		oci_error(dbh, imp_dbh->errhp, status, "OCILobCharSetForm");
-	dest_sv = &PL_sv_undef;
-		return;
-	}
-    {
-        /* see rt 75163 */
-        boolean is_open;
-
-        OCILobFileIsOpen_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator, &is_open, status);
-        if (status == OCI_SUCCESS && !is_open) {
-            OCILobFileOpen_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator,
-                                    (ub1)OCI_FILE_READONLY, status);
-            if (status != OCI_SUCCESS) {
-                oci_error(dbh, imp_dbh->errhp, status, "OCILobFileOpen");
-                dest_sv = &PL_sv_undef;
+
+    if (length > 0) {
+        SvPOK_on(dest_sv);
+        bufp_len = SvLEN(dest_sv);	/* XXX bytes not chars? (lab: yes) */
+        bufp = SvPVX(dest_sv);
+        amtp = length;	/* if utf8 and clob/nclob: in: chars, out: bytes */
+        /* http://www.lc.leidenuniv.nl/awcourse/oracle/appdev.920/a96584/oci16m40.htm#427818 */
+        /* if locator is CLOB and data is UTF8 and not in bytes pragma */
+        /* if (0 && SvUTF8(dest_sv) && !IN_BYTES) { amtp = sv_len_utf8(dest_sv); }  */
+        /* added by lab: */
+        OCILobCharSetForm_log_stat(imp_dbh,  imp_dbh->envhp, imp_dbh->errhp, locator, &csform, status );
+        if (status != OCI_SUCCESS) {
+            oci_error(dbh, imp_dbh->errhp, status, "OCILobCharSetForm");
+            dest_sv = &PL_sv_undef;
+            return;
+        }
+        {
+            /* see rt 75163 */
+            boolean is_open;
+
+            OCILobFileIsOpen_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator, &is_open, status);
+            if (status == OCI_SUCCESS && !is_open) {
+                OCILobFileOpen_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator,
+                                        (ub1)OCI_FILE_READONLY, status);
+                if (status != OCI_SUCCESS) {
+                    oci_error(dbh, imp_dbh->errhp, status, "OCILobFileOpen");
+                    dest_sv = &PL_sv_undef;
+                }
             }
         }
-    }
 
-	OCILobRead_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator,
-		&amtp, (ub4)offset, /* offset starts at 1 */
-		bufp, (ub4)bufp_len,
-		0, 0, (ub2)0, csform, status);
-	if (status != OCI_SUCCESS) {
-		oci_error(dbh, imp_dbh->errhp, status, "OCILobRead");
-		dest_sv = &PL_sv_undef;
-	}
-	else {
-		SvCUR(dest_sv) = amtp; /* always bytes here */
-		*SvEND(dest_sv) = '\0';
-		if (csform){
-			if (CSFORM_IMPLIES_UTF8(csform)){
-				SvUTF8_on(dest_sv);
-			}
-  	  	}
-	}
+        OCILobRead_log_stat(imp_dbh, imp_dbh->svchp, imp_dbh->errhp, locator,
+                            &amtp, (ub4)offset, /* offset starts at 1 */
+                            bufp, (ub4)bufp_len,
+                            0, 0, (ub2)0, csform, status);
+        if (status != OCI_SUCCESS) {
+            oci_error(dbh, imp_dbh->errhp, status, "OCILobRead");
+            dest_sv = &PL_sv_undef;
+        }
+        else {
+            SvCUR(dest_sv) = amtp; /* always bytes here */
+            *SvEND(dest_sv) = '\0';
+            if (csform){
+                if (CSFORM_IMPLIES_UTF8(csform)){
+                    SvUTF8_on(dest_sv);
+                }
+            }
+        }
+    } /* length > 0 */
+
 	ST(0) = dest_sv;
 
 void

Modified: dbd-oracle/trunk/lib/DBD/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/lib/DBD/Oracle.pm	(original)
+++ dbd-oracle/trunk/lib/DBD/Oracle.pm	Sun Jun 24 04:34:06 2012
@@ -4188,6 +4188,12 @@
 Read a portion of the LOB. $offset starts at 1.
 Uses the Oracle OCILobRead function.
 
+NOTE: DBD::Oracle post 1.46 will return undef for any read lob if the
+length specified in the ora_lob_read is 0. See RT 55028. This avoids
+the potential problem with empty lobs (created with empty_clob) which
+return a length of 0 from ora_lob_length and prior to 1.46 a call to
+ora_lob_read with a 0 length would segfault.
+
 =item ora_lob_write
 
   $rc = $dbh->ora_lob_write($lob_locator, $offset, $data);