Skip to content

Commit cdaf877

Browse files
committed
safer memory protection
1 parent f65e1a0 commit cdaf877

File tree

1 file changed

+22
-33
lines changed

1 file changed

+22
-33
lines changed

src/core.c

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,19 @@ SEXP rawOneString(unsigned char *bytes, R_xlen_t nbytes, R_xlen_t *np) {
9999

100100
SEXP nano_decode(unsigned char *buf, const size_t sz, const int mod, const int kpr) {
101101

102-
int tryErr = 0;
102+
int p = 0, tryErr = 0;
103103
SEXP raw, data;
104104

105105
switch (mod) {
106106
case 1:
107-
PROTECT(raw = Rf_allocVector(RAWSXP, sz));
107+
PROTECT(raw = Rf_allocVector(RAWSXP, sz)); p++;
108108
memcpy(RAW(raw), buf, sz);
109109
SEXP expr;
110-
PROTECT(expr = Rf_lang2(nano_UnserSymbol, raw));
111-
data = R_tryEval(expr, R_BaseEnv, &tryErr);
112-
UNPROTECT(1);
110+
PROTECT(expr = Rf_lang2(nano_UnserSymbol, raw)); p++;
111+
PROTECT(data = R_tryEval(expr, R_BaseEnv, &tryErr)); p++;
113112
break;
114113
case 2:
115-
PROTECT(data = Rf_allocVector(STRSXP, sz));
114+
PROTECT(data = Rf_allocVector(STRSXP, sz)); p++;
116115
R_xlen_t i, m, nbytes = sz, np = 0;
117116
for (i = 0, m = 0; i < sz; i++) {
118117
SEXP onechar = rawOneString(buf, nbytes, &np);
@@ -123,31 +122,31 @@ SEXP nano_decode(unsigned char *buf, const size_t sz, const int mod, const int k
123122
SETLENGTH(data, m);
124123
break;
125124
case 3:
126-
PROTECT(data = Rf_allocVector(CPLXSXP, sz / (sizeof(double) * 2)));
125+
PROTECT(data = Rf_allocVector(CPLXSXP, sz / (sizeof(double) * 2))); p++;
127126
memcpy(COMPLEX(data), buf, sz);
128127
break;
129128
case 4:
130-
PROTECT(data = Rf_allocVector(REALSXP, sz / sizeof(double)));
129+
PROTECT(data = Rf_allocVector(REALSXP, sz / sizeof(double))); p++;
131130
memcpy(REAL(data), buf, sz);
132131
break;
133132
case 5:
134-
PROTECT(data = Rf_allocVector(INTSXP, sz / sizeof(int)));
133+
PROTECT(data = Rf_allocVector(INTSXP, sz / sizeof(int))); p++;
135134
memcpy(INTEGER(data), buf, sz);
136135
break;
137136
case 6:
138-
PROTECT(data = Rf_allocVector(LGLSXP, sz / sizeof(int)));
137+
PROTECT(data = Rf_allocVector(LGLSXP, sz / sizeof(int))); p++;
139138
memcpy(LOGICAL(data), buf, sz);
140139
break;
141140
case 7:
142-
PROTECT(data = Rf_allocVector(REALSXP, sz / sizeof(double)));
141+
PROTECT(data = Rf_allocVector(REALSXP, sz / sizeof(double))); p++;
143142
memcpy(REAL(data), buf, sz);
144143
break;
145144
case 8:
146-
PROTECT(data = Rf_allocVector(RAWSXP, sz));
145+
PROTECT(data = Rf_allocVector(RAWSXP, sz)); p++;
147146
memcpy(RAW(data), buf, sz);
148147
break;
149148
default:
150-
PROTECT(data = R_NilValue);
149+
PROTECT(data = R_NilValue); p++;
151150
break;
152151
}
153152

@@ -159,29 +158,27 @@ SEXP nano_decode(unsigned char *buf, const size_t sz, const int mod, const int k
159158
switch (mod) {
160159
case 1:
161160
if (tryErr) {
162-
PROTECT(data = raw);
163-
raw = R_NilValue;
164-
} else {
165-
PROTECT(data);
161+
PROTECT(data = raw); p++;
162+
PROTECT(raw = R_NilValue); p++;
166163
}
167164
break;
168165
case 8:
169-
PROTECT(raw = data);
166+
PROTECT(raw = data); p++;
170167
break;
171168
default:
172-
PROTECT(raw = Rf_allocVector(RAWSXP, sz));
169+
PROTECT(raw = Rf_allocVector(RAWSXP, sz)); p++;
173170
memcpy(RAW(raw), buf, sz);
174171
}
175172

176-
PROTECT(out = Rf_mkNamed(VECSXP, names));
173+
PROTECT(out = Rf_mkNamed(VECSXP, names)); p++;
177174
SET_VECTOR_ELT(out, 0, raw);
178175
SET_VECTOR_ELT(out, 1, data);
179176

180-
UNPROTECT(3);
177+
UNPROTECT(p);
181178
return out;
182179
}
183180

184-
UNPROTECT(1);
181+
UNPROTECT(p);
185182
return data;
186183

187184
}
@@ -650,9 +647,7 @@ SEXP rnng_recv(SEXP socket, SEXP mode, SEXP block, SEXP keep) {
650647
return mk_error(xc);
651648
}
652649
nng_msg *msgp = nng_aio_get_msg(aiop);
653-
buf = nng_msg_body(msgp);
654-
sz = nng_msg_len(msgp);
655-
res = nano_decode(buf, sz, mod, kpr);
650+
res = nano_decode(nng_msg_body(msgp), nng_msg_len(msgp), mod, kpr);
656651
nng_msg_free(msgp);
657652
nng_aio_free(aiop);
658653
}
@@ -707,8 +702,6 @@ SEXP rnng_ctx_recv(SEXP context, SEXP mode, SEXP timeout, SEXP keep) {
707702
const nng_duration dur = (nng_duration) Rf_asInteger(timeout);
708703
const int mod = *INTEGER(mode), kpr = *LOGICAL(keep);
709704
int xc;
710-
unsigned char *buf;
711-
size_t sz;
712705
SEXP res;
713706

714707
xc = nng_aio_alloc(&aiop, NULL, NULL);
@@ -725,9 +718,7 @@ SEXP rnng_ctx_recv(SEXP context, SEXP mode, SEXP timeout, SEXP keep) {
725718
}
726719

727720
nng_msg *msgp = nng_aio_get_msg(aiop);
728-
buf = nng_msg_body(msgp);
729-
sz = nng_msg_len(msgp);
730-
res = nano_decode(buf, sz, mod, kpr);
721+
res = nano_decode(nng_msg_body(msgp), nng_msg_len(msgp), mod, kpr);
731722
nng_msg_free(msgp);
732723
nng_aio_free(aiop);
733724

@@ -790,7 +781,6 @@ SEXP rnng_stream_recv(SEXP stream, SEXP mode, SEXP timeout, SEXP keep, SEXP byte
790781
int xc;
791782
nng_iov iov;
792783
nng_aio *aiop;
793-
unsigned char *buf;
794784
size_t sz;
795785
SEXP res;
796786

@@ -821,9 +811,8 @@ SEXP rnng_stream_recv(SEXP stream, SEXP mode, SEXP timeout, SEXP keep, SEXP byte
821811
return mk_error(xc);
822812
}
823813

824-
buf = iov.iov_buf;
825814
sz = nng_aio_count(aiop);
826-
res = nano_decode(buf, sz, mod, kpr);
815+
res = nano_decode(iov.iov_buf, sz, mod, kpr);
827816
nng_aio_free(aiop);
828817
R_Free(iov.iov_buf);
829818

0 commit comments

Comments
 (0)