1 /*
2     $Id: bytesobj.c 2606 2021-04-25 10:49:01Z soci $
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 
18 */
19 #include "bytesobj.h"
20 #include <string.h>
21 #include "math.h"
22 #include "eval.h"
23 #include "unicode.h"
24 #include "encoding.h"
25 #include "variables.h"
26 #include "arguments.h"
27 #include "error.h"
28 
29 #include "boolobj.h"
30 #include "floatobj.h"
31 #include "codeobj.h"
32 #include "intobj.h"
33 #include "strobj.h"
34 #include "bitsobj.h"
35 #include "listobj.h"
36 #include "typeobj.h"
37 #include "noneobj.h"
38 #include "errorobj.h"
39 #include "addressobj.h"
40 
41 static Type obj;
42 
43 Type *const BYTES_OBJ = &obj;
44 
45 static Bytes null_bytesval = { { &obj, 1 }, 0, null_bytesval.u.val, { { 0 } } };
46 static Bytes inv_bytesval = { { &obj, 1 }, ~0, inv_bytesval.u.val, { { 0 } } };
47 
48 Obj *const null_bytes = &null_bytesval.v;
49 Obj *const inv_bytes = &inv_bytesval.v;
50 static Bytes *bytes_value[256];
51 
ref_bytes(Bytes * v1)52 static inline Bytes *ref_bytes(Bytes *v1) {
53     v1->v.refcount++; return v1;
54 }
55 
byteslen(const Bytes * v1)56 static inline size_t byteslen(const Bytes *v1) {
57     ssize_t len = v1->len;
58     return (size_t)(len < 0 ? ~len : len);
59 }
60 
61 static MUST_CHECK Obj *bytes_from_int(const Int *, linepos_t);
62 static MUST_CHECK Obj *bytes_from_u8(unsigned int i);
63 
bytes_from_obj(Obj * v1,linepos_t epoint)64 MUST_CHECK Obj *bytes_from_obj(Obj *v1, linepos_t epoint) {
65     Obj *err, *ret;
66     switch (v1->obj->type) {
67     case T_NONE:
68     case T_ERROR:
69     case T_BYTES: return val_reference(v1);
70     case T_BOOL: return bytes_from_u8(v1 == true_value ? 1 : 0);
71     case T_BITS: return bytes_from_bits(Bits(v1), epoint);
72     case T_STR: return bytes_from_str(Str(v1), epoint, BYTES_MODE_TEXT);
73     case T_INT: return bytes_from_int(Int(v1), epoint);
74     case T_CODE: return bytes_from_code(Code(v1), epoint);
75     case T_ADDRESS: return bytes_from_address(Address(v1), epoint);
76     case T_FLOAT:
77          err = int_from_float(Float(v1), epoint);
78          if (err->obj != INT_OBJ) return err;
79          ret = bytes_from_int(Int(err), epoint);
80          val_destroy(err);
81          return ret;
82     default: break;
83     }
84     return new_error_conv(v1, BYTES_OBJ, epoint);
85 }
86 
convert(oper_t op)87 static MUST_CHECK Obj *convert(oper_t op) {
88     return bytes_from_obj(op->v2, op->epoint2);
89 }
90 
bytes_destroy(Bytes * v1)91 static FAST_CALL NO_INLINE void bytes_destroy(Bytes *v1) {
92     free(v1->data);
93 }
94 
destroy(Obj * o1)95 static FAST_CALL void destroy(Obj *o1) {
96     Bytes *v1 = Bytes(o1);
97     if (v1->u.val != v1->data) bytes_destroy(v1);
98 }
99 
new_bytes(size_t ln)100 MALLOC Bytes *new_bytes(size_t ln) {
101     Bytes *v = Bytes(val_alloc(BYTES_OBJ));
102     if (ln > sizeof v->u.val) {
103         v->u.s.max = ln;
104         v->u.s.hash = -1;
105         v->data = (uint8_t *)mallocx(ln);
106     } else {
107         v->data = v->u.val;
108     }
109     return v;
110 }
111 
new_bytes2(size_t ln)112 static MALLOC Bytes *new_bytes2(size_t ln) {
113     Bytes *v = Bytes(val_alloc(BYTES_OBJ));
114     if (ln > sizeof v->u.val) {
115         v->u.s.max = ln;
116         v->u.s.hash = -1;
117         v->data = (uint8_t *)malloc(ln);
118         if (v->data == NULL) {
119             val_destroy(Obj(v));
120             v = NULL;
121         }
122     } else {
123         v->data = v->u.val;
124     }
125     return v;
126 }
127 
extend_bytes(Bytes * v,size_t ln)128 static uint8_t *extend_bytes(Bytes *v, size_t ln) {
129     uint8_t *tmp;
130     if (ln <= sizeof v->u.val) {
131         return v->u.val;
132     }
133     if (v->u.val != v->data) {
134         if (ln <= v->u.s.max) {
135             v->u.s.hash = -1;
136             return v->data;
137         }
138         tmp = (uint8_t *)realloc(v->data, ln);
139         if (tmp == NULL) return tmp;
140     } else {
141         tmp = (uint8_t *)malloc(ln);
142         if (tmp == NULL) return tmp;
143         memcpy(tmp, v->u.val, byteslen(v));
144     }
145     v->data = tmp;
146     v->u.s.max = ln;
147     v->u.s.hash = -1;
148     return tmp;
149 }
150 
convert2(oper_t op)151 static MUST_CHECK Obj *convert2(oper_t op) {
152     Funcargs *v2 = Funcargs(op->v2);
153     argcount_t args = v2->len;
154     Error *err;
155     ival_t ival;
156     uval_t len2;
157     size_t blen;
158     Obj *v;
159     Bytes *bytes, *bytes2;
160     bool inplace, bits;
161     if (args != 2) {
162         return new_error_argnum(args, 1, 2, op->epoint2);
163     }
164     v = v2->val[1].val;
165     err = v->obj->ival(v, &ival, 8 * sizeof ival - 3, &v2->val[1].epoint);
166     if (err != 0) return Obj(err);
167     v = v2->val[0].val;
168     inplace = (v->obj == BYTES_OBJ);
169     bits = (v->obj == BITS_OBJ);
170     if (!inplace) {
171         v = bytes_from_obj(v, op->epoint2);
172         if (v->obj != BYTES_OBJ) return v;
173     }
174     bytes = Bytes(v);
175     if (ival >= 0) {
176         len2 = (uval_t)ival;
177         if (!inplace && !bits && bytes->len < 0) {
178             val_destroy(Obj(bytes));
179             err = new_error(ERROR______NOT_UVAL, &v2->val[0].epoint);
180             err->u.intconv.val = val_reference(v2->val[0].val);
181             return Obj(err);
182         }
183     } else {
184         len2 = (uval_t)-ival;
185     }
186     blen = byteslen(bytes);
187     if (blen > len2 || (ival < 0 && blen == len2 && bytes->data[len2 - 1] >= 0x80)) {
188         if (!inplace) val_destroy(Obj(bytes));
189         err = new_error(ival < 0 ? ERROR_____CANT_IVAL : ERROR_____CANT_UVAL, &v2->val[0].epoint);
190         err->u.intconv.bits = len2 * 8;
191         err->u.intconv.val = val_reference(v2->val[0].val);
192         return Obj(err);
193     }
194     if (blen == len2) {
195         return Obj(inplace ? ref_bytes(bytes) : bytes);
196     }
197     if (bytes->v.refcount == 1) {
198         if (extend_bytes(bytes, len2) == NULL) {
199             if (!inplace) val_destroy(Obj(bytes));
200             return new_error_mem(op->epoint3);
201         }
202         bytes2 = inplace ? ref_bytes(bytes) : bytes;
203         inplace = true;
204     } else {
205         bytes2 = new_bytes(len2);
206         if (blen != 0) memcpy(bytes2->data, bytes->data, blen);
207     }
208     memset(bytes2->data + blen, 0, len2 - blen);
209     bytes2->len = (ssize_t)(bytes->len < 0 ? ~(size_t)len2 : len2);
210     if (!inplace) val_destroy(Obj(bytes));
211     return Obj(bytes2);
212 }
213 
invert(const Bytes * v1,linepos_t epoint)214 static MUST_CHECK Obj *invert(const Bytes *v1, linepos_t epoint) {
215     size_t sz;
216     sz = byteslen(v1);
217     if (sz != 0) {
218         Bytes *v = new_bytes2(sz);
219         if (v == NULL) return new_error_mem(epoint);
220         v->len = ~v1->len;
221         memcpy(v->data, v1->data, sz);
222         return Obj(v);
223     }
224     return val_reference((v1->len < 0) ? null_bytes : inv_bytes);
225 }
226 
negate(Bytes * v1,linepos_t epoint)227 static MUST_CHECK Obj *negate(Bytes *v1, linepos_t epoint) {
228     size_t i, sz = byteslen(v1);
229     Bytes *v;
230     if (v1->len == 0) return val_reference(Obj(v1));
231     if (v1->len < 0) {
232         for (i = 0; i < sz; i++) {
233             if (v1->data[i] != (uint8_t)~0) break;
234         }
235         if (i == sz) return NULL;
236         v = new_bytes2(sz);
237         if (v == NULL) goto failed;
238         v->data[i] = (uint8_t)(v1->data[i] + 1U);
239     } else {
240         for (i = 0; i < sz; i++) {
241             if (v1->data[i] != 0) break;
242         }
243         if (i == sz) return val_reference(Obj(v1));
244         v = new_bytes2(sz);
245         if (v == NULL) goto failed;
246         v->data[i] = (uint8_t)(v1->data[i] - 1U);
247     }
248     if (i != 0) memset(v->data, (v1->len < 0) ? 0 : ~0, i);
249     i++;
250     if (i < sz) memcpy(v->data + i, v1->data + i, sz - i);
251     v->len = ~v1->len;
252     return Obj(v);
253 failed:
254     return new_error_mem(epoint);
255 }
256 
bytes_same(const Bytes * v1,const Bytes * v2)257 static FAST_CALL NO_INLINE bool bytes_same(const Bytes *v1, const Bytes *v2) {
258     return memcmp(v1->data, v2->data, byteslen(v2)) == 0;
259 }
260 
same(const Obj * o1,const Obj * o2)261 static FAST_CALL bool same(const Obj *o1, const Obj *o2) {
262     const Bytes *v1 = Bytes(o1), *v2 = Bytes(o2);
263     if (o1->obj != o2->obj || v1->len != v2->len) return false;
264     switch (v1->len) {
265     case ~0:
266     case 0: return true;
267     case ~1:
268     case 1: return v1->data[0] == v2->data[0];
269     default: return bytes_same(v1, v2);
270     }
271 }
272 
to_bool(const Bytes * v1)273 static bool to_bool(const Bytes *v1) {
274     size_t i, sz;
275     if (v1->len < 0) return true;
276     sz = byteslen(v1);
277     for (i = 0; i < sz; i++) {
278         if (v1->data[i] != 0) return true;
279     }
280     return false;
281 }
282 
truth(Obj * o1,Truth_types type,linepos_t epoint)283 static MUST_CHECK Obj *truth(Obj *o1, Truth_types type, linepos_t epoint) {
284     const Bytes *v1 = Bytes(o1);
285     size_t i, sz;
286     uint8_t inv;
287     switch (type) {
288     case TRUTH_ALL:
289         sz = byteslen(v1);
290         inv = (v1->len < 0) ? (uint8_t)~0 : 0;
291         for (i = 0; i < sz; i++) {
292             if (v1->data[i] == inv) return ref_false();
293         }
294         return ref_true();
295     case TRUTH_ANY:
296         if (v1->len == 0 || v1->len == ~0) return ref_false();
297         /* fall through */
298     default:
299         return truth_reference(to_bool(v1));
300     }
301     return DEFAULT_OBJ->truth(o1, type, epoint);
302 }
303 
z85_encode(uint8_t * dest,const uint8_t * src,size_t len)304 static uint8_t *z85_encode(uint8_t *dest, const uint8_t *src, size_t len) {
305     static const char *z85 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#";
306     size_t i;
307 
308     for (i = 0; i < len; i += 4) {
309         const uint8_t *src2 = src + i;
310         uint32_t tmp;
311         unsigned int j;
312 
313         tmp = (uint32_t)src2[3] | ((uint32_t)src2[2] << 8) | ((uint32_t)src2[1] << 16) | ((uint32_t)src2[0] << 24);
314 
315         for (j = 4; j > 0; j--) {
316             uint32_t divided = tmp / 85;
317             dest[j] = (uint8_t)z85[tmp - divided * 85];
318             tmp = divided;
319         }
320         dest[j] = (uint8_t)z85[tmp];
321         dest += 5;
322     }
323     return dest;
324 }
325 
326 static const uint8_t z85_dec[93] = {
327         68, 85, 84, 83, 82, 72, 85, 75, 76, 70, 65, 85, 63, 62, 69,
328     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  64, 85, 73, 66, 74, 71,
329     81, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
330     51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 85, 78, 67, 85,
331     85, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
332     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 79, 85, 80
333 };
334 
z85_decode(uint8_t * dest,const uint8_t * src,size_t len)335 static const uint8_t *z85_decode(uint8_t *dest, const uint8_t *src, size_t len) {
336     size_t i;
337 
338     for (i = 0; i < len; i += 4) {
339         uint32_t tmp;
340         unsigned int j;
341 
342         tmp = z85_dec[src[0] - 33];
343         for (j = 1; j < 5; j++) {
344             tmp = tmp * 85 + z85_dec[src[j] - 33];
345         }
346         dest[i] = (uint8_t)(tmp >> 24);
347         dest[i+1] = (uint8_t)(tmp >> 16);
348         dest[i+2] = (uint8_t)(tmp >> 8);
349         dest[i+3] = (uint8_t)tmp;
350         src += 5;
351     }
352     return src;
353 }
354 
str(Obj * o1,linepos_t UNUSED (epoint),size_t maxsize)355 static MUST_CHECK Obj *str(Obj *o1, linepos_t UNUSED(epoint), size_t maxsize) {
356     Bytes *v1 = Bytes(o1);
357     static const char *hex = "0123456789abcdef";
358     size_t i, len, len2, sz;
359     uint8_t *s, b;
360     Str *v;
361     sz = byteslen(v1);
362     len2 = sz * 2;
363     len = (v1->len < 0) ? 4 : 3;
364     len += len2;
365     if (len < len2 || sz > SIZE_MAX / 2) return NULL; /* overflow */
366     if (len > maxsize) return NULL;
367     v = new_str2(len);
368     if (v == NULL) return NULL;
369     v->chars = len;
370     s = v->data;
371 
372     if (v1->len < 0) *s++ = '~';
373     *s++ = 'x';
374     *s++ = '\'';
375     for (i = 0;i < sz; i++) {
376         b = v1->data[i];
377         *s++ = (uint8_t)hex[b >> 4];
378         *s++ = (uint8_t)hex[b & 0xf];
379     }
380     *s = '\'';
381     return Obj(v);
382 }
383 
repr(Obj * o1,linepos_t epoint,size_t maxsize)384 static MUST_CHECK Obj *repr(Obj *o1, linepos_t epoint, size_t maxsize) {
385     Bytes *v1 = Bytes(o1);
386     size_t len, len2, sz;
387     uint8_t *s;
388     Str *v;
389     sz = byteslen(v1);
390     if (sz <= 1) return str(o1, epoint, maxsize);
391     len2 = sz / 4 * 5;
392     if ((sz & 3) != 0) len2 += (sz & 3) + 1;
393     len = (v1->len < 0) ? 4 : 3;
394     len += len2;
395     if (len < len2 || sz > SIZE_MAX / 2) return NULL; /* overflow */
396     if (len > maxsize) return NULL;
397     v = new_str2(len);
398     if (v == NULL) return NULL;
399     v->chars = len;
400     s = v->data;
401 
402     if (v1->len < 0) *s++ = '~';
403     *s++ = 'z';
404     *s++ = '\'';
405     s = z85_encode(s, v1->data, sz & ~3U);
406     if ((sz & 3) != 0) {
407         uint8_t tmp2[5], tmp[4] = {0, 0, 0, 0};
408         memcpy(tmp + 4 - (sz & 3), v1->data + (sz & ~3U), sz & 3);
409         sz &= 3;
410         z85_encode(tmp2, tmp, sz);
411         sz++;
412         memcpy(s, tmp2 + 5 - sz, sz);
413         s += sz;
414     }
415     *s = '\'';
416     return Obj(v);
417 }
418 
hash(Obj * o1,int * hs,linepos_t UNUSED (epoint))419 static MUST_CHECK Obj *hash(Obj *o1, int *hs, linepos_t UNUSED(epoint)) {
420     Bytes *v1 = Bytes(o1);
421     size_t l = byteslen(v1);
422     const uint8_t *s2 = v1->data;
423     unsigned int h;
424     if (s2 != v1->u.val && v1->u.s.hash >= 0) {
425         *hs = v1->u.s.hash;
426         return NULL;
427     }
428     if (l == 0) {
429         *hs = 0;
430         return NULL;
431     }
432     h = (unsigned int)*s2 << 7;
433     while ((l--) != 0) h = (1000003 * h) ^ *s2++;
434     h ^= (unsigned int)v1->len;
435     h &= ((~0U) >> 1);
436     if (v1->data != v1->u.val) v1->u.s.hash = (int)h;
437     *hs = (int)h;
438     return NULL;
439 }
440 
bytes_from_hexstr(const uint8_t * s,linecpos_t * ln,linepos_t epoint)441 MUST_CHECK Obj *bytes_from_hexstr(const uint8_t *s, linecpos_t *ln, linepos_t epoint) {
442     Bytes *v;
443     linecpos_t i, j, spc;
444     uint8_t ch2, ch = s[0];
445 
446     i = 1; j = (s[1] == 0x20) ? 2 : 0; spc = 0;
447     for (;;) {
448         if ((ch2 = s[i]) == 0) {
449             *ln = i;
450             return ref_none();
451         }
452         i++;
453         if (ch2 == ch) {
454             break; /* end of string; */
455         }
456         ch2 ^= 0x30;
457         if (ch2 < 10) continue;
458         ch2 = (uint8_t)((ch2 | 0x20) - 0x71);
459         if (ch2 >= 6 && j == 0) {
460             if (ch2 == 0xbf && ((i - spc) & 1) == 0) {
461                 spc++;
462                 continue;
463             }
464             j = i;
465         }
466     }
467     if (j == 0 && s[i - 2] == 0x20) j = i - 1;
468     *ln = i;
469     if (j != 0) {
470         struct linepos_s epoint2;
471         epoint2 = *epoint;
472         epoint2.pos += j;
473         err_msg2(ERROR______EXPECTED, "hex digit", &epoint2);
474         return ref_none();
475     }
476     i -= spc;
477     if ((i & 1) != 0) err_msg2(ERROR______EXPECTED, "even number of hex digits", epoint);
478     j = (i - 2) / 2;
479     v = new_bytes2(j);
480     if (v == NULL) return new_error_mem(epoint);
481     v->len = (ssize_t)j;
482     for (i = 0; i < j; i++) {
483         unsigned int c1, c2;
484         s++;
485         c1 = s[i] ^ 0x30;
486         if (c1 >= 10) {
487             if (c1 == 0x10) {i--; continue;}
488             c1 = (c1 | 0x20) - 0x67;
489         }
490         c2 = s[i+1] ^ 0x30;
491         if (c2 >= 10) c2 = (c2 | 0x20) - 0x67;
492         v->data[i] = (uint8_t)((c1 << 4) | c2);
493     }
494     return Obj(v);
495 }
496 
bytes_from_z85str(const uint8_t * s,linecpos_t * ln,linepos_t epoint)497 MUST_CHECK Obj *bytes_from_z85str(const uint8_t *s, linecpos_t *ln, linepos_t epoint) {
498     Bytes *v;
499     linecpos_t i, j, sz;
500     uint8_t ch2, ch = s[0];
501 
502     i = 1; j = 0;
503     for (;;) {
504         if ((ch2 = s[i]) == 0) {
505             *ln = i;
506             return ref_none();
507         }
508         i++;
509         if (ch2 == ch) {
510             break; /* end of string; */
511         }
512         if (j == 0 && (ch2 <= ' ' || ch2 >= '~' || z85_dec[ch2 - 33] == 85)) j = i;
513     }
514     *ln = i;
515     if (j != 0) {
516         struct linepos_s epoint2;
517         epoint2 = *epoint;
518         epoint2.pos += j;
519         err_msg2(ERROR______EXPECTED, "z85 character", &epoint2);
520         return ref_none();
521     }
522     i = (i > 1) ? (i - 2) : 0;
523     j = i / 5;
524     i -= j * 5;
525     j *= 4;
526     if (i == 1) {
527         err_msg2(ERROR______EXPECTED, "valid z85 string", epoint);
528         return ref_none();
529     }
530     sz = (i > 1) ? (j + i - 1) : j;
531     v = new_bytes2(sz);
532     if (v == NULL) return new_error_mem(epoint);
533     v->len = (ssize_t)sz;
534     s = z85_decode(v->data, s + 1, j);
535     if (i > 1) {
536         uint8_t tmp2[4], tmp[5] = {'0', '0', '0', '0', '0'};
537         memcpy(tmp + 5 - i, s, i);
538         i--;
539         z85_decode(tmp2, tmp, i);
540         memcpy(v->data + j, tmp2 + 4 - i, i);
541         if (memcmp(tmp2, "\x0\x0\x0\x0", 4 - i) != 0) {
542             err_msg2(ERROR______EXPECTED, "valid z85 string", epoint);
543         }
544     }
545     return Obj(v);
546 }
547 
bytes_from_str(const Str * v1,linepos_t epoint,Textconv_types mode)548 MUST_CHECK Obj *bytes_from_str(const Str *v1, linepos_t epoint, Textconv_types mode) {
549     size_t len = v1->len, len2 = (mode == BYTES_MODE_PTEXT || mode == BYTES_MODE_NULL) ? 1 : 0;
550     uint8_t *s;
551     Bytes *v;
552     if (len != 0 || len2 != 0) {
553         struct encoder_s *encoder;
554         int ch;
555         if (actual_encoding == NULL) {
556             if (v1->chars == 1) {
557                 uchar_t ch2 = v1->data[0];
558                 if ((ch2 & 0x80) != 0) utf8in(v1->data, &ch2);
559                 return bytes_from_uval(ch2, 3);
560             }
561             return Obj(new_error((v1->chars == 0) ? ERROR__EMPTY_STRING : ERROR__NOT_ONE_CHAR, epoint));
562         }
563         if (len < sizeof v->u.val) len = sizeof v->u.val;
564         if (len == 0) {
565             return val_reference(null_bytes);
566         }
567         v = new_bytes2(len);
568         if (v == NULL) goto failed;
569         s = v->data;
570         encoder = encode_string_init(v1, epoint);
571         while ((ch = encode_string(encoder)) != EOF) {
572             if (len2 >= len) {
573                 if (v->u.val == s) {
574                     len = 32;
575                     s = (uint8_t *)malloc(len);
576                     if (s == NULL) goto failed2;
577                     v->data = s;
578                     memcpy(s, v->u.val, len2);
579                     v->u.s.hash = -1;
580                 } else {
581                     len += 1024;
582                     if (len < 1024) goto failed2; /* overflow */
583                     s = (uint8_t *)realloc(s, len);
584                     if (s == NULL) goto failed2;
585                     v->data = s;
586                 }
587                 v->u.s.max = len;
588             }
589             switch (mode) {
590             case BYTES_MODE_SHIFT_CHECK:
591             case BYTES_MODE_SHIFT: if ((ch & 0x80) != 0) encode_error(encoder, ERROR___NO_HIGH_BIT); s[len2] = ch & 0x7f; break;
592             case BYTES_MODE_SHIFTL: if ((ch & 0x80) != 0) encode_error(encoder, ERROR___NO_HIGH_BIT); s[len2] = (uint8_t)(ch << 1); break;
593             case BYTES_MODE_NULL_CHECK:if (ch == 0) {encode_error(encoder, ERROR_NO_ZERO_VALUE); ch = 0xff;} s[len2] = (uint8_t)ch; break;
594             case BYTES_MODE_NULL: if (ch == 0) encode_error(encoder, ERROR_NO_ZERO_VALUE); s[len2 - 1] = (uint8_t)ch; break;
595             case BYTES_MODE_PTEXT:
596             case BYTES_MODE_TEXT: s[len2] = (uint8_t)ch; break;
597             }
598             len2++;
599         }
600         switch (mode) {
601         case BYTES_MODE_SHIFT: if (len2 != 0) s[len2 - 1] |= 0x80; else err_msg2(ERROR__BYTES_NEEDED, NULL, epoint); break;
602         case BYTES_MODE_SHIFTL: if (len2 != 0) s[len2 - 1] |= 0x01; else err_msg2(ERROR__BYTES_NEEDED, NULL, epoint);break;
603         case BYTES_MODE_NULL: s[len2 - 1] = 0x00; break;
604         case BYTES_MODE_PTEXT: s[0] = (uint8_t)(len2 - 1); if (len2 > 256) err_msg2(ERROR____PTEXT_LONG, &len2, epoint); break;
605         case BYTES_MODE_SHIFT_CHECK:
606         case BYTES_MODE_NULL_CHECK:
607         case BYTES_MODE_TEXT: break;
608         }
609         if (v->u.val != s) {
610             if (len2 <= sizeof v->u.val) {
611                 if (len2 != 0) memcpy(v->u.val, s, len2);
612                 free(s);
613                 v->data = v->u.val;
614             } else if (len2 < len) {
615                 uint8_t *s2 = (uint8_t *)realloc(s, len2);
616                 v->data = (s2 != NULL) ? s2 : s;
617                 v->u.s.max = len2;
618             }
619         }
620         if (len2 > SSIZE_MAX) goto failed2; /* overflow */
621         v->len = (ssize_t)len2;
622         return Obj(v);
623     }
624     if (actual_encoding != NULL) {
625         if (mode == BYTES_MODE_SHIFT || mode == BYTES_MODE_SHIFTL) err_msg2(ERROR__EMPTY_STRING, NULL, epoint);
626     }
627     return val_reference(null_bytes);
628 failed2:
629     val_destroy(Obj(v));
630 failed:
631     return new_error_mem(epoint);
632 }
633 
bytes_from_u8(unsigned int i)634 static MUST_CHECK Obj *bytes_from_u8(unsigned int i) {
635     Bytes *v;
636     i &= 0xff;
637     v = bytes_value[i];
638     if (v == NULL) {
639         v = new_bytes(1);
640         v->len = 1;
641         v->data[0] = (uint8_t)i;
642         bytes_value[i] = v;
643     }
644     return Obj(ref_bytes(v));
645 }
646 
bytes_from_uval(uval_t i,unsigned int bytes)647 MUST_CHECK Obj *bytes_from_uval(uval_t i, unsigned int bytes) {
648     Bytes *v = new_bytes(bytes);
649     v->len = (ssize_t)bytes;
650     switch (bytes) {
651     default: v->data[3] = (uint8_t)(i >> 24); /* fall through */
652     case 3: v->data[2] = (uint8_t)(i >> 16); /* fall through */
653     case 2: v->data[1] = (uint8_t)(i >> 8); /* fall through */
654     case 1: v->data[0] = (uint8_t)i; /* fall through */
655     case 0: break;
656     }
657     return Obj(v);
658 }
659 
bytes_from_bits(const Bits * v1,linepos_t epoint)660 MUST_CHECK Obj *bytes_from_bits(const Bits *v1, linepos_t epoint) {
661     size_t i, sz, len1;
662     uint8_t *d;
663     Bytes *v;
664     bool inv = (v1->len < 0);
665 
666     len1 = v1->bits;
667     if (len1 == 0) {
668         return val_reference(inv ? inv_bytes : null_bytes);
669     }
670     if (len1 <= 8 && !inv) {
671         return bytes_from_u8(v1->data[0]);
672     }
673 
674     sz = len1 / 8;
675     if ((len1 % 8) != 0) sz++;
676     if (sz > SSIZE_MAX) goto failed; /* overflow */
677     v = new_bytes2(sz);
678     if (v == NULL) goto failed;
679     v->len = (ssize_t)(inv ? ~sz : sz);
680     d = v->data;
681 
682     len1 = (size_t)(inv ? ~v1->len : v1->len);
683     i = 0;
684     if (len1 != 0) {
685         bdigit_t b = v1->data[0];
686         int bits = 0;
687         size_t j = 0;
688         while (sz > i) {
689             d[i++] = (uint8_t)(b >> bits);
690             if (bits == (8 * sizeof b) - 8) {
691                 bits = 0;
692                 j++;
693                 if (j >= len1) break;
694                 b = v1->data[j];
695             } else bits += 8;
696         }
697     }
698     if (sz > i) memset(d + i , 0, sz - i);
699     return Obj(v);
700 failed:
701     return new_error_mem(epoint);
702 }
703 
bytes_from_int(const Int * v1,linepos_t epoint)704 static MUST_CHECK Obj *bytes_from_int(const Int *v1, linepos_t epoint) {
705     bool inv, c;
706     size_t i, sz;
707     uint8_t *d;
708     digit_t b2;
709     const digit_t *b;
710     Bytes *v;
711 
712     switch (v1->len) {
713     case -1:
714         if (v1->data[0] == 1) return val_reference(inv_bytes);
715         break;
716     case 0:
717         return val_reference(null_bytes);
718     case 1:
719         if (v1->data[0] < 256) return bytes_from_u8(v1->data[0]);
720         break;
721     default:
722         break;
723     }
724 
725     inv = (v1->len < 0);
726     sz = (size_t)(inv ? -v1->len : v1->len);
727     if (sz > SSIZE_MAX / sizeof *b) goto failed; /* overflow */
728     sz *= sizeof *b;
729     v = new_bytes2(sz);
730     if (v == NULL) goto failed;
731     d = v->data;
732 
733     b = v1->data;
734     c = inv;
735     b2 = 0;
736     for (i = 0; i < sz; i++) {
737         if (i % sizeof *b == 0) {
738             b2 = b[i / sizeof *b];
739             if (c) {
740                 c = (b2 == 0);
741                 b2--;
742             }
743         } else b2 >>= 8;
744         d[i] = (uint8_t)b2;
745     }
746 
747     while (sz != 0 && d[sz - 1] == 0) sz--;
748     if (sz > SSIZE_MAX) goto failed2; /* overflow */
749     v->len = (ssize_t)(inv ? ~sz : sz);
750     if (v->u.val != d) {
751         if (sz <= sizeof v->u.val) {
752             if (sz != 0) memcpy(v->u.val, d, sz);
753             free(d);
754             v->data = v->u.val;
755         } else if (sz < i) {
756             uint8_t *d2 = (uint8_t *)realloc(d, sz);
757             v->data = (d2 != NULL) ? d2 : d;
758             v->u.s.max = sz;
759         }
760     }
761     return Obj(v);
762 failed2:
763     val_destroy(Obj(v));
764 failed:
765     return new_error_mem(epoint);
766 }
767 
uvalx(Obj * o1,uval_t * uv,unsigned int bits)768 static bool uvalx(Obj *o1, uval_t *uv, unsigned int bits) {
769     Bytes *v1 = Bytes(o1);
770     size_t ln = byteslen(v1);
771     uval_t u;
772     if (ln > bits / 8) return false;
773     u = 0;
774     while (ln != 0) u = (u << 8) | v1->data[--ln];
775     *uv = (v1->len < 0) ? ~u : u;
776     return true;
777 }
778 
ival(Obj * o1,ival_t * iv,unsigned int bits,linepos_t epoint)779 static MUST_CHECK Error *ival(Obj *o1, ival_t *iv, unsigned int bits, linepos_t epoint) {
780     Error *v;
781     if (uvalx(o1, (uval_t *)iv, bits)) return NULL;
782     v = new_error(ERROR_____CANT_IVAL, epoint);
783     v->u.intconv.bits = bits;
784     v->u.intconv.val = val_reference(o1);
785     return v;
786 }
787 
uval(Obj * o1,uval_t * uv,unsigned int bits,linepos_t epoint)788 static MUST_CHECK Error *uval(Obj *o1, uval_t *uv, unsigned int bits, linepos_t epoint) {
789     Error *v;
790     if (uvalx(o1, uv, bits)) return NULL;
791     v = new_error(ERROR_____CANT_UVAL, epoint);
792     v->u.intconv.bits = bits;
793     v->u.intconv.val = val_reference(o1);
794     return v;
795 }
796 
uval2(Obj * o1,uval_t * uv,unsigned int bits,linepos_t epoint)797 static MUST_CHECK Error *uval2(Obj *o1, uval_t *uv, unsigned int bits, linepos_t epoint) {
798     if (Bytes(o1)->len < 0) {
799         Error *v = new_error(ERROR______NOT_UVAL, epoint);
800         v->u.intconv.val = val_reference(o1);
801         return v;
802     }
803     return uval(o1, uv, bits, epoint);
804 }
805 
float_from_bytes(const Bytes * v1,linepos_t epoint)806 MUST_CHECK Obj *float_from_bytes(const Bytes *v1, linepos_t epoint) {
807     double d;
808     size_t i, len1;
809     switch (v1->len) {
810     case ~3: d = -1.0 - (double)(v1->data[0] + v1->data[1] * 256 + v1->data[2] * 65536); break;
811     case ~2: d = -1.0 - (double)(v1->data[0] + v1->data[1] * 256); break;
812     case ~1: d = -1.0 - v1->data[0]; break;
813     case ~0: d = -1.0; break;
814     case 0: d = 0.0; break;
815     case 1: d = v1->data[0]; break;
816     case 2: d = (v1->data[0] + v1->data[1] * 256); break;
817     case 3: d = (v1->data[0] + v1->data[1] * 256 + v1->data[2] * 65536); break;
818     default:
819         d = ((v1->len < 0) ? 1 : 0) + v1->data[0];
820         len1 = byteslen(v1);
821         for (i = 1; i < len1; i++) {
822             d += ldexp(v1->data[i], (int)(i * 8));
823         }
824         if (v1->len < 0) d = -d;
825         return float_from_double(d, epoint);
826     }
827     return new_float(d);
828 }
829 
sign(Obj * o1,linepos_t UNUSED (epoint))830 static MUST_CHECK Obj *sign(Obj *o1, linepos_t UNUSED(epoint)) {
831     Bytes *v1 = Bytes(o1);
832     size_t i, sz;
833     if (v1->len < 0) return val_reference(minus1_value);
834     sz = byteslen(v1);
835     for (i = 0; i < sz; i++) {
836         if (v1->data[i] != 0) return val_reference(int_value[1]);
837     }
838     return val_reference(int_value[0]);
839 }
840 
function(oper_t op)841 static MUST_CHECK Obj *function(oper_t op) {
842     Bytes *v1 = Bytes(op->v2);
843     Obj *tmp, *ret;
844     op->v2 = tmp = int_from_bytes(v1, op->epoint2);
845     op->inplace = tmp->refcount == 1 ? tmp : NULL;
846     ret = tmp->obj->function(op);
847     val_destroy(tmp);
848     return ret;
849 }
850 
len(oper_t op)851 static MUST_CHECK Obj *len(oper_t op) {
852     Bytes *v1 = Bytes(op->v2);
853     return int_from_size(byteslen(v1));
854 }
855 
iter_element(struct iter_s * v1,size_t i)856 static FAST_CALL MUST_CHECK Obj *iter_element(struct iter_s *v1, size_t i) {
857     Bytes *iter = Bytes(v1->iter);
858     const Bytes *vv1 = Bytes(v1->data);
859     if (iter->v.refcount != 1) {
860         iter->v.refcount--;
861         iter = new_bytes(1);
862         v1->iter = Obj(iter);
863         iter->len = (vv1->len < 0) ? ~1 : 1;
864     }
865     iter->data[0] = vv1->data[i];
866     return Obj(iter);
867 }
868 
iter_forward(struct iter_s * v1)869 static FAST_CALL MUST_CHECK Obj *iter_forward(struct iter_s *v1) {
870     if (v1->val >= v1->len) return NULL;
871     return iter_element(v1, v1->val++);
872 }
873 
getiter(struct iter_s * v)874 static void getiter(struct iter_s *v) {
875     v->iter = val_reference(v->data);
876     v->val = 0;
877     v->data = val_reference(v->data);
878     v->next = iter_forward;
879     v->len = byteslen(Bytes(v->data));
880 }
881 
iter_reverse(struct iter_s * v1)882 static FAST_CALL MUST_CHECK Obj *iter_reverse(struct iter_s *v1) {
883     if (v1->val >= v1->len) return NULL;
884     return iter_element(v1, v1->len - ++v1->val);
885 }
886 
getriter(struct iter_s * v)887 static void getriter(struct iter_s *v) {
888     v->iter = val_reference(v->data);
889     v->val = 0;
890     v->data = val_reference(v->data);
891     v->next = iter_reverse;
892     v->len = byteslen(Bytes(v->data));
893 }
894 
binary(oper_t op)895 static inline MUST_CHECK Obj *binary(oper_t op) {
896     Bytes *vv1 = Bytes(op->v1), *vv2 = Bytes(op->v2);
897     size_t i, len1, len2, sz;
898     bool neg1, neg2, neg;
899     const uint8_t *v1, *v2;
900     uint8_t *v;
901     Bytes *vv;
902     len1 = byteslen(vv1); len2 = byteslen(vv2);
903 
904     if (len1 < len2) {
905         Bytes *tmp = vv1; vv1 = vv2; vv2 = tmp;
906         sz = len1; len1 = len2; len2 = sz;
907     }
908     neg1 = vv1->len < 0; neg2 = vv2->len < 0;
909 
910     switch (op->op) {
911     case O_AND:
912         neg = neg1 && neg2;
913         sz = neg2 ? len1 : len2;
914         break;
915     case O_OR:
916         neg = neg1 || neg2;
917         sz = neg2 ? len2 : len1;
918         break;
919     default:
920         neg = neg1 != neg2;
921         sz = len1;
922         break;
923     }
924     if (sz == 0) return val_reference(neg ? inv_bytes : null_bytes);
925     if (op->inplace == Obj(vv1)) {
926         vv = ref_bytes(vv1);
927         if (vv->data != vv->u.val) vv->u.s.hash = -1;
928     } else if (op->inplace == Obj(vv2) && sz <= len2) {
929         vv = ref_bytes(vv2);
930         if (vv->data != vv->u.val) vv->u.s.hash = -1;
931     } else {
932         vv = new_bytes2(sz);
933         if (vv == NULL) return new_error_mem(op->epoint3);
934     }
935     v = vv->data;
936     v1 = vv1->data; v2 = vv2->data;
937 
938     i = 0;
939     switch (op->op) {
940     case O_AND:
941         if (neg1) {
942             if (neg2) {
943                 for (; i < len2; i++) v[i] = v1[i] | v2[i];
944             } else {
945                 for (; i < len2; i++) v[i] = (uint8_t)(~v1[i] & v2[i]);
946             }
947         } else {
948             if (neg2) {
949                 for (; i < len2; i++) v[i] = (uint8_t)(v1[i] & ~v2[i]);
950             } else {
951                 for (; i < len2; i++) v[i] = v1[i] & v2[i];
952             }
953         }
954         break;
955     case O_OR:
956         if (neg1) {
957             if (neg2) {
958                 for (; i < len2; i++) v[i] = v1[i] & v2[i];
959             } else {
960                 for (; i < len2; i++) v[i] = (uint8_t)(v1[i] & ~v2[i]);
961             }
962         } else {
963             if (neg2) {
964                 for (; i < len2; i++) v[i] = (uint8_t)(~v1[i] & v2[i]);
965             } else {
966                 for (; i < len2; i++) v[i] = v1[i] | v2[i];
967             }
968         }
969         break;
970     default:
971         for (; i < len2; i++) v[i] = v1[i] ^ v2[i];
972         break;
973     }
974     for (; i < sz; i++) v[i] = v1[i];
975     /*if (i > SSIZE_MAX) err_msg_out_of_memory();*/ /* overflow */
976     vv->len = (ssize_t)(neg ? ~i : i);
977     return Obj(vv);
978 }
979 
concat(oper_t op)980 static MUST_CHECK Obj *concat(oper_t op) {
981     Bytes *v1 = Bytes(op->v1), *v2 = Bytes(op->v2), *v;
982     uint8_t *s;
983     size_t ln, i, len1, len2;
984 
985     if (v1->len == 0) {
986         return Obj(ref_bytes(v2));
987     }
988     if (v2->len == 0 || v2->len == ~(ssize_t)0) {
989         return Obj(ref_bytes(v1));
990     }
991     len1 = byteslen(v1);
992     len2 = byteslen(v2);
993     ln = len1 + len2;
994     if (ln < len2 || ln > SSIZE_MAX) goto failed; /* overflow */
995     if (op->inplace == Obj(v1)) {
996         size_t ln2;
997         if (ln > sizeof v1->u.val && v1->u.val != v1->data && ln > v1->u.s.max) {
998             ln2 = ln + (ln < 1024 ? ln : 1024);
999             if (ln2 < ln) ln2 = ln;
1000         } else ln2 = ln;
1001         s = extend_bytes(v1, ln2);
1002         if (s == NULL) goto failed;
1003         v = ref_bytes(v1);
1004     } else {
1005         v = new_bytes2(ln);
1006         if (v == NULL) goto failed;
1007         s = v->data;
1008         memcpy(s, v1->data, len1);
1009     }
1010     if ((v2->len ^ v1->len) < 0) {
1011         for (i = 0; i < len2; i++) s[i + len1] = (uint8_t)~v2->data[i];
1012     } else memcpy(s + len1, v2->data, len2);
1013     v->len = (ssize_t)(v1->len < 0 ? ~ln : ln);
1014     return Obj(v);
1015 failed:
1016     return new_error_mem(op->epoint3);
1017 }
1018 
icmp(oper_t op)1019 static int icmp(oper_t op) {
1020     const Bytes *v1 = Bytes(op->v1), *v2 = Bytes(op->v2);
1021     size_t len1 = byteslen(v1), len2 = byteslen(v2);
1022     size_t i, ln = (len1 < len2) ? len1 : len2;
1023     int h;
1024     if ((v1->len >= 0) == (v2->len >= 0)) {
1025         h = memcmp(v1->data, v2->data, ln);
1026     } else {
1027         h = 0;
1028         for (i = 0; i < ln; i++) {
1029             h = v1->data[i] - (uint8_t)~v2->data[i];
1030             if (h != 0) break;
1031         }
1032     }
1033     if (h != 0) return (v1->len >= 0) ? h : -h;
1034     if (len1 < len2) return -1;
1035     return (len1 > len2) ? 1 : 0;
1036 }
1037 
calc1(oper_t op)1038 static MUST_CHECK Obj *calc1(oper_t op) {
1039     Bytes *v1 = Bytes(op->v1);
1040     Obj *v;
1041     Obj *tmp;
1042     unsigned int u;
1043     switch (op->op) {
1044     case O_BANK:
1045     case O_HIGHER:
1046     case O_LOWER:
1047     case O_HWORD:
1048     case O_WORD:
1049     case O_BSWORD:
1050         u = (v1->len > 0 || v1->len < ~0) ? v1->data[0] : 0;
1051         if (v1->len > 1 || v1->len < ~1) u |= (unsigned int)v1->data[1] << 8;
1052         if (v1->len > 2 || v1->len < ~2) u |= (unsigned int)v1->data[2] << 8;
1053         return bits_calc1(op->op, (v1->len < 0) ? ~u : u);
1054     case O_POS: return val_reference(Obj(v1));
1055     case O_INV:
1056         if (op->inplace != Obj(v1)) return invert(v1, op->epoint3);
1057         v1->len = ~v1->len;
1058         if (v1->data != v1->u.val) v1->u.s.hash = -1;
1059         return val_reference(Obj(v1));
1060     case O_NEG:
1061         v = negate(v1, op->epoint3);
1062         if (v != NULL) return v;
1063         /* fall through */
1064     case O_STRING:
1065         tmp = int_from_bytes(v1, op->epoint);
1066         op->v1 = tmp;
1067         op->inplace = (tmp->refcount == 1) ? tmp : NULL;
1068         v = tmp->obj->calc1(op);
1069         val_destroy(tmp);
1070         return v;
1071     case O_LNOT:
1072         if (diagnostics.strict_bool) err_msg_bool_oper(op);
1073         return truth_reference(!to_bool(v1));
1074     default: break;
1075     }
1076     return obj_oper_error(op);
1077 }
1078 
calc2_bytes(oper_t op)1079 static MUST_CHECK Obj *calc2_bytes(oper_t op) {
1080     Bytes *v1 = Bytes(op->v1), *v2 = Bytes(op->v2);
1081     int val;
1082     switch (op->op) {
1083     case O_ADD:
1084     case O_SUB:
1085     case O_MUL:
1086     case O_DIV:
1087     case O_MOD:
1088     case O_EXP:
1089         {
1090             Obj *tmp, *tmp2, *result;
1091             tmp = int_from_bytes(v1, op->epoint);
1092             tmp2 = int_from_bytes(v2, op->epoint2);
1093             op->v1 = tmp;
1094             op->v2 = tmp2;
1095             op->inplace = (tmp->refcount == 1) ? tmp : NULL;
1096             result = tmp->obj->calc2(op);
1097             if (result->obj == ERROR_OBJ) {
1098                 error_obj_update(Error(result), tmp, Obj(v1));
1099                 error_obj_update(Error(result), tmp2, Obj(v2));
1100             }
1101             val_destroy(tmp2);
1102             val_destroy(tmp);
1103             return result;
1104         }
1105     case O_AND:
1106     case O_OR:
1107     case O_XOR: return binary(op);
1108     case O_LSHIFT:
1109     case O_RSHIFT:
1110         {
1111             Obj *tmp, *result;
1112             tmp = bits_from_bytes(v1, op->epoint);
1113             op->v1 = tmp;
1114             op->inplace = (tmp->refcount == 1) ? tmp : NULL;
1115             result = tmp->obj->calc2(op);
1116             if (result->obj == ERROR_OBJ) error_obj_update(Error(result), tmp, Obj(v1));
1117             val_destroy(tmp);
1118             return result;
1119         }
1120     case O_CMP:
1121         val = icmp(op);
1122         return val_reference(val < 0 ? minus1_value : int_value[(val > 0) ? 1 : 0]);
1123     case O_EQ: return truth_reference(icmp(op) == 0);
1124     case O_NE: return truth_reference(icmp(op) != 0);
1125     case O_MIN:
1126     case O_LT: return truth_reference(icmp(op) < 0);
1127     case O_LE: return truth_reference(icmp(op) <= 0);
1128     case O_MAX:
1129     case O_GT: return truth_reference(icmp(op) > 0);
1130     case O_GE: return truth_reference(icmp(op) >= 0);
1131     case O_CONCAT: return concat(op);
1132     case O_IN:
1133         {
1134             const uint8_t *c, *c2, *e;
1135             size_t len1 = byteslen(v1), len2 = byteslen(v2), i;
1136             if (len1 == 0) return ref_true();
1137             if (len1 > len2) return ref_false();
1138             c2 = v2->data;
1139             e = c2 + len2 - len1;
1140             if ((v1->len ^ v2->len) < 0) {
1141                 for (;;) {
1142                     c = (const uint8_t *)memchr(c2, ~v1->data[0], (size_t)(e - c2) + 1);
1143                     if (c == NULL) return ref_false();
1144                     for (i = 1; i < len1; i++) {
1145                         if (c[i] != (0xff - v1->data[i])) break;
1146                     }
1147                     if (i == len1) return ref_true();
1148                     c2 = c + 1;
1149                 }
1150             } else {
1151                 for (;;) {
1152                     c = (const uint8_t *)memchr(c2, v1->data[0], (size_t)(e - c2) + 1);
1153                     if (c == NULL) return ref_false();
1154                     if (memcmp(c, v1->data, len1) == 0) return ref_true();
1155                     c2 = c + 1;
1156                 }
1157             }
1158         }
1159     default: break;
1160     }
1161     return obj_oper_error(op);
1162 }
1163 
repeat(oper_t op)1164 static inline MUST_CHECK Obj *repeat(oper_t op) {
1165     Bytes *v1 = Bytes(op->v1), *v;
1166     uval_t rep;
1167     size_t len1 = byteslen(v1);
1168     Error *err;
1169 
1170     err = op->v2->obj->uval(op->v2, &rep, 8 * sizeof rep, op->epoint2);
1171     if (err != NULL) return Obj(err);
1172 
1173     if (len1 == 0 || rep == 0) return val_reference((v1->len < 0) ? inv_bytes : null_bytes);
1174     do {
1175         uint8_t *s;
1176         if (rep == 1) {
1177             return Obj(ref_bytes(v1));
1178         }
1179         if (len1 > SSIZE_MAX / rep) break; /* overflow */
1180         v = new_bytes2(len1 * rep);
1181         if (v == NULL) break;
1182         s = v->data;
1183         v->len = 0;
1184         while ((rep--) != 0) {
1185             memcpy(s + v->len, v1->data, len1);
1186             v->len += (ssize_t)len1;
1187         }
1188         if (v1->len < 0) v->len = ~v->len;
1189         return Obj(v);
1190     } while (false);
1191     return new_error_mem(op->epoint3);
1192 }
1193 
slice(oper_t op,argcount_t indx)1194 static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {
1195     uint8_t *p2;
1196     size_t i;
1197     Bytes *v, *v1 = Bytes(op->v1);
1198     Obj *err;
1199     uint8_t inv = (v1->len < 0) ? (uint8_t)~0 : 0;
1200     Funcargs *args = Funcargs(op->v2);
1201     struct indexoffs_s io;
1202 
1203     if (args->len < 1 || args->len - 1 > indx) {
1204         return new_error_argnum(args->len, 1, indx + 1, op->epoint2);
1205     }
1206     io.len = byteslen(v1);
1207     io.epoint = &args->val[indx].epoint;
1208     io.val = args->val[indx].val;
1209 
1210     if (io.val->obj->iterable) {
1211         struct iter_s iter;
1212         iter.data = io.val; io.val->obj->getiter(&iter);
1213 
1214         if (iter.len == 0) {
1215             iter_destroy(&iter);
1216             return val_reference(null_bytes);
1217         }
1218         v = new_bytes2(iter.len);
1219         if (v == NULL) {
1220             iter_destroy(&iter);
1221             goto failed;
1222         }
1223         p2 = v->data;
1224         for (i = 0; i < iter.len && (io.val = iter.next(&iter)) != NULL; i++) {
1225             err = indexoffs(&io);
1226             if (err != NULL) {
1227                 val_destroy(Obj(v));
1228                 iter_destroy(&iter);
1229                 return err;
1230             }
1231             p2[i] = v1->data[io.offs] ^ inv;
1232         }
1233         iter_destroy(&iter);
1234         if (i > SSIZE_MAX) goto failed2; /* overflow */
1235         v->len = (ssize_t)i;
1236         return Obj(v);
1237     }
1238     if (io.val->obj == COLONLIST_OBJ) {
1239         struct sliceparam_s s;
1240 
1241         err = sliceparams(&s, &io);
1242         if (err != NULL) return err;
1243 
1244         switch (s.length) {
1245         case 0:
1246             return val_reference(null_bytes);
1247         case 1:
1248             return bytes_from_u8(v1->data[s.offset] ^ inv);
1249         }
1250         if (s.step == 1 && inv == 0) {
1251             if (s.length == byteslen(v1)) {
1252                 return Obj(ref_bytes(v1)); /* original bytes */
1253             }
1254             if (op->inplace == Obj(v1)) {
1255                 v = ref_bytes(v1);
1256                 if (v->data != v->u.val && s.length <= sizeof v->u.val) {
1257                     p2 = v->u.val;
1258                     memcpy(p2, v1->data + s.offset, s.length);
1259                 } else {
1260                     p2 = v->data;
1261                     if (s.offset != 0) memmove(p2, v1->data + s.offset, s.length);
1262                     if (v->data != v->u.val) v->u.s.hash = -1;
1263                 }
1264             } else {
1265                 v = new_bytes2(s.length);
1266                 if (v == NULL) goto failed;
1267                 p2 = v->data;
1268                 memcpy(p2, v1->data + s.offset, s.length);
1269             }
1270         } else {
1271             if (s.step > 0 && op->inplace == Obj(v1)) {
1272                 v = ref_bytes(v1);
1273                 if (v->data != v->u.val && s.length <= sizeof v->u.val) {
1274                     p2 = v->u.val;
1275                 } else {
1276                     p2 = v->data;
1277                     if (v->data != v->u.val) v->u.s.hash = -1;
1278                 }
1279             } else {
1280                 v = new_bytes2(s.length);
1281                 if (v == NULL) goto failed;
1282                 p2 = v->data;
1283             }
1284             for (i = 0; i < s.length; i++) {
1285                 p2[i] = v1->data[s.offset] ^ inv;
1286                 s.offset += s.step;
1287             }
1288         }
1289         if (p2 != v->data) {
1290             free(v->data);
1291             v->data = p2;
1292         }
1293         v->len = (ssize_t)s.length;
1294         return Obj(v);
1295     }
1296     err = indexoffs(&io);
1297     if (err != NULL) return err;
1298     return bytes_from_u8(v1->data[io.offs] ^ inv);
1299 failed2:
1300     val_destroy(Obj(v));
1301 failed:
1302     return new_error_mem(op->epoint3);
1303 }
1304 
calc2(oper_t op)1305 static MUST_CHECK Obj *calc2(oper_t op) {
1306     Bytes *v1 = Bytes(op->v1);
1307     Obj *o2 = op->v2;
1308     Obj *tmp;
1309 
1310     if (op->op == O_X) {
1311         if (o2 == none_value || o2->obj == ERROR_OBJ) return val_reference(o2);
1312         return repeat(op);
1313     }
1314     if (op->op == O_LAND) {
1315         if (diagnostics.strict_bool) err_msg_bool_oper(op);
1316         return val_reference(to_bool(v1) ? o2 : Obj(v1));
1317     }
1318     if (op->op == O_LOR) {
1319         if (diagnostics.strict_bool) err_msg_bool_oper(op);
1320         return val_reference(to_bool(v1) ? Obj(v1) : o2);
1321     }
1322     if (o2->obj->iterable) {
1323         if (op->op != O_MEMBER) {
1324             return o2->obj->rcalc2(op);
1325         }
1326     }
1327     switch (o2->obj->type) {
1328     case T_BYTES: return calc2_bytes(op);
1329     case T_BOOL:
1330         if (diagnostics.strict_bool) err_msg_bool_oper(op);
1331         /* fall through */
1332     case T_INT:
1333     case T_BITS:
1334     case T_FLOAT:
1335     case T_CODE:
1336     case T_ADDRESS:
1337     case T_REGISTER:
1338         {
1339             Obj *result;
1340             switch (op->op) {
1341             case O_CONCAT:
1342             case O_AND:
1343             case O_OR:
1344             case O_XOR:
1345             case O_LSHIFT:
1346             case O_RSHIFT: tmp = bits_from_bytes(v1, op->epoint); break;
1347             default: tmp = int_from_bytes(v1, op->epoint);
1348             }
1349             op->v1 = tmp;
1350             op->inplace = (tmp->refcount == 1) ? tmp : NULL;
1351             result = tmp->obj->calc2(op);
1352             if (result->obj == ERROR_OBJ) error_obj_update(Error(result), tmp, Obj(v1));
1353             val_destroy(tmp);
1354             return result;
1355         }
1356     case T_STR:
1357     case T_GAP:
1358         if (op->op != O_MEMBER) {
1359             return o2->obj->rcalc2(op);
1360         }
1361         break;
1362     case T_NONE:
1363     case T_ERROR:
1364         return val_reference(o2);
1365     default:
1366         break;
1367     }
1368     return obj_oper_error(op);
1369 }
1370 
rcalc2(oper_t op)1371 static MUST_CHECK Obj *rcalc2(oper_t op) {
1372     Bytes *v2 = Bytes(op->v2);
1373     Obj *o1 = op->v1;
1374     Obj *tmp;
1375     switch (o1->obj->type) {
1376     case T_BOOL:
1377         if (diagnostics.strict_bool) err_msg_bool_oper(op);
1378         /* fall through */
1379     case T_INT:
1380     case T_BITS:
1381     case T_FLOAT:
1382     case T_CODE:
1383     case T_ADDRESS:
1384         {
1385             Obj *result;
1386             switch (op->op) {
1387             case O_CONCAT:
1388             case O_AND:
1389             case O_OR:
1390             case O_XOR: tmp = bits_from_bytes(v2, op->epoint2); break;
1391             default: tmp = int_from_bytes(v2, op->epoint2);
1392             }
1393             op->v2 = tmp;
1394             op->inplace = NULL;
1395             result = o1->obj->calc2(op);
1396             if (result->obj == ERROR_OBJ) error_obj_update(Error(result), tmp, Obj(v2));
1397             val_destroy(tmp);
1398             return result;
1399         }
1400     default:
1401         if (!o1->obj->iterable) {
1402             break;
1403         }
1404         /* fall through */
1405     case T_NONE:
1406     case T_ERROR:
1407         if (op->op != O_IN) {
1408             return o1->obj->calc2(op);
1409         }
1410         break;
1411     }
1412     return obj_oper_error(op);
1413 }
1414 
bytesobj_init(void)1415 void bytesobj_init(void) {
1416     new_type(&obj, T_BYTES, "bytes", sizeof(Bytes));
1417     obj.convert = convert;
1418     obj.convert2 = convert2;
1419     obj.destroy = destroy;
1420     obj.same = same;
1421     obj.truth = truth;
1422     obj.hash = hash;
1423     obj.repr = repr;
1424     obj.str = str;
1425     obj.ival = ival;
1426     obj.uval = uval;
1427     obj.uval2 = uval2;
1428     obj.iaddress = ival;
1429     obj.uaddress = uval;
1430     obj.sign = sign;
1431     obj.function = function;
1432     obj.len = len;
1433     obj.getiter = getiter;
1434     obj.getriter = getriter;
1435     obj.calc1 = calc1;
1436     obj.calc2 = calc2;
1437     obj.rcalc2 = rcalc2;
1438     obj.slice = slice;
1439 }
1440 
bytesobj_names(void)1441 void bytesobj_names(void) {
1442     new_builtin("bytes", val_reference(Obj(BYTES_OBJ)));
1443 }
1444 
bytesobj_destroy(void)1445 void bytesobj_destroy(void) {
1446     int i;
1447 #ifdef DEBUG
1448     if (null_bytes->refcount != 1) fprintf(stderr, "bytes %" PRIuSIZE "\n", null_bytes->refcount - 1);
1449     if (inv_bytes->refcount != 1) fprintf(stderr, "invbytes %" PRIuSIZE "\n", inv_bytes->refcount - 1);
1450     for (i = 0; i < 256; i++) {
1451         if (bytes_value[i] && bytes_value[i]->v.refcount != 1) {
1452             fprintf(stderr, "bytes[%d] %" PRIuSIZE "\n", i, bytes_value[i]->v.refcount - 1);
1453         }
1454     }
1455 #endif
1456 
1457     for (i = 0; i < 256; i++) {
1458         if (bytes_value[i] != NULL) val_destroy(Obj(bytes_value[i]));
1459     }
1460 }
1461