[Rcpp-devel] ColDatum constructors memory safety
Dirk Eddelbuettel
edd at debian.org
Wed Mar 17 01:49:02 CET 2010
On 16 March 2010 at 16:59, Alistair Gee wrote:
| Here are patches to RcppFrame.h:
Sweet! Thanks a lot!
Now, just to top it off, could provide a unit test that would ideally trigger
the issue (or something related) pre-fix but not post-fix?
Dirk
| --- RcppFrame.h~ 2010-02-16 10:54:01.000000000 -0500
| +++ RcppFrame.h 2010-03-16 19:48:29.847994574 -0400
| @@ -30,7 +30,8 @@
| enum ColType { // Supported data frame column types.
| COLTYPE_DOUBLE, COLTYPE_INT, COLTYPE_STRING,
| COLTYPE_FACTOR, COLTYPE_LOGICAL,
| - COLTYPE_DATE, COLTYPE_DATETIME
| + COLTYPE_DATE, COLTYPE_DATETIME,
| + COLTYPE_UNKNOWN = -1
| };
| class ColDatum; // forward declaration, see below
|
|
| and RcppFrame.cpp:
|
|
| --- RcppFrame.cpp~ 2010-03-12 15:11:45.000000000 -0500
| +++ RcppFrame.cpp 2010-03-16 19:48:30.517076368 -0400
| @@ -22,7 +22,7 @@
|
| #include <RcppFrame.h>
|
| -ColDatum::ColDatum() : level(0) { }
| +ColDatum::ColDatum() : type(COLTYPE_UNKNOWN), level(0) { }
|
| ColDatum::ColDatum(const ColDatum& datum) {
| // Need deep copy so contruction/destruction is synchronized.
|
|
|
|
| On Sat, Mar 13, 2010 at 12:03 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
| >
| > Hi Alistair,
| >
| > Thanks for sharing the analysis.
| >
| > On 12 March 2010 at 15:15, Alistair Gee wrote:
| > | The ColDatum default constructor does not initialize any fields except
| > | for "level". But the ColDatum *copy* constructor expects the "type"
| > | field to be properly initialized, b/c if type is COLTYPE_FACTOR, the
| > | copy constructor proceeds to allocate memory using the numLevels field
| > | (which is unreliable b/c numLevels was never initialized). See
| > | comments in source below:
| > |
| > | ColDatum::ColDatum() : level(0) { };
| > |
| > | ColDatum::ColDatum(const ColDatum& datum) {
| > | // Need deep copy so contruction/destruction is synchronized.
| > | s = datum.s;
| > | x = datum.x;
| > | i = datum.i;
| > | type = datum.type; // XXX datum.type was never initialized.
| > | level = datum.level;
| > | numLevels = datum.numLevels; // XXX datum.numLevels was never initialzed.
| > | d = datum.d;
| > | if (type == COLTYPE_FACTOR) {
| > | levelNames = new std::string[numLevels]; // XXX numLevels was copied
| > |
| > | // from datum.numLevels which
| > |
| > | // was never initialized
| > | for (int j = 0; j < numLevels; j++)
| > | levelNames[j] = datum.levelNames[j]; // XXX datum.levelNames is
| > |
| > | // an uninitialized pointer.
| > | }
| > | }
| > |
| > | This is a problem if one tries to create a vector of ColDatum, e.g.
| > |
| > | vector<ColDatum> colDatumVector(10);
| > |
| > | Here, the default constructor is used to first construct a ColDatum
| > | object (which will not have "type" and "levelNames" properly
| > | initialized). Then the copy constructor called by the vector
| > | constructor to create 10 copies.
| >
| > ColDatum is part of what we now call the 'classic' API. It is not getting
| > much attention or love as we focus on the 'new' API. That said, the new API
| > still lacks coverage for data.frame (and Date or Datetime classes).
| >
| > If you can think of a fix, we'd give it a good luck.
| >
| > Else, if you had a patch to clarify the header or code file and maybe just
| > warn of the issue, that would help too.
| >
| > Cheers, Dirk
| >
| > --
| > Registration is open for the 2nd International conference R / Finance 2010
| > See http://www.RinFinance.com for details, and see you in Chicago in April!
| >
--
Registration is open for the 2nd International conference R / Finance 2010
See http://www.RinFinance.com for details, and see you in Chicago in April!
More information about the Rcpp-devel
mailing list