[Dplr-commits] r855 - in pkg/dplR: . src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Mon May 5 22:39:51 CEST 2014
Author: mvkorpel
Date: 2014-05-05 22:39:50 +0200 (Mon, 05 May 2014)
New Revision: 855
Modified:
pkg/dplR/ChangeLog
pkg/dplR/DESCRIPTION
pkg/dplR/src/dplR.h
pkg/dplR/src/rcompact.c
Log:
C code of read.compact() is now more robust in case of unusual (unlikely) input
Modified: pkg/dplR/ChangeLog
===================================================================
--- pkg/dplR/ChangeLog 2014-05-03 17:06:59 UTC (rev 854)
+++ pkg/dplR/ChangeLog 2014-05-05 20:39:50 UTC (rev 855)
@@ -6,6 +6,11 @@
- Bug fix: make.plot=TRUE threw an error when input data.frame had leading
or trailing all-NA rows
+File: rcompact.c
+----------------
+
+- Made the C code of read.compact() more resilient to unusual inputs
+
File: redfit.c
--------------
Modified: pkg/dplR/DESCRIPTION
===================================================================
--- pkg/dplR/DESCRIPTION 2014-05-03 17:06:59 UTC (rev 854)
+++ pkg/dplR/DESCRIPTION 2014-05-05 20:39:50 UTC (rev 855)
@@ -3,7 +3,7 @@
Type: Package
Title: Dendrochronology Program Library in R
Version: 1.6.1
-Date: 2014-05-03
+Date: 2014-05-05
Authors at R: c(person("Andy", "Bunn", role = c("aut", "cph",
"cre", "trl"), email = "andy.bunn at wwu.edu"), person("Mikko",
"Korpela", role = c("aut", "trl")), person("Franco", "Biondi",
Modified: pkg/dplR/src/dplR.h
===================================================================
--- pkg/dplR/src/dplR.h 2014-05-03 17:06:59 UTC (rev 854)
+++ pkg/dplR/src/dplR.h 2014-05-05 20:39:50 UTC (rev 855)
@@ -31,4 +31,7 @@
/* 64 or 80 bits */
#endif
+#define R_INT_MAX 2147483647
+#define R_INT_MIN -R_INT_MAX
+
#endif
Modified: pkg/dplR/src/rcompact.c
===================================================================
--- pkg/dplR/src/rcompact.c 2014-05-03 17:06:59 UTC (rev 854)
+++ pkg/dplR/src/rcompact.c 2014-05-05 20:39:50 UTC (rev 855)
@@ -114,8 +114,10 @@
*id_start, *old_point, *point, *point2, *endp, *tmp_name,
*tmp_comment;
int i, j, n, first_yr, last_yr, id_length, exponent,
- n_repeats, field_width, precision, n_x_w, n_lines, remainder, idx,
+ n_repeats, field_width, n_x_w, n_lines, remainder, idx,
this_last, *i_first, *i_last;
+ long int precision;
+ size_t idx2;
Rboolean n_found, divide;
long long int read_int;
double read_double, mplier, *r_mplier, *r_data;
@@ -138,8 +140,8 @@
this = &first; /* current rwlnode */
comment_this = &comment_first; /* current commentnode */
n = 0; /* number of series */
- first_yr = INT_MAX; /* the first year in all data */
- last_yr = INT_MIN; /* the last year in all data */
+ first_yr = R_INT_MAX; /* the first year in all data */
+ last_yr = R_INT_MIN; /* the last year in all data */
/* Each round of the loop reads a header line,
* then the data lines of the corresponding series
@@ -203,7 +205,7 @@
error(_("Series %d: Only a number must be found right before 1st '='"),
n+1);
}
- if(read_int > INT_MAX){
+ if(read_int > R_INT_MAX || read_int < R_INT_MIN){
fclose(f);
error(_("Series %d: Number %lld exceeds integer range"),
n+1, read_int);
@@ -248,7 +250,7 @@
error(_("Series %d: Only a number must be found after first field, right before 2nd '='"),
n+1);
}
- if(read_int > INT_MAX){
+ if(read_int > R_INT_MAX || read_int < R_INT_MIN){
fclose(f);
error(_("Series %d: Number %lld exceeds integer range"),
n+1, read_int);
@@ -269,10 +271,13 @@
n+1, *(found2+1));
}
+ /* Check for overflow */
+ if(this->first_yr > 1 && this->n - 1 > R_INT_MAX - this->first_yr)
+ error(_("Series %d: Last year exceeds integer range"), n+1);
/* Update global first and last year */
if(this->first_yr < first_yr)
first_yr = this->first_yr;
- this_last = this->first_yr + this->n - 1;
+ this_last = this->first_yr + (this->n - 1);
if(this_last > last_yr)
last_yr = this_last;
@@ -327,7 +332,7 @@
/* Require space */
if(*point != ' '){
fclose(f);
- error(_("Series %d (%s): Space required after alphanumerid ID"),
+ error(_("Series %d (%s): Space required after alphanumeric ID"),
n+1, this->id);
}
@@ -416,7 +421,7 @@
n+1, this->id, field_width);
}
point = found_dot+1;
- precision = (int) strtol(point, &endp, 10);
+ precision = strtol(point, &endp, 10);
if(endp == point){
fclose(f);
error(_("Series %d (%s): Number of decimals not found"),
@@ -427,7 +432,7 @@
error(_("Series %d (%s): Number of decimals and ')' must be adjacent"),
n+1, this->id);
}
- if(precision != 0){
+ if(precision != 0L){
fclose(f);
error(_("Series %d (%s): No (implied) decimal places allowed in format"),
n+1, this->id);
@@ -564,28 +569,28 @@
r_mplier = REAL(series_mplier);
r_data = REAL(series_data);
- /* idx is for indexing r_data.
+ /* idx2 is for indexing r_data.
* The matrix series_data is stored in column-major order: We
- * proceed one series at a time, simply incrementing idx on each
+ * proceed one series at a time, simply incrementing idx2 on each
* (carefully planned) write to the array.
*/
- idx = -1;
+ idx2 = 0;
this = &first;
for(i=0; i<n; i++){
- this_last = this->first_yr + this->n - 1;
+ this_last = this->first_yr + (this->n - 1);
SET_STRING_ELT(series_id, i, mkChar(this->id));
i_first[i] = this->first_yr;
i_last[i] = this_last;
r_mplier[i] = this->mplier;
/* Add NA to beginning */
for(j=0; j < this->first_yr - first_yr; j++)
- r_data[++idx] = NA_REAL;
+ r_data[idx2++] = NA_REAL;
/* Add data to middle */
for(j=0; j < this->n; j++)
- r_data[++idx] = this->data[j];
+ r_data[idx2++] = this->data[j];
/* Add NA to end */
for(j=0; j < last_yr - this_last; j++)
- r_data[++idx] = NA_REAL;
+ r_data[idx2++] = NA_REAL;
this = this->next;
}
More information about the Dplr-commits
mailing list