Deleted Added
full compact
bcode.c (232994) bcode.c (244861)
1/* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
1/* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
20__FBSDID("$FreeBSD: head/usr.bin/dc/bcode.c 232994 2012-03-15 01:43:44Z kevlo $");
20__FBSDID("$FreeBSD: head/usr.bin/dc/bcode.c 244861 2012-12-30 15:20:27Z kevlo $");
21
22#include <err.h>
23#include <limits.h>
24#include <openssl/ssl.h>
25#include <signal.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "extern.h"
31
21
22#include <err.h>
23#include <limits.h>
24#include <openssl/ssl.h>
25#include <signal.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "extern.h"
31
32BIGNUM zero;
33
34#define __inline
35
36#define MAX_ARRAY_INDEX 2048
37#define READSTACK_SIZE 8
38
39#define NO_ELSE -2 /* -1 is EOF */
40#define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1)
41#define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1)

--- 203 unchanged lines hidden (view full) ---

245 stack_init(&bmachine.reg[i]);
246
247 bmachine.readstack_sz = READSTACK_SIZE;
248 bmachine.readstack = calloc(sizeof(struct source),
249 bmachine.readstack_sz);
250 if (bmachine.readstack == NULL)
251 err(1, NULL);
252 bmachine.obase = bmachine.ibase = 10;
32#define __inline
33
34#define MAX_ARRAY_INDEX 2048
35#define READSTACK_SIZE 8
36
37#define NO_ELSE -2 /* -1 is EOF */
38#define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1)
39#define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1)

--- 203 unchanged lines hidden (view full) ---

243 stack_init(&bmachine.reg[i]);
244
245 bmachine.readstack_sz = READSTACK_SIZE;
246 bmachine.readstack = calloc(sizeof(struct source),
247 bmachine.readstack_sz);
248 if (bmachine.readstack == NULL)
249 err(1, NULL);
250 bmachine.obase = bmachine.ibase = 10;
253 BN_init(&zero);
254 bn_check(BN_zero(&zero));
255}
256
251}
252
253u_int
254bmachine_scale(void)
255{
256 return (bmachine.scale);
257}
258
257/* Reset the things needed before processing a (new) file */
258void
259reset_bmachine(struct source *src)
260{
261
262 bmachine.readsp = 0;
263 bmachine.readstack[0] = *src;
264}

--- 137 unchanged lines hidden (view full) ---

402 bn_check(BN_exp(a, a, p, ctx));
403 bn_check(BN_div(i, f, n->number, a, ctx));
404 BN_CTX_free(ctx);
405 BN_free(a);
406 BN_free(p);
407 }
408}
409
259/* Reset the things needed before processing a (new) file */
260void
261reset_bmachine(struct source *src)
262{
263
264 bmachine.readsp = 0;
265 bmachine.readstack[0] = *src;
266}

--- 137 unchanged lines hidden (view full) ---

404 bn_check(BN_exp(a, a, p, ctx));
405 bn_check(BN_div(i, f, n->number, a, ctx));
406 BN_CTX_free(ctx);
407 BN_free(a);
408 BN_free(p);
409 }
410}
411
410__inline void
412void
411normalize(struct number *n, u_int s)
412{
413
414 scale_number(n->number, s - n->scale);
415 n->scale = s;
416}
417
418static u_long
419get_ulong(struct number *n)
420{
421
422 normalize(n, 0);
423 return (BN_get_word(n->number));
424}
425
426void
427negate(struct number *n)
428{
429
413normalize(struct number *n, u_int s)
414{
415
416 scale_number(n->number, s - n->scale);
417 n->scale = s;
418}
419
420static u_long
421get_ulong(struct number *n)
422{
423
424 normalize(n, 0);
425 return (BN_get_word(n->number));
426}
427
428void
429negate(struct number *n)
430{
431
430 bn_check(BN_sub(n->number, &zero, n->number));
432 BN_set_negative(n->number, !BN_is_negative(n->number));
431}
432
433static __inline void
434push_number(struct number *n)
435{
436
437 stack_pushnumber(&bmachine.stack, n);
438}

--- 137 unchanged lines hidden (view full) ---

576static void
577set_scale(void)
578{
579 struct number *n;
580 u_long scale;
581
582 n = pop_number();
583 if (n != NULL) {
433}
434
435static __inline void
436push_number(struct number *n)
437{
438
439 stack_pushnumber(&bmachine.stack, n);
440}

--- 137 unchanged lines hidden (view full) ---

578static void
579set_scale(void)
580{
581 struct number *n;
582 u_long scale;
583
584 n = pop_number();
585 if (n != NULL) {
584 if (BN_cmp(n->number, &zero) < 0)
586 if (BN_is_negative(n->number))
585 warnx("scale must be a nonnegative number");
586 else {
587 scale = get_ulong(n);
588 if (scale != BN_MASK2 && scale <= UINT_MAX)
589 bmachine.scale = (u_int)scale;
590 else
591 warnx("scale too large");
592 }

--- 280 unchanged lines hidden (view full) ---

873 int reg;
874
875 reg = readreg();
876 if (reg >= 0) {
877 inumber = pop_number();
878 if (inumber == NULL)
879 return;
880 idx = get_ulong(inumber);
587 warnx("scale must be a nonnegative number");
588 else {
589 scale = get_ulong(n);
590 if (scale != BN_MASK2 && scale <= UINT_MAX)
591 bmachine.scale = (u_int)scale;
592 else
593 warnx("scale too large");
594 }

--- 280 unchanged lines hidden (view full) ---

875 int reg;
876
877 reg = readreg();
878 if (reg >= 0) {
879 inumber = pop_number();
880 if (inumber == NULL)
881 return;
882 idx = get_ulong(inumber);
881 if (BN_cmp(inumber->number, &zero) < 0)
883 if (BN_is_negative(inumber->number))
882 warnx("negative idx");
883 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
884 warnx("idx too big");
885 else {
886 stack = &bmachine.reg[reg];
887 v = frame_retrieve(stack, idx);
888 if (v == NULL || v->type == BCODE_NONE) {
889 n = new_number();

--- 22 unchanged lines hidden (view full) ---

912 if (inumber == NULL)
913 return;
914 value = pop();
915 if (value == NULL) {
916 free_number(inumber);
917 return;
918 }
919 idx = get_ulong(inumber);
884 warnx("negative idx");
885 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
886 warnx("idx too big");
887 else {
888 stack = &bmachine.reg[reg];
889 v = frame_retrieve(stack, idx);
890 if (v == NULL || v->type == BCODE_NONE) {
891 n = new_number();

--- 22 unchanged lines hidden (view full) ---

914 if (inumber == NULL)
915 return;
916 value = pop();
917 if (value == NULL) {
918 free_number(inumber);
919 return;
920 }
921 idx = get_ulong(inumber);
920 if (BN_cmp(inumber->number, &zero) < 0) {
922 if (BN_is_negative(inumber->number)) {
921 warnx("negative idx");
922 stack_free_value(value);
923 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
924 warnx("idx too big");
925 stack_free_value(value);
926 } else {
927 stack = &bmachine.reg[reg];
928 frame_assign(stack, idx, value);

--- 75 unchanged lines hidden (view full) ---

1004 normalize(b, r->scale);
1005 bn_check(BN_sub(r->number, b->number, a->number));
1006 push_number(r);
1007 free_number(a);
1008 free_number(b);
1009}
1010
1011void
923 warnx("negative idx");
924 stack_free_value(value);
925 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
926 warnx("idx too big");
927 stack_free_value(value);
928 } else {
929 stack = &bmachine.reg[reg];
930 frame_assign(stack, idx, value);

--- 75 unchanged lines hidden (view full) ---

1006 normalize(b, r->scale);
1007 bn_check(BN_sub(r->number, b->number, a->number));
1008 push_number(r);
1009 free_number(a);
1010 free_number(b);
1011}
1012
1013void
1012bmul_number(struct number *r, struct number *a, struct number *b)
1014bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
1013{
1014 BN_CTX *ctx;
1015
1016 /* Create copies of the scales, since r might be equal to a or b */
1017 u_int ascale = a->scale;
1018 u_int bscale = b->scale;
1019 u_int rscale = ascale + bscale;
1020
1021 ctx = BN_CTX_new();
1022 bn_checkp(ctx);
1023 bn_check(BN_mul(r->number, a->number, b->number, ctx));
1024 BN_CTX_free(ctx);
1025
1015{
1016 BN_CTX *ctx;
1017
1018 /* Create copies of the scales, since r might be equal to a or b */
1019 u_int ascale = a->scale;
1020 u_int bscale = b->scale;
1021 u_int rscale = ascale + bscale;
1022
1023 ctx = BN_CTX_new();
1024 bn_checkp(ctx);
1025 bn_check(BN_mul(r->number, a->number, b->number, ctx));
1026 BN_CTX_free(ctx);
1027
1026 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) {
1027 r->scale = rscale;
1028 normalize(r, max(bmachine.scale, max(ascale, bscale)));
1029 } else
1030 r->scale = rscale;
1028 r->scale = rscale;
1029 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1030 normalize(r, max(scale, max(ascale, bscale)));
1031}
1032
1033static void
1034bmul(void)
1035{
1036 struct number *a, *b, *r;
1037
1038 a = pop_number();
1039 if (a == NULL) {
1040 return;
1041 }
1042 b = pop_number();
1043 if (b == NULL) {
1044 push_number(a);
1045 return;
1046 }
1047
1048 r = new_number();
1031}
1032
1033static void
1034bmul(void)
1035{
1036 struct number *a, *b, *r;
1037
1038 a = pop_number();
1039 if (a == NULL) {
1040 return;
1041 }
1042 b = pop_number();
1043 if (b == NULL) {
1044 push_number(a);
1045 return;
1046 }
1047
1048 r = new_number();
1049 bmul_number(r, a, b);
1049 bmul_number(r, a, b, bmachine.scale);
1050
1051 push_number(r);
1052 free_number(a);
1053 free_number(b);
1054}
1055
1056static void
1057bdiv(void)

--- 109 unchanged lines hidden (view full) ---

1167 free_number(a);
1168 free_number(b);
1169}
1170
1171static void
1172bexp(void)
1173{
1174 struct number *a, *p, *r;
1050
1051 push_number(r);
1052 free_number(a);
1053 free_number(b);
1054}
1055
1056static void
1057bdiv(void)

--- 109 unchanged lines hidden (view full) ---

1167 free_number(a);
1168 free_number(b);
1169}
1170
1171static void
1172bexp(void)
1173{
1174 struct number *a, *p, *r;
1175 u_int scale;
1175 u_int rscale;
1176 bool neg;
1177
1178 p = pop_number();
1179 if (p == NULL) {
1180 return;
1181 }
1182 a = pop_number();
1183 if (a == NULL) {
1184 push_number(p);
1185 return;
1186 }
1187
1176 bool neg;
1177
1178 p = pop_number();
1179 if (p == NULL) {
1180 return;
1181 }
1182 a = pop_number();
1183 if (a == NULL) {
1184 push_number(p);
1185 return;
1186 }
1187
1188 if (p->scale != 0)
1189 warnx("Runtime warning: non-zero scale in exponent");
1188 if (p->scale != 0) {
1189 BIGNUM *i, *f;
1190 i = BN_new();
1191 bn_checkp(i);
1192 f = BN_new();
1193 bn_checkp(f);
1194 split_number(p, i, f);
1195 if (!BN_is_zero(f))
1196 warnx("Runtime warning: non-zero fractional part "
1197 "in exponent");
1198 BN_free(i);
1199 BN_free(f);
1200 }
1201
1190 normalize(p, 0);
1191
1192 neg = false;
1202 normalize(p, 0);
1203
1204 neg = false;
1193 if (BN_cmp(p->number, &zero) < 0) {
1205 if (BN_is_negative(p->number)) {
1194 neg = true;
1195 negate(p);
1206 neg = true;
1207 negate(p);
1196 scale = bmachine.scale;
1208 rscale = bmachine.scale;
1197 } else {
1198 /* Posix bc says min(a.scale * b, max(a.scale, scale) */
1199 u_long b;
1200 u_int m;
1201
1202 b = BN_get_word(p->number);
1203 m = max(a->scale, bmachine.scale);
1209 } else {
1210 /* Posix bc says min(a.scale * b, max(a.scale, scale) */
1211 u_long b;
1212 u_int m;
1213
1214 b = BN_get_word(p->number);
1215 m = max(a->scale, bmachine.scale);
1204 scale = a->scale * (u_int)b;
1205 if (scale > m || (a->scale > 0 && (b == BN_MASK2 ||
1216 rscale = a->scale * (u_int)b;
1217 if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1206 b > UINT_MAX)))
1218 b > UINT_MAX)))
1207 scale = m;
1219 rscale = m;
1208 }
1209
1210 if (BN_is_zero(p->number)) {
1211 r = new_number();
1212 bn_check(BN_one(r->number));
1220 }
1221
1222 if (BN_is_zero(p->number)) {
1223 r = new_number();
1224 bn_check(BN_one(r->number));
1213 normalize(r, scale);
1225 normalize(r, rscale);
1214 } else {
1226 } else {
1227 u_int ascale, mscale;
1228
1229 ascale = a->scale;
1215 while (!BN_is_bit_set(p->number, 0)) {
1230 while (!BN_is_bit_set(p->number, 0)) {
1216 bmul_number(a, a, a);
1231 ascale *= 2;
1232 bmul_number(a, a, a, ascale);
1217 bn_check(BN_rshift1(p->number, p->number));
1218 }
1219
1220 r = dup_number(a);
1233 bn_check(BN_rshift1(p->number, p->number));
1234 }
1235
1236 r = dup_number(a);
1221 normalize(r, scale);
1222 bn_check(BN_rshift1(p->number, p->number));
1223
1237 bn_check(BN_rshift1(p->number, p->number));
1238
1239 mscale = ascale;
1224 while (!BN_is_zero(p->number)) {
1240 while (!BN_is_zero(p->number)) {
1225 bmul_number(a, a, a);
1226 if (BN_is_bit_set(p->number, 0))
1227 bmul_number(r, r, a);
1241 ascale *= 2;
1242 bmul_number(a, a, a, ascale);
1243 if (BN_is_bit_set(p->number, 0)) {
1244 mscale += ascale;
1245 bmul_number(r, r, a, mscale);
1246 }
1228 bn_check(BN_rshift1(p->number, p->number));
1229 }
1230
1231 if (neg) {
1232 BN_CTX *ctx;
1233 BIGNUM *one;
1234
1235 one = BN_new();
1236 bn_checkp(one);
1237 bn_check(BN_one(one));
1238 ctx = BN_CTX_new();
1239 bn_checkp(ctx);
1247 bn_check(BN_rshift1(p->number, p->number));
1248 }
1249
1250 if (neg) {
1251 BN_CTX *ctx;
1252 BIGNUM *one;
1253
1254 one = BN_new();
1255 bn_checkp(one);
1256 bn_check(BN_one(one));
1257 ctx = BN_CTX_new();
1258 bn_checkp(ctx);
1240 scale_number(one, r->scale + scale);
1241 normalize(r, scale);
1242 bn_check(BN_div(r->number, NULL, one, r->number, ctx));
1259 scale_number(one, r->scale + rscale);
1260
1261 if (BN_is_zero(r->number))
1262 warnx("divide by zero");
1263 else
1264 bn_check(BN_div(r->number, NULL, one,
1265 r->number, ctx));
1243 BN_free(one);
1244 BN_CTX_free(ctx);
1266 BN_free(one);
1267 BN_CTX_free(ctx);
1268 r->scale = rscale;
1245 } else
1269 } else
1246 normalize(r, scale);
1270 normalize(r, rscale);
1247 }
1248 push_number(r);
1249 free_number(a);
1250 free_number(p);
1251}
1252
1253static bool
1254bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)

--- 22 unchanged lines hidden (view full) ---

1277 onecount = 0;
1278 n = pop_number();
1279 if (n == NULL) {
1280 return;
1281 }
1282 if (BN_is_zero(n->number)) {
1283 r = new_number();
1284 push_number(r);
1271 }
1272 push_number(r);
1273 free_number(a);
1274 free_number(p);
1275}
1276
1277static bool
1278bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)

--- 22 unchanged lines hidden (view full) ---

1301 onecount = 0;
1302 n = pop_number();
1303 if (n == NULL) {
1304 return;
1305 }
1306 if (BN_is_zero(n->number)) {
1307 r = new_number();
1308 push_number(r);
1285 } else if (BN_cmp(n->number, &zero) < 0)
1309 } else if (BN_is_negative(n->number))
1286 warnx("square root of negative number");
1287 else {
1288 scale = max(bmachine.scale, n->scale);
1289 normalize(n, 2*scale);
1290 x = BN_dup(n->number);
1291 bn_checkp(x);
1292 bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1293 y = BN_new();

--- 460 unchanged lines hidden ---
1310 warnx("square root of negative number");
1311 else {
1312 scale = max(bmachine.scale, n->scale);
1313 normalize(n, 2*scale);
1314 x = BN_dup(n->number);
1315 bn_checkp(x);
1316 bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1317 y = BN_new();

--- 460 unchanged lines hidden ---