[ruby-oci8-commit] [377] trunk/ruby-oci8: * ext/oci8/ocinumber.c, ext/oci8/oranumber_util.c,
nobody at rubyforge.org
nobody at rubyforge.org
Sun Feb 7 07:52:15 EST 2010
Revision: 377
Author: kubo
Date: 2010-02-07 07:52:15 -0500 (Sun, 07 Feb 2010)
Log Message:
-----------
* ext/oci8/ocinumber.c, ext/oci8/oranumber_util.c,
ext/oci8/oranumber_util.h: change the declaration of
oranumber_to_str() to prevent buffer overflow by
unexpected invalid Oracle number internal data.
Modified Paths:
--------------
trunk/ruby-oci8/ChangeLog
trunk/ruby-oci8/ext/oci8/ocinumber.c
trunk/ruby-oci8/ext/oci8/oranumber_util.c
trunk/ruby-oci8/ext/oci8/oranumber_util.h
Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog 2010-02-07 10:02:22 UTC (rev 376)
+++ trunk/ruby-oci8/ChangeLog 2010-02-07 12:52:15 UTC (rev 377)
@@ -1,4 +1,10 @@
2010-02-07 KUBO Takehiro <kubo at jiubao.org>
+ * ext/oci8/ocinumber.c, ext/oci8/oranumber_util.c,
+ ext/oci8/oranumber_util.h: change the declaration of
+ oranumber_to_str() to prevent buffer overflow by
+ unexpected invalid Oracle number internal data.
+
+2010-02-07 KUBO Takehiro <kubo at jiubao.org>
* ext/oci8/error.c, ext/oci8/oci8.h: add oci8_raise_by_msgno()
to retrieve a Oracle error message which depends on NLS_LANGUAGE.
* ext/oci8/oranumber_util.c, ext/oci8/oranumber_util.h,
Modified: trunk/ruby-oci8/ext/oci8/ocinumber.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/ocinumber.c 2010-02-07 10:02:22 UTC (rev 376)
+++ trunk/ruby-oci8/ext/oci8/ocinumber.c 2010-02-07 12:52:15 UTC (rev 377)
@@ -123,12 +123,12 @@
return LONG2NUM(sl);
}
/* convert to Integer via String */
- rv = oranumber_to_str(s, buf);
+ rv = oranumber_to_str(s, buf, sizeof(buf));
if (rv > 0) {
return rb_cstr2inum(buf, 10);
}
oranumber_dump(s, buf);
- rb_raise(eOCIException, "Could not convert OraNumber(%s) to string", buf);
+ rb_raise(eOCIException, "Invalid internal number format: %s", buf);
}
VALUE oci8_make_float(OCINumber *s, OCIError *errhp)
@@ -1026,10 +1026,12 @@
rb_scan_args(argc, argv, "02", &fmt /* nil */, &nls_params /* nil */);
if (NIL_P(fmt)) {
- rv = oranumber_to_str(_NUMBER(self), buf);
+ rv = oranumber_to_str(_NUMBER(self), buf, sizeof(buf));
if (rv > 0) {
return rb_usascii_str_new(buf, rv);
}
+ oranumber_dump(_NUMBER(self), buf);
+ rb_raise(eOCIException, "Invalid internal number format: %s", buf);
}
StringValue(fmt);
fmt_ptr = RSTRING_ORATEXT(fmt);
Modified: trunk/ruby-oci8/ext/oci8/oranumber_util.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oranumber_util.c 2010-02-07 10:02:22 UTC (rev 376)
+++ trunk/ruby-oci8/ext/oci8/oranumber_util.c 2010-02-07 12:52:15 UTC (rev 377)
@@ -3,7 +3,7 @@
#include <string.h>
#include "oranumber_util.h"
-int oranumber_to_str(const OCINumber *on, char *buf)
+int oranumber_to_str(const OCINumber *on, char *buf, int buflen)
{
signed char exponent;
signed char mantissa[21]; /* terminated by a negative number */
@@ -11,6 +11,20 @@
int len = 0;
int idx;
int n;
+#define PUTC(chr) do { \
+ if (len < buflen) { \
+ buf[len++] = (chr); \
+ } else { \
+ return ORANUMBER_TOO_SHORT_BUFFER; \
+ } \
+} while(0)
+#define PUTEND() do { \
+ if (len < buflen) { \
+ buf[len] = '\0'; \
+ } else { \
+ return ORANUMBER_TOO_SHORT_BUFFER; \
+ } \
+} while(0)
if (datalen == 0) {
/* too short */
@@ -19,8 +33,8 @@
if (datalen == 1) {
if (on->OCINumberPart[1] == 0x80) {
/* zero */
- buf[0] = '0';
- buf[1] = '\0';
+ PUTC('0');
+ PUTEND();
return 1;
}
/* unexpected format */
@@ -45,7 +59,7 @@
mantissa[idx] = 101 - on->OCINumberPart[idx + 2];
}
mantissa[idx] = -1;
- buf[len++] = '-';
+ PUTC('-');
}
/* convert exponent and mantissa to human readable number */
idx = 0;
@@ -53,43 +67,43 @@
/* integer part */
n = mantissa[idx++];
if (n / 10 != 0) {
- buf[len++] = n / 10 + '0';
+ PUTC(n / 10 + '0');
}
- buf[len++] = n % 10 + '0';
+ PUTC(n % 10 + '0');
while (exponent-- >= 0) {
n = mantissa[idx++];
if (n < 0) {
do {
- buf[len++] = '0';
- buf[len++] = '0';
+ PUTC('0');
+ PUTC('0');
} while (exponent-- >= 0);
- buf[len] = '\0';
+ PUTEND();
return len;
}
- buf[len++] = n / 10 + '0';
- buf[len++] = n % 10 + '0';
+ PUTC(n / 10 + '0');
+ PUTC(n % 10 + '0');
}
if (mantissa[idx] < 0) {
- buf[len] = '\0';
+ PUTEND();
return len;
}
} else {
- buf[len++] = '0';
+ PUTC('0');
}
- buf[len++] = '.';
+ PUTC('.');
/* fractional number part */
while (++exponent < -1) {
- buf[len++] = '0';
- buf[len++] = '0';
+ PUTC('0');
+ PUTC('0');
}
while ((n = mantissa[idx++]) >= 0) {
- buf[len++] = n / 10 + '0';
- buf[len++] = n % 10 + '0';
+ PUTC(n / 10 + '0');
+ PUTC(n % 10 + '0');
}
if (buf[len - 1] == '0') {
len--;
}
- buf[len] = '\0';
+ PUTEND();
return len;
}
Modified: trunk/ruby-oci8/ext/oci8/oranumber_util.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oranumber_util.h 2010-02-07 10:02:22 UTC (rev 376)
+++ trunk/ruby-oci8/ext/oci8/oranumber_util.h 2010-02-07 12:52:15 UTC (rev 377)
@@ -8,11 +8,14 @@
#define ORANUMBER_UTIL_H 1
#include <orl.h>
+#define ORANUMBER_INVALID_INTERNAL_FORMAT -1
+#define ORANUMBER_TOO_SHORT_BUFFER -2
+
#define ORANUMBER_SUCCESS 0
#define ORANUMBER_INVALID_NUMBER 1722
#define ORANUMBER_NUMERIC_OVERFLOW 1426
-int oranumber_to_str(const OCINumber *on, char *buf);
+int oranumber_to_str(const OCINumber *on, char *buf, int buflen);
int oranumber_from_str(OCINumber *on, const char *buf, int buflen);
#define ORANUMBER_DUMP_BUF_SIZ 99
More information about the ruby-oci8-commit
mailing list