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