aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-10-12 16:23:05 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-10-12 16:23:05 +0200
commit182e2d45678d0487be71370c37b88daca3d2c54b (patch)
tree3987ecd9bade082a7b41901c2376daa73401e548 /src
parentda8fdd4955fd24666643915a6728678e9965a0d3 (diff)
downloadnissy-core-182e2d45678d0487be71370c37b88daca3d2c54b.tar.gz
nissy-core-182e2d45678d0487be71370c37b88daca3d2c54b.zip
Make gendata and co safer by checking buffer size
Diffstat (limited to 'src')
-rw-r--r--src/nissy.c21
-rw-r--r--src/solvers/h48/gendata_cocsep.h11
-rw-r--r--src/solvers/h48/gendata_h48.h120
-rw-r--r--src/solvers/h48/gendata_types_macros.h1
-rw-r--r--src/solvers/h48/solve.h9
-rw-r--r--src/solvers/h48/solve_multithread.h12
-rw-r--r--src/solvers/tables.h84
-rw-r--r--src/solvers/tables_types_macros.h12
8 files changed, 156 insertions, 114 deletions
diff --git a/src/nissy.c b/src/nissy.c
index d725599..d3ff58a 100644
--- a/src/nissy.c
+++ b/src/nissy.c
@@ -394,8 +394,11 @@ nissy_datainfo(
394{ 394{
395 uint8_t i; 395 uint8_t i;
396 tableinfo_t info; 396 tableinfo_t info;
397 int64_t ret;
397 398
398 readtableinfo(data, &info); 399 ret = readtableinfo(data_size, data, &info);
400 if (ret != 0)
401 return ret;
399 402
400 write("\n---------\n\n"); 403 write("\n---------\n\n");
401 write("Table information for '%s'\n", info.solver); 404 write("Table information for '%s'\n", info.solver);
@@ -446,13 +449,14 @@ nissy_gendata(
446 return NISSY_ERROR_NULL_POINTER; 449 return NISSY_ERROR_NULL_POINTER;
447 } 450 }
448 451
452 arg.buf_size = data_size;
449 arg.buf = data; 453 arg.buf = data;
450 if (!strncmp(solver, "h48", 3)) { 454 if (!strncmp(solver, "h48", 3)) {
451 p = parse_h48_solver(solver, &arg.h, &arg.k); 455 p = parse_h48_solver(solver, &arg.h, &arg.k);
452 arg.maxdepth = 20; 456 arg.maxdepth = 20;
453 if (p != 0) 457 if (p != 0)
454 return NISSY_ERROR_UNKNOWN; 458 return NISSY_ERROR_UNKNOWN;
455 return (int64_t)gendata_h48(&arg); 459 return gendata_h48(&arg);
456 } else { 460 } else {
457 LOG("gendata: unknown solver %s\n", solver); 461 LOG("gendata: unknown solver %s\n", solver);
458 return NISSY_ERROR_INVALID_SOLVER; 462 return NISSY_ERROR_INVALID_SOLVER;
@@ -468,7 +472,10 @@ nissy_checkdata(
468 char *buf; 472 char *buf;
469 tableinfo_t info; 473 tableinfo_t info;
470 474
471 for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) { 475 for (buf = (char *)data;
476 readtableinfo(data_size, buf, &info);
477 buf += info.next, data_size -= info.next)
478 {
472 if (!checkdata(buf, &info)) { 479 if (!checkdata(buf, &info)) {
473 LOG("Error: data for %s is inconsistent with info!\n", 480 LOG("Error: data for %s is inconsistent with info!\n",
474 info.solver); 481 info.solver);
@@ -547,10 +554,10 @@ nissy_solve(
547 return NISSY_ERROR_INVALID_SOLVER; 554 return NISSY_ERROR_INVALID_SOLVER;
548 } else { 555 } else {
549 return THREADS > 1 ? 556 return THREADS > 1 ?
550 solve_h48_multithread(c, minmoves, 557 solve_h48_multithread(c, minmoves, maxmoves,
551 maxmoves, maxsols, data, sols) : 558 maxsols, data_size, data, sols_size, sols) :
552 solve_h48(c, minmoves, 559 solve_h48(c, minmoves, maxmoves, maxsols,
553 maxmoves, maxsols, data, sols); 560 data_size, data, sols_size, sols);
554 } 561 }
555 } else if (!strcmp(solver, "simple")) { 562 } else if (!strcmp(solver, "simple")) {
556 return solve_simple( 563 return solve_simple(
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h
index 18bfc38..b46bcf3 100644
--- a/src/solvers/h48/gendata_cocsep.h
+++ b/src/solvers/h48/gendata_cocsep.h
@@ -1,7 +1,8 @@
1STATIC_INLINE bool get_visited(const uint8_t *, int64_t); 1STATIC_INLINE bool get_visited(const uint8_t *, int64_t);
2STATIC_INLINE void set_visited(uint8_t *, int64_t); 2STATIC_INLINE void set_visited(uint8_t *, int64_t);
3 3
4STATIC size_t gendata_cocsep(void *, uint64_t *, cube_t *); 4STATIC size_t gendata_cocsep(
5 char [static COCSEP_FULLSIZE+INFOSIZE], uint64_t *, cube_t *);
5STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *); 6STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *);
6STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]); 7STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]);
7 8
@@ -19,7 +20,11 @@ After the data as described above, more auxiliary information is appended:
19 of positions having that pruning value. 20 of positions having that pruning value.
20*/ 21*/
21STATIC size_t 22STATIC size_t
22gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep) 23gendata_cocsep(
24 char buf[static COCSEP_FULLSIZE+INFOSIZE],
25 uint64_t *selfsim,
26 cube_t *rep
27)
23{ 28{
24 uint32_t *buf32, cc; 29 uint32_t *buf32, cc;
25 uint16_t n; 30 uint16_t n;
@@ -64,7 +69,7 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep)
64 info.distribution[i] = cc; 69 info.distribution[i] = cc;
65 } 70 }
66 71
67 writetableinfo(&info, buf); 72 writetableinfo(&info, COCSEP_FULLSIZE+INFOSIZE, buf);
68 73
69 DBG_ASSERT(n == COCSEP_CLASSES, 0, 74 DBG_ASSERT(n == COCSEP_CLASSES, 0,
70 "cocsep: computed %" PRIu16 " symmetry classes, " 75 "cocsep: computed %" PRIu16 " symmetry classes, "
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 50ab01c..2a4469f 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -1,14 +1,16 @@
1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *); 1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *);
2STATIC size_t gendata_h48(gendata_h48_arg_t *); 2STATIC int64_t gendata_h48(gendata_h48_arg_t *);
3STATIC size_t gendata_h48h0k4(gendata_h48_arg_t *); 3STATIC void gendata_h48h0k4(gendata_h48_arg_t *);
4STATIC size_t gendata_h48k2(gendata_h48_arg_t *); 4STATIC void gendata_h48k2(gendata_h48_arg_t *);
5STATIC void gendata_h48k2_realcoord(gendata_h48_arg_t *);
6
5STATIC void * gendata_h48h0k4_runthread(void *); 7STATIC void * gendata_h48h0k4_runthread(void *);
8STATIC void * gendata_h48k2_runthread(void *);
9
6STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t *); 10STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t *);
7STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *); 11STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *);
8STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *); 12STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *);
9STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *);
10STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); 13STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
11STATIC void * gendata_h48k2_runthread(void *);
12STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); 14STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *);
13STATIC void getdistribution_h48(const uint8_t *, 15STATIC void getdistribution_h48(const uint8_t *,
14 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); 16 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t);
@@ -62,75 +64,77 @@ gendata_h48short(gendata_h48short_arg_t *arg)
62} 64}
63 65
64/* Generic function that dispatches to the data generators */ 66/* Generic function that dispatches to the data generators */
65STATIC size_t 67STATIC int64_t
66gendata_h48(gendata_h48_arg_t *arg) 68gendata_h48(gendata_h48_arg_t *arg)
67{ 69{
70 uint64_t size;
68 void *cocsepdata_offset; 71 void *cocsepdata_offset;
69 size_t cocsepsize, h48size; 72 size_t cocsepsize;
70 tableinfo_t cocsepinfo; 73 tableinfo_t cocsepinfo;
71 74
72 cocsepsize = gendata_cocsep(arg->buf, arg->selfsim, arg->crep); 75 if (arg == NULL) {
76 LOG("Error computing H48 data: arg is NULL.\n");
77 return NISSY_ERROR_UNKNOWN;
78 }
73 79
74 if (arg->buf == NULL) { 80 size = 2*INFOSIZE + COCSEP_FULLSIZE + H48_TABLESIZE(arg->h, arg->k);
75 cocsepdata_offset = NULL; 81
76 arg->cocsepdata = NULL; 82 if (arg->buf == NULL)
77 arg->h48buf = NULL; 83 return size; /* Dry-run */
78 } else { 84
79 cocsepdata_offset = (char *)arg->buf + INFOSIZE; 85 if (arg->buf_size < size) {
80 arg->cocsepdata = (uint32_t *)cocsepdata_offset; 86 LOG("Error computing H48 data: buffer is too small "
81 arg->h48buf = (char *)arg->buf + cocsepsize; 87 "(needed %" PRId64 " bytes but received %" PRId64 ")\n",
88 size, arg->buf_size);
89 return NISSY_ERROR_BUFFER_SIZE;
82 } 90 }
83 91
84 arg->base = 99; // TODO: set this somewhere else 92 cocsepsize = gendata_cocsep(arg->buf, arg->selfsim, arg->crep);
93
94 cocsepdata_offset = (char *)arg->buf + INFOSIZE;
95 arg->cocsepdata = (uint32_t *)cocsepdata_offset;
96 arg->h48buf = (char *)arg->buf + cocsepsize;
97
98 arg->base = 99; /* TODO: set this somewhere else */
85 99
86 if (arg->h == 0 && arg->k == 4) { 100 if (arg->h == 0 && arg->k == 4) {
87 h48size = gendata_h48h0k4(arg); 101 gendata_h48h0k4(arg);
88 } else if ((arg->h == 0 || arg->h == 11) && arg->k == 2) { 102 } else if ((arg->h == 0 || arg->h == 11) && arg->k == 2) {
89 h48size = gendata_h48k2_realcoord(arg); 103 gendata_h48k2_realcoord(arg);
90 } else if (arg->k == 2) { 104 } else if (arg->k == 2) {
91 h48size = gendata_h48k2(arg); 105 gendata_h48k2(arg);
92 } else { 106 } else {
93 LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8 107 LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8
94 " (not implemented yet)\n", arg->h, arg->k); 108 " (not implemented yet)\n", arg->h, arg->k);
95 goto gendata_h48_error; 109 return NISSY_ERROR_INVALID_SOLVER;
96 } 110 }
97 111
98 if (arg->buf == NULL) 112 if (readtableinfo(arg->buf_size, arg->buf, &cocsepinfo) != NISSY_OK) {
99 goto gendata_h48_return_size;
100
101 if (!readtableinfo(arg->buf, &cocsepinfo)) {
102 LOG("gendata_h48: could not read info for cocsep table\n"); 113 LOG("gendata_h48: could not read info for cocsep table\n");
103 goto gendata_h48_error; 114 return NISSY_ERROR_UNKNOWN;
104 } 115 }
105 116
106 cocsepinfo.next = cocsepsize; 117 cocsepinfo.next = cocsepsize;
107 if (!writetableinfo(&cocsepinfo, arg->buf)) { 118 if (writetableinfo(&cocsepinfo, arg->buf_size, arg->buf) != NISSY_OK) {
108 LOG("gendata_h48: could not write info for cocsep table" 119 LOG("gendata_h48: could not write info for cocsep table"
109 " with updated 'next' value\n"); 120 " with updated 'next' value\n");
110 goto gendata_h48_error; 121 return NISSY_ERROR_UNKNOWN;
111 } 122 }
112 123
113gendata_h48_return_size: 124 return size;
114 return cocsepsize + h48size;
115
116gendata_h48_error:
117 return 0;
118} 125}
119 126
120STATIC size_t 127STATIC void
121gendata_h48h0k4(gendata_h48_arg_t *arg) 128gendata_h48h0k4(gendata_h48_arg_t *arg)
122{ 129{
123 _Atomic uint8_t *table; 130 _Atomic uint8_t *table;
124 uint8_t val; 131 uint8_t val;
125 int64_t i, sc, done, d, h48max; 132 int64_t i, sc, done, d, h48max;
126 uint64_t t, tt, isize, cc; 133 uint64_t t, tt, isize, cc, bufsize;
127 h48h0k4_bfs_arg_t bfsarg[THREADS]; 134 h48h0k4_bfs_arg_t bfsarg[THREADS];
128 pthread_t thread[THREADS]; 135 pthread_t thread[THREADS];
129 pthread_mutex_t table_mutex[CHUNKS]; 136 pthread_mutex_t table_mutex[CHUNKS];
130 137
131 if (arg->buf == NULL)
132 goto gendata_h48h0k4_return_size;
133
134 arg->info = (tableinfo_t) { 138 arg->info = (tableinfo_t) {
135 .solver = "h48 solver h = 0, k = 4", 139 .solver = "h48 solver h = 0, k = 4",
136 .type = TABLETYPE_PRUNING, 140 .type = TABLETYPE_PRUNING,
@@ -194,10 +198,8 @@ gendata_h48h0k4(gendata_h48_arg_t *arg)
194 } 198 }
195 199
196 arg->info.maxvalue = d - 1; 200 arg->info.maxvalue = d - 1;
197 writetableinfo(&arg->info, arg->h48buf); 201 bufsize = arg->buf_size - COCSEP_FULLSIZE - INFOSIZE;
198 202 writetableinfo(&arg->info, bufsize, arg->h48buf);
199gendata_h48h0k4_return_size:
200 return H48_TABLESIZE(0, 4) + INFOSIZE;
201} 203}
202 204
203STATIC void * 205STATIC void *
@@ -258,7 +260,7 @@ gendata_h48h0k4_runthread(void *arg)
258 return NULL; 260 return NULL;
259} 261}
260 262
261STATIC size_t 263STATIC void
262gendata_h48k2(gendata_h48_arg_t *arg) 264gendata_h48k2(gendata_h48_arg_t *arg)
263{ 265{
264 static const uint8_t shortdepth = 8; 266 static const uint8_t shortdepth = 8;
@@ -313,19 +315,15 @@ gendata_h48k2(gendata_h48_arg_t *arg)
313 uint8_t t; 315 uint8_t t;
314 uint8_t *table; 316 uint8_t *table;
315 int64_t j; 317 int64_t j;
316 uint64_t i, ii, inext, count; 318 uint64_t i, ii, inext, count, bufsize;
317 h48map_t shortcubes; 319 h48map_t shortcubes;
318 gendata_h48short_arg_t shortarg; 320 gendata_h48short_arg_t shortarg;
319 h48k2_dfs_arg_t dfsarg[THREADS]; 321 h48k2_dfs_arg_t dfsarg[THREADS];
320 pthread_t thread[THREADS]; 322 pthread_t thread[THREADS];
321 pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS]; 323 pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS];
322 324
323 if (arg->buf == NULL)
324 goto gendata_h48k2_return_size;
325
326 table = (uint8_t *)arg->h48buf + INFOSIZE; 325 table = (uint8_t *)arg->h48buf + INFOSIZE;
327 if (arg->buf != NULL) 326 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
328 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
329 327
330 LOG("Computing depth <=%" PRIu8 "\n", shortdepth) 328 LOG("Computing depth <=%" PRIu8 "\n", shortdepth)
331 h48map_create(&shortcubes, capacity, randomizer); 329 h48map_create(&shortcubes, capacity, randomizer);
@@ -379,10 +377,8 @@ gendata_h48k2(gendata_h48_arg_t *arg)
379 arg->info.distribution[t]++; 377 arg->info.distribution[t]++;
380 } 378 }
381 379
382 writetableinfo(&arg->info, arg->h48buf); 380 bufsize = arg->buf_size - COCSEP_FULLSIZE - INFOSIZE;
383 381 writetableinfo(&arg->info, bufsize, arg->h48buf);
384gendata_h48k2_return_size:
385 return H48_TABLESIZE(arg->h, 2) + INFOSIZE;
386} 382}
387 383
388STATIC void * 384STATIC void *
@@ -565,11 +561,11 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
565 } 561 }
566} 562}
567 563
568STATIC size_t 564STATIC void
569gendata_h48k2_realcoord(gendata_h48_arg_t *arg) 565gendata_h48k2_realcoord(gendata_h48_arg_t *arg)
570{ 566{
571 /* TODO */ 567 /* TODO */
572 return gendata_h48k2(arg); 568 gendata_h48k2(arg);
573} 569}
574 570
575STATIC void * 571STATIC void *
@@ -684,6 +680,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
684 const uint8_t *h48full; 680 const uint8_t *h48full;
685 uint8_t *h48derive; 681 uint8_t *h48derive;
686 int64_t i, j, h48max; 682 int64_t i, j, h48max;
683 uint64_t bufsize;
687 gendata_h48_arg_t arg; 684 gendata_h48_arg_t arg;
688 tableinfo_t cocsepinfo, fulltableinfo; 685 tableinfo_t cocsepinfo, fulltableinfo;
689 686
@@ -693,7 +690,9 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
693 fulltableinfo.bits = 2; 690 fulltableinfo.bits = 2;
694 fulltableinfo.base = 8; 691 fulltableinfo.base = 8;
695 692
696 readtableinfo_n(fulltable, 2, &fulltableinfo); 693 int64_t TODOlarge = 999999999999; /* TODO: cleanup here */
694
695 readtableinfo_n(TODOlarge, fulltable, 2, &fulltableinfo);
697 arg.h = h; 696 arg.h = h;
698 arg.k = fulltableinfo.bits; 697 arg.k = fulltableinfo.bits;
699 arg.maxdepth = 20; 698 arg.maxdepth = 20;
@@ -711,13 +710,15 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
711 if (buf == NULL) 710 if (buf == NULL)
712 goto gendata_h48_derive_return_size; 711 goto gendata_h48_derive_return_size;
713 712
714 if (!readtableinfo(buf, &cocsepinfo)) { 713 bufsize = COCSEP_FULLSIZE + INFOSIZE;
714 if (readtableinfo(bufsize, buf, &cocsepinfo) != NISSY_OK) {
715 LOG("gendata_h48: could not read info for cocsep table\n"); 715 LOG("gendata_h48: could not read info for cocsep table\n");
716 goto gendata_h48_derive_error; 716 goto gendata_h48_derive_error;
717 } 717 }
718 718
719 cocsepinfo.next = cocsepsize; 719 cocsepinfo.next = cocsepsize;
720 if (!writetableinfo(&cocsepinfo, buf)) { 720 bufsize = COCSEP_FULLSIZE + INFOSIZE;
721 if (writetableinfo(&cocsepinfo, bufsize, buf) != NISSY_OK) {
721 LOG("gendata_h48_derive: could not write info for cocsep table" 722 LOG("gendata_h48_derive: could not write info for cocsep table"
722 " with updated 'next' value\n"); 723 " with updated 'next' value\n");
723 goto gendata_h48_derive_error; 724 goto gendata_h48_derive_error;
@@ -742,7 +743,8 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
742 743
743 getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); 744 getdistribution_h48(h48derive, arg.info.distribution, h, arg.k);
744 745
745 if (!writetableinfo(&arg.info, arg.h48buf)) { 746 bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE;
747 if (writetableinfo(&arg.info, bufsize, arg.h48buf) != NISSY_OK) {
746 LOG("gendata_h48_derive: could not write info for table\n"); 748 LOG("gendata_h48_derive: could not write info for table\n");
747 goto gendata_h48_derive_error; 749 goto gendata_h48_derive_error;
748 } 750 }
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h
index e0e4df7..73a46ff 100644
--- a/src/solvers/h48/gendata_types_macros.h
+++ b/src/solvers/h48/gendata_types_macros.h
@@ -58,6 +58,7 @@ typedef struct {
58 uint8_t base; 58 uint8_t base;
59 uint8_t maxdepth; 59 uint8_t maxdepth;
60 tableinfo_t info; 60 tableinfo_t info;
61 uint64_t buf_size;
61 void *buf; 62 void *buf;
62 void *h48buf; 63 void *h48buf;
63 uint32_t *cocsepdata; 64 uint32_t *cocsepdata;
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 3948b15..f2babdf 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -21,7 +21,8 @@ STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t);
21STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); 21STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *);
22STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); 22STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *);
23STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); 23STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *);
24STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); 24STATIC int64_t solve_h48(cube_t, int8_t, int8_t,
25 int8_t, uint64_t, const void *, uint64_t, char *);
25 26
26STATIC uint32_t 27STATIC uint32_t
27allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) 28allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch)
@@ -163,7 +164,9 @@ solve_h48(
163 int8_t minmoves, 164 int8_t minmoves,
164 int8_t maxmoves, 165 int8_t maxmoves,
165 int8_t maxsolutions, 166 int8_t maxsolutions,
167 uint64_t data_size,
166 const void *data, 168 const void *data,
169 uint64_t solutions_size,
167 char *solutions 170 char *solutions
168) 171)
169{ 172{
@@ -171,9 +174,9 @@ solve_h48(
171 dfsarg_solveh48_t arg; 174 dfsarg_solveh48_t arg;
172 tableinfo_t info; 175 tableinfo_t info;
173 176
174 if(!readtableinfo_n(data, 2, &info)) { 177 if(readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) {
175 LOG("solve_h48: error reading table\n"); 178 LOG("solve_h48: error reading table\n");
176 return 0; 179 return NISSY_ERROR_DATA;
177 } 180 }
178 181
179 arg = (dfsarg_solveh48_t) { 182 arg = (dfsarg_solveh48_t) {
diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h
index 766d84a..3ba914a 100644
--- a/src/solvers/h48/solve_multithread.h
+++ b/src/solvers/h48/solve_multithread.h
@@ -20,7 +20,8 @@ STATIC void copy_queue(task_queue_t *, task_queue_t *, int, _Atomic int64_t *);
20STATIC void *start_thread(void *); 20STATIC void *start_thread(void *);
21STATIC int64_t solve_h48_bfs(dfsarg_solveh48_t *, task_queue_t *, int8_t); 21STATIC int64_t solve_h48_bfs(dfsarg_solveh48_t *, task_queue_t *, int8_t);
22STATIC int64_t solve_h48_single(dfsarg_solveh48_t *, task_queue_t *); 22STATIC int64_t solve_h48_single(dfsarg_solveh48_t *, task_queue_t *);
23STATIC int64_t solve_h48_multithread(cube_t, int8_t, int8_t, int8_t, const void *, char *); 23STATIC int64_t solve_h48_multithread(cube_t, int8_t, int8_t, int8_t,
24 uint64_t, const void *, uint64_t, char *);
24 25
25STATIC void 26STATIC void
26solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) 27solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq)
@@ -236,8 +237,11 @@ solve_h48_multithread(
236 int8_t minmoves, 237 int8_t minmoves,
237 int8_t maxmoves, 238 int8_t maxmoves,
238 int8_t maxsolutions, 239 int8_t maxsolutions,
240 uint64_t data_size,
239 const void *data, 241 const void *data,
240 char *solutions) 242 uint64_t solutions_size,
243 char *solutions
244)
241{ 245{
242 _Atomic int64_t nsols = 0; 246 _Atomic int64_t nsols = 0;
243 int p_depth = 0; 247 int p_depth = 0;
@@ -245,9 +249,9 @@ solve_h48_multithread(
245 tableinfo_t info; 249 tableinfo_t info;
246 pthread_t threads[THREADS]; 250 pthread_t threads[THREADS];
247 251
248 if (!readtableinfo_n(data, 2, &info)){ 252 if (readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) {
249 LOG("solve_h48: error reading table\n"); 253 LOG("solve_h48: error reading table\n");
250 return 0; 254 return NISSY_ERROR_DATA;
251 } 255 }
252 256
253 arg = (dfsarg_solveh48_t){ 257 arg = (dfsarg_solveh48_t){
diff --git a/src/solvers/tables.h b/src/solvers/tables.h
index d73fa31..060b018 100644
--- a/src/solvers/tables.h
+++ b/src/solvers/tables.h
@@ -1,14 +1,14 @@
1/* Type definitions and macros are in a separate file for easier testing */ 1/* Type definitions and macros are in a separate file for easier testing */
2#include "tables_types_macros.h" 2#include "tables_types_macros.h"
3 3
4STATIC uint64_t read_unaligned_u64(const void *); 4STATIC uint64_t read_unaligned_u64(const char *);
5STATIC void write_unaligned_u64(void *, uint64_t); 5STATIC void write_unaligned_u64(char *, uint64_t);
6STATIC bool readtableinfo(const void *, tableinfo_t *); 6STATIC int64_t readtableinfo(uint64_t, const char *, tableinfo_t *);
7STATIC bool readtableinfo_n(const void *, uint8_t, tableinfo_t *); 7STATIC int64_t readtableinfo_n(uint64_t, const char *, uint8_t, tableinfo_t *);
8STATIC bool writetableinfo(const tableinfo_t *, void *); 8STATIC int64_t writetableinfo(const tableinfo_t *, uint64_t, char *);
9 9
10STATIC uint64_t 10STATIC uint64_t
11read_unaligned_u64(const void *buf) 11read_unaligned_u64(const char *buf)
12{ 12{
13 uint64_t ret; 13 uint64_t ret;
14 14
@@ -18,24 +18,30 @@ read_unaligned_u64(const void *buf)
18} 18}
19 19
20STATIC void 20STATIC void
21write_unaligned_u64(void *buf, uint64_t x) 21write_unaligned_u64(char *buf, uint64_t x)
22{ 22{
23 memcpy(buf, &x, sizeof(uint64_t)); 23 memcpy(buf, &x, sizeof(uint64_t));
24} 24}
25 25
26STATIC bool 26STATIC int64_t
27readtableinfo(const void *buf, tableinfo_t *info) 27readtableinfo(uint64_t buf_size, const char *buf, tableinfo_t *info)
28{ 28{
29 size_t i; 29 size_t i;
30 30
31 if (buf == NULL) { 31 if (buf == NULL) {
32 LOG("Error reading table: buffer is NULL\n"); 32 LOG("Error reading table: buffer is NULL\n");
33 return false; 33 return NISSY_ERROR_NULL_POINTER;
34 }
35
36 if (buf_size < INFOSIZE) {
37 LOG("Error reading table: buffer size is too small "
38 "(smaller than INFOSIZE = %" PRId64 ")\n", INFOSIZE);
39 return NISSY_ERROR_BUFFER_SIZE;
34 } 40 }
35 41
36 if (info == NULL) { 42 if (info == NULL) {
37 LOG("Error reading table info: info struct is NULL\n"); 43 LOG("Error reading table info: info struct is NULL\n");
38 return false; 44 return NISSY_ERROR_UNKNOWN;
39 } 45 }
40 46
41 for (i = 0; i < INFO_DISTRIBUTION_LEN; i++) 47 for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
@@ -53,39 +59,53 @@ readtableinfo(const void *buf, tableinfo_t *info)
53 memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER), 59 memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER),
54 INFO_SOLVER_STRLEN); 60 INFO_SOLVER_STRLEN);
55 61
56 info->h48h = *OFFSET(buf, INFO_OFFSET_H48H); 62 info->h48h = *(uint8_t *)OFFSET(buf, INFO_OFFSET_H48H);
57 info->bits = *OFFSET(buf, INFO_OFFSET_BITS); 63 info->bits = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BITS);
58 info->base = *OFFSET(buf, INFO_OFFSET_BASE); 64 info->base = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BASE);
59 info->maxvalue = *OFFSET(buf, INFO_OFFSET_MAXVALUE); 65 info->maxvalue = *(uint8_t *)OFFSET(buf, INFO_OFFSET_MAXVALUE);
60 66
61 return true; 67 return NISSY_OK;
62} 68}
63 69
64STATIC bool 70STATIC int64_t
65readtableinfo_n(const void *buf, uint8_t n, tableinfo_t *info) 71readtableinfo_n(
72 uint64_t buf_size,
73 const char *buf,
74 uint8_t n,
75 tableinfo_t *info
76)
66{ 77{
67 for ( ; n > 0; n--, buf = (char *)buf + info->next) 78 int64_t ret;
68 if (!readtableinfo(buf, info)) 79
69 return false; 80 for (; n > 0; n--, buf = buf + info->next, buf_size -= info->next)
81 if ((ret = readtableinfo(buf_size, buf, info)) != 0)
82 return ret;
70 83
71 return true; 84 return NISSY_OK;
72} 85}
73 86
74STATIC bool 87STATIC int64_t
75writetableinfo(const tableinfo_t *info, void *buf) 88writetableinfo(const tableinfo_t *info, uint64_t data_size, char *buf)
76{ 89{
77 size_t i; 90 size_t i;
78 bool end; 91 bool end;
79 uint8_t *c; 92 char *c;
80 93
81 if (buf == NULL) { 94 if (buf == NULL) {
82 LOG("Error writing table: buffer is NULL\n"); 95 LOG("Error writing table: buffer is NULL\n");
83 return false; 96 return NISSY_ERROR_NULL_POINTER;
84 } 97 }
85 98
86 if (info == NULL) { 99 if (info == NULL) {
87 LOG("Error writing table info: provided info is NULL\n"); 100 LOG("Error writing table info: provided info is NULL\n");
88 return false; 101 return NISSY_ERROR_UNKNOWN;
102 }
103
104 if (data_size < info->fullsize) {
105 LOG("Error writing table: buffer size is too small "
106 "(given %" PRId64 " but table requires %" PRId64 ")\n",
107 data_size, info->fullsize);
108 return NISSY_ERROR_BUFFER_SIZE;
89 } 109 }
90 110
91 for (i = 0; i < INFO_DISTRIBUTION_LEN; i++) 111 for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
@@ -112,10 +132,10 @@ writetableinfo(const tableinfo_t *info, void *buf)
112 *c = 0; 132 *c = 0;
113 } 133 }
114 134
115 *OFFSET(buf, INFO_OFFSET_H48H) = info->h48h; 135 *(uint8_t *)OFFSET(buf, INFO_OFFSET_H48H) = info->h48h;
116 *OFFSET(buf, INFO_OFFSET_BITS) = info->bits; 136 *(uint8_t *)OFFSET(buf, INFO_OFFSET_BITS) = info->bits;
117 *OFFSET(buf, INFO_OFFSET_BASE) = info->base; 137 *(uint8_t *)OFFSET(buf, INFO_OFFSET_BASE) = info->base;
118 *OFFSET(buf, INFO_OFFSET_MAXVALUE) = info->maxvalue; 138 *(uint8_t *)OFFSET(buf, INFO_OFFSET_MAXVALUE) = info->maxvalue;
119 139
120 return true; 140 return NISSY_OK;
121} 141}
diff --git a/src/solvers/tables_types_macros.h b/src/solvers/tables_types_macros.h
index 39b3986..465bed1 100644
--- a/src/solvers/tables_types_macros.h
+++ b/src/solvers/tables_types_macros.h
@@ -1,11 +1,11 @@
1#define OFFSET(B, K) (((uint8_t *)B) + K) 1#define OFFSET(B, K) (((char *)B) + K)
2 2
3#define INFOSIZE 512 3#define INFOSIZE INT64_C(512)
4#define INFO_SOLVER_STRLEN 100 4#define INFO_SOLVER_STRLEN INT64_C(100)
5#define INFO_DISTRIBUTION_LEN 21 5#define INFO_DISTRIBUTION_LEN INT64_C(21)
6 6
7#define TABLETYPE_PRUNING 0 7#define TABLETYPE_PRUNING UINT64_C(0)
8#define TABLETYPE_SPECIAL 1 8#define TABLETYPE_SPECIAL UINT64_C(1)
9 9
10#define INFO_OFFSET_DISTRIBUTION 0 10#define INFO_OFFSET_DISTRIBUTION 0
11#define INFO_OFFSET_TYPE (INFO_DISTRIBUTION_LEN * sizeof(uint64_t)) 11#define INFO_OFFSET_TYPE (INFO_DISTRIBUTION_LEN * sizeof(uint64_t))

Generated with cgit - Back to sebastiano.tronto.net