···707707 (Xavier Clerc, report by Christophe Troestler, review by Nicolás Ojeda Bär
708708 and Gabriel Scherer)
709709710710+- GPR#1835: Fix off-by-one errors in Weak.get_copy and Weak.blit
711711+ (KC Sivaramakrishnan)
712712+710713OCaml 4.06.1 (16 Feb 2018):
711714---------------------------
712715
+23-23
byterun/weak.c
···6868 mlsize_t size, i;
6969 value res;
70707171- size = Long_val (len) + 1 /* weak_list */ + 1 /* the value */;
7272- if (size < 2 || size > Max_wosize) caml_invalid_argument ("Weak.create");
7171+ size = Long_val (len) + CAML_EPHE_FIRST_KEY;
7272+ if (size < CAML_EPHE_FIRST_KEY || size > Max_wosize)
7373+ caml_invalid_argument ("Weak.create");
7374 res = caml_alloc_shr (size, Abstract_tag);
7475 for (i = 1; i < size; i++) Field (res, i) = caml_ephe_none;
7576 Field (res, CAML_EPHE_LINK_OFFSET) = caml_ephe_list_head;
···119120 that is going to disappear is dead and so should trigger a cleaning
120121 */
121122static void do_check_key_clean(value ar, mlsize_t offset){
122122- CAMLassert ( offset >= 2);
123123+ CAMLassert (offset >= CAML_EPHE_FIRST_KEY);
123124 if (caml_gc_phase == Phase_clean){
124125 value elt = Field (ar, offset);
125126 if (elt != caml_ephe_none && Is_Dead_during_clean(elt)){
···161162162163CAMLprim value caml_ephe_set_key (value ar, value n, value el)
163164{
164164- mlsize_t offset = Long_val (n) + 2;
165165+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
165166 CAMLassert (Is_in_heap (ar));
166166- if (offset < 2 || offset >= Wosize_val (ar)){
167167+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
167168 caml_invalid_argument ("Weak.set");
168169 }
169170 do_check_key_clean(ar,offset);
···173174174175CAMLprim value caml_ephe_unset_key (value ar, value n)
175176{
176176- mlsize_t offset = Long_val (n) + 2;
177177+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
177178 CAMLassert (Is_in_heap (ar));
178178- if (offset < 2 || offset >= Wosize_val (ar)){
179179+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
179180 caml_invalid_argument ("Weak.set");
180181 }
181182 do_check_key_clean(ar,offset);
···185186186187value caml_ephe_set_key_option (value ar, value n, value el)
187188{
188188- mlsize_t offset = Long_val (n) + 2;
189189+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
189190 CAMLassert (Is_in_heap (ar));
190190- if (offset < 2 || offset >= Wosize_val (ar)){
191191+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
191192 caml_invalid_argument ("Weak.set");
192193 }
193194 do_check_key_clean(ar,offset);
···212213 cleaned we always need to check it. */
213214 caml_ephe_clean(ar);
214215 };
215215- do_set (ar, 1, el);
216216+ do_set (ar, CAML_EPHE_DATA_OFFSET, el);
216217 return Val_unit;
217218}
218219···226227CAMLprim value caml_ephe_get_key (value ar, value n)
227228{
228229 CAMLparam2 (ar, n);
229229- mlsize_t offset = Long_val (n) + 2;
230230+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
230231 CAMLlocal2 (res, elt);
231232 CAMLassert (Is_in_heap (ar));
232232- if (offset < 2 || offset >= Wosize_val (ar)){
233233+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
233234 caml_invalid_argument ("Weak.get_key");
234235 }
235236 if (is_ephe_key_none(ar, offset)){
···252253CAMLprim value caml_ephe_get_data (value ar)
253254{
254255 CAMLparam1 (ar);
255255- mlsize_t offset = 1;
256256 CAMLlocal2 (res, elt);
257257 CAMLassert (Is_in_heap (ar));
258258- elt = Field (ar, offset);
258258+ elt = Field (ar, CAML_EPHE_DATA_OFFSET);
259259 if(caml_gc_phase == Phase_clean) caml_ephe_clean(ar);
260260 if (elt == caml_ephe_none){
261261 res = None_val;
···272272CAMLprim value caml_ephe_get_key_copy (value ar, value n)
273273{
274274 CAMLparam2 (ar, n);
275275- mlsize_t offset = Long_val (n) + 2;
275275+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
276276 CAMLlocal2 (res, elt);
277277 value v; /* Caution: this is NOT a local root. */
278278 CAMLassert (Is_in_heap (ar));
279279- if (offset < 1 || offset >= Wosize_val (ar)){
279279+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
280280 caml_invalid_argument ("Weak.get_copy");
281281 }
282282···319319CAMLprim value caml_ephe_get_data_copy (value ar)
320320{
321321 CAMLparam1 (ar);
322322- mlsize_t offset = 1;
322322+ mlsize_t offset = CAML_EPHE_DATA_OFFSET;
323323 CAMLlocal2 (res, elt);
324324 value v; /* Caution: this is NOT a local root. */
325325 CAMLassert (Is_in_heap (ar));
···360360361361CAMLprim value caml_ephe_check_key (value ar, value n)
362362{
363363- mlsize_t offset = Long_val (n) + 2;
363363+ mlsize_t offset = Long_val (n) + CAML_EPHE_FIRST_KEY;
364364 CAMLassert (Is_in_heap (ar));
365365- if (offset < 2 || offset >= Wosize_val (ar)){
365365+ if (offset < CAML_EPHE_FIRST_KEY || offset >= Wosize_val (ar)){
366366 caml_invalid_argument ("Weak.check");
367367 }
368368 return Val_bool (!is_ephe_key_none(ar, offset));
···382382CAMLprim value caml_ephe_blit_key (value ars, value ofs,
383383 value ard, value ofd, value len)
384384{
385385- mlsize_t offset_s = Long_val (ofs) + 2;
386386- mlsize_t offset_d = Long_val (ofd) + 2;
385385+ mlsize_t offset_s = Long_val (ofs) + CAML_EPHE_FIRST_KEY;
386386+ mlsize_t offset_d = Long_val (ofd) + CAML_EPHE_FIRST_KEY;
387387 mlsize_t length = Long_val (len);
388388 long i;
389389 CAMLassert (Is_in_heap (ars));
390390 CAMLassert (Is_in_heap (ard));
391391- if (offset_s < 1 || offset_s + length > Wosize_val (ars)){
391391+ if (offset_s < CAML_EPHE_FIRST_KEY || offset_s + length > Wosize_val (ars)){
392392 caml_invalid_argument ("Weak.blit");
393393 }
394394- if (offset_d < 1 || offset_d + length > Wosize_val (ard)){
394394+ if (offset_d < CAML_EPHE_FIRST_KEY || offset_d + length > Wosize_val (ard)){
395395 caml_invalid_argument ("Weak.blit");
396396 }
397397 if (caml_gc_phase == Phase_clean){