commit ef087c3849cfbe58f4f77e09367d6fbf152e5498
parent 37a48208d419a6c2797f5705ba37d7b362fcb8fe
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sat, 12 Oct 2024 17:06:50 +0200
Make writemoves (and solver) safer by checking buffer size
Diffstat:
7 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/src/core/io_moves.h b/src/core/io_moves.h
@@ -1,6 +1,6 @@
STATIC uint8_t readmove(char);
STATIC uint8_t readmodifier(char);
-STATIC int writemoves(uint8_t *, int, char *);
+STATIC int64_t writemoves(uint8_t *, int, uint64_t, char *);
STATIC uint8_t
readmove(char c)
@@ -38,18 +38,29 @@ readmodifier(char c)
}
}
-STATIC int
-writemoves(uint8_t *m, int n, char *buf)
+STATIC int64_t
+writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf)
{
int i;
- size_t len;
+ uint64_t len;
const char *s;
char *b;
- for (i = 0, b = buf; i < n; i++, b++) {
+ if (buf_size == 0) {
+ LOG("Error: cannot write moves to buffer of size 0.\n");
+ return NISSY_ERROR_BUFFER_SIZE;
+ }
+
+ for (i = 0, b = buf; i < n; i++, b++, buf_size--) {
s = movestr[m[i]];
len = strlen(s);
+ if (len >= buf_size) {
+ LOG("Error: the given buffer is too small for "
+ "writing the given moves.\n");
+ goto writemoves_error;
+ }
memcpy(b, s, len);
+ buf_size -= len;
b += len;
*b = ' ';
}
@@ -58,5 +69,9 @@ writemoves(uint8_t *m, int n, char *buf)
b--; /* Remove last space */
*b = '\0';
- return b - buf;
+ return buf_size;
+
+writemoves_error:
+ *buf = '\0';
+ return NISSY_ERROR_BUFFER_SIZE;
}
diff --git a/src/core/io_trans.h b/src/core/io_trans.h
@@ -1,8 +1,8 @@
-STATIC uint8_t readtrans(const char *);
-STATIC void writetrans(uint8_t, char *);
+STATIC uint8_t readtrans(const char [static NISSY_SIZE_TRANSFORMATION]);
+STATIC void writetrans(uint8_t, char [static NISSY_SIZE_TRANSFORMATION]);
STATIC uint8_t
-readtrans(const char *buf)
+readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION])
{
uint8_t t;
@@ -14,7 +14,7 @@ readtrans(const char *buf)
}
STATIC void
-writetrans(uint8_t t, char *buf)
+writetrans(uint8_t t, char buf[static NISSY_SIZE_TRANSFORMATION])
{
if (t >= 48)
memcpy(buf, "error trans", 11);
diff --git a/src/nissy.c b/src/nissy.c
@@ -559,9 +559,6 @@ nissy_solve(
solve_h48(c, minmoves, maxmoves, maxsols,
data_size, data, sols_size, sols);
}
- } else if (!strcmp(solver, "simple")) {
- return solve_simple(
- c, minmoves, maxmoves, maxsols, optimal, sols);
} else {
LOG("solve: unknown solver '%s'\n", solver);
return NISSY_ERROR_INVALID_SOLVER;
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
@@ -10,6 +10,7 @@ typedef struct {
uint8_t k;
const uint32_t *cocsepdata;
const uint8_t *h48data;
+ uint64_t solutions_size;
char **nextsol;
uint8_t nissbranch;
int8_t npremoves;
@@ -55,26 +56,40 @@ allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch)
STATIC void
solve_h48_appendsolution(dfsarg_solveh48_t *arg)
{
- int strl;
+ int64_t strl;
uint8_t invertedpremoves[MAXLEN];
char *solution = *arg->nextsol;
- strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
+ strl = writemoves(
+ arg->moves, arg->nmoves, arg->solutions_size, *arg->nextsol);
+
+ if (strl < 0)
+ goto solve_h48_appendsolution_error;
*arg->nextsol += strl;
+ arg->solutions_size -= strl;
if (arg->npremoves) {
**arg->nextsol = ' ';
(*arg->nextsol)++;
invertmoves(arg->premoves, arg->npremoves, invertedpremoves);
- strl = writemoves(invertedpremoves, arg->npremoves, *arg->nextsol);
+ strl = writemoves(invertedpremoves,
+ arg->npremoves, arg->solutions_size, *arg->nextsol);
+
+ if (strl < 0)
+ goto solve_h48_appendsolution_error;
*arg->nextsol += strl;
+ arg->solutions_size -= strl;
}
LOG("Solution found: %s\n", solution);
**arg->nextsol = '\n';
(*arg->nextsol)++;
(*arg->nsols)++;
+
+solve_h48_appendsolution_error:
+ /* We could add some logging, but writemoves() already does */
+ return;
}
STATIC_INLINE bool
@@ -188,6 +203,7 @@ solve_h48(
.k = info.bits,
.cocsepdata = get_cocsepdata_constptr(data),
.h48data = get_h48data_constptr(data),
+ .solutions_size = solutions_size,
.nextsol = &solutions
};
diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h
@@ -27,12 +27,17 @@ STATIC void
solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq)
{
pthread_mutex_lock(&tq->mutex);
- int strl = 0;
+ int64_t strl = 0;
uint8_t invertedpremoves[MAXLEN];
char *solution = *arg->nextsol;
- strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
+ strl = writemoves(
+ arg->moves, arg->nmoves, arg->solutions_size, *arg->nextsol);
+
+ if (strl < 0)
+ goto solve_h48_appendsolution_thread_error;
*arg->nextsol += strl;
+ arg->solutions_size -= strl;
if (arg->npremoves)
{
@@ -40,14 +45,22 @@ solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq)
(*arg->nextsol)++;
invertmoves(arg->premoves, arg->npremoves, invertedpremoves);
- strl = writemoves(invertedpremoves, arg->npremoves, *arg->nextsol);
+ strl = writemoves(invertedpremoves,
+ arg->npremoves, arg->solutions_size, *arg->nextsol);
+
+ if (strl < 0)
+ goto solve_h48_appendsolution_thread_error;
*arg->nextsol += strl;
+ arg->solutions_size -= strl;
}
LOG("Solution found: %s\n", solution);
**arg->nextsol = '\n';
(*arg->nextsol)++;
(*arg->nsols)++;
+
+solve_h48_appendsolution_thread_error:
+ /* We could add some logging, but writemoves() already does */
pthread_mutex_unlock(&tq->mutex);
}
@@ -264,7 +277,9 @@ solve_h48_multithread(
.k = info.bits,
.cocsepdata = get_cocsepdata_constptr(data),
.h48data = get_h48data_constptr(data),
- .nextsol = &solutions};
+ .solutions_size = solutions_size,
+ .nextsol = &solutions
+ };
task_queue_t q;
init_queue(&q);
diff --git a/test/032_invertmoves/invertmoves_tests.c b/test/032_invertmoves/invertmoves_tests.c
@@ -3,7 +3,7 @@
#define MAXMOVES 20
int64_t readmoves(const char *, int, uint8_t *);
-void writemoves(uint8_t *, int, char *);
+void writemoves(uint8_t *, int, uint64_t, char *);
void invertmoves(uint8_t *, uint8_t, uint8_t *);
void run(void) {
@@ -15,7 +15,7 @@ void run(void) {
c = readmoves(movestr, MAXMOVES, moves);
invertmoves(moves, c, ret);
- writemoves(ret, c, outstr);
+ writemoves(ret, c, STRLENMAX, outstr);
printf("%s\n", outstr);
}
diff --git a/test/061_inverse_trans/inverse_trans_tests.c b/test/061_inverse_trans/inverse_trans_tests.c
@@ -1,6 +1,6 @@
#include "../test.h"
-uint8_t readtrans(char *);
+uint8_t readtrans(char [static NISSY_SIZE_TRANSFORMATION]);
uint8_t inverse_trans(uint8_t);
cube_t applymoves(cube_t, char *);
cube_t applytrans(cube_t, char *);