aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-10-12 11:11:28 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-10-12 11:11:28 +0200
commitda8fdd4955fd24666643915a6728678e9965a0d3 (patch)
tree878d7baf68f90e80949bc79a039bda159865821f /src/core
parent14689e29252e608d51c5b52e61e43471d2aa021e (diff)
downloadnissy-core-da8fdd4955fd24666643915a6728678e9965a0d3.tar.gz
nissy-core-da8fdd4955fd24666643915a6728678e9965a0d3.zip
Make writecube safer
Diffstat (limited to 'src/core')
-rw-r--r--src/core/io_cube.h103
1 files changed, 61 insertions, 42 deletions
diff --git a/src/core/io_cube.h b/src/core/io_cube.h
index 1ac8ec7..0c18f34 100644
--- a/src/core/io_cube.h
+++ b/src/core/io_cube.h
@@ -1,5 +1,5 @@
1STATIC cube_t readcube(const char *, const char *); 1STATIC cube_t readcube(const char *, const char *);
2STATIC int writecube(const char *, cube_t, char *); 2STATIC int64_t writecube(const char *, cube_t, uint64_t, char *);
3STATIC void log_available_formats(void); 3STATIC void log_available_formats(void);
4STATIC uint8_t readco(const char *); 4STATIC uint8_t readco(const char *);
5STATIC uint8_t readcp(const char *); 5STATIC uint8_t readcp(const char *);
@@ -10,10 +10,10 @@ STATIC cube_t readcube_H48(const char *);
10STATIC uint8_t readpiece_LST(const char **); 10STATIC uint8_t readpiece_LST(const char **);
11STATIC cube_t readcube_LST(const char *); 11STATIC cube_t readcube_LST(const char *);
12 12
13STATIC int writepiece_LST(uint8_t, char *); 13STATIC int64_t writepiece_LST(uint8_t, uint64_t, char *);
14STATIC void writecube_B32(cube_t, char *); 14STATIC int64_t writecube_B32(cube_t, uint64_t, char *);
15STATIC void writecube_H48(cube_t, char *); 15STATIC int64_t writecube_H48(cube_t, uint64_t, char *);
16STATIC void writecube_LST(cube_t, char *); 16STATIC int64_t writecube_LST(cube_t, uint64_t, char *);
17 17
18STATIC uint8_t b32toedge(char); 18STATIC uint8_t b32toedge(char);
19STATIC uint8_t b32tocorner(char); 19STATIC uint8_t b32tocorner(char);
@@ -23,7 +23,7 @@ STATIC char cornertob32(uint8_t);
23STATIC struct { 23STATIC struct {
24 const char *name; 24 const char *name;
25 cube_t (*read)(const char *); 25 cube_t (*read)(const char *);
26 void (*write)(cube_t, char *); 26 int64_t (*write)(cube_t, uint64_t, char *);
27} ioformat[] = 27} ioformat[] =
28{ 28{
29 { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, 29 { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
@@ -46,35 +46,18 @@ readcube(const char *format, const char *buf)
46 return ZERO_CUBE; 46 return ZERO_CUBE;
47} 47}
48 48
49STATIC int 49STATIC int64_t
50writecube(const char *format, cube_t cube, char *buf) 50writecube(const char *format, cube_t cube, uint64_t buf_size, char *buf)
51{ 51{
52 char *errormsg;
53 size_t len;
54
55 if (!isconsistent(cube)) {
56 errormsg = "ERROR: inconsistent";
57 goto writecube_error;
58 }
59
60 int i; 52 int i;
61 53
62 for (i = 0; ioformat[i].write != NULL; i++) { 54 for (i = 0; ioformat[i].write != NULL; i++)
63 if (!strcmp(format, ioformat[i].name)) { 55 if (!strcmp(format, ioformat[i].name))
64 ioformat[i].write(cube, buf); 56 return ioformat[i].write(cube, buf_size, buf);
65 return 0;
66 }
67 }
68 57
69 LOG("Cannot write cube: unknown format '%s'\n", format); 58 LOG("Cannot write cube: unknown format '%s'\n", format);
70 log_available_formats(); 59 log_available_formats();
71 errormsg = "ERROR: format"; 60 return NISSY_ERROR_INVALID_FORMAT;
72
73writecube_error:
74 len = strlen(errormsg);
75 memcpy(buf, errormsg, len);
76 buf[len] = '\0';
77 return 1;
78} 61}
79 62
80STATIC void 63STATIC void
@@ -249,11 +232,14 @@ readcube_LST(const char *buf)
249 return cubefromarray(c, e); 232 return cubefromarray(c, e);
250} 233}
251 234
252STATIC int 235STATIC int64_t
253writepiece_LST(uint8_t piece, char *buf) 236writepiece_LST(uint8_t piece, uint64_t buf_size, char *buf)
254{ 237{
255 char digits[3]; 238 char digits[3];
256 int i, len; 239 uint64_t i, len;
240
241 if (piece > 99 || buf_size < 3)
242 return 0;
257 243
258 len = 0; 244 len = 0;
259 while (piece != 0) { 245 while (piece != 0) {
@@ -261,6 +247,9 @@ writepiece_LST(uint8_t piece, char *buf)
261 piece /= 10; 247 piece /= 10;
262 } 248 }
263 249
250 if (buf_size < len+2)
251 return 0;
252
264 if (len == 0) 253 if (len == 0)
265 digits[len++] = '0'; 254 digits[len++] = '0';
266 255
@@ -273,12 +262,19 @@ writepiece_LST(uint8_t piece, char *buf)
273 return len+2; 262 return len+2;
274} 263}
275 264
276STATIC void 265STATIC int64_t
277writecube_B32(cube_t cube, char *buf) 266writecube_B32(cube_t cube, uint64_t buf_size, char *buf)
278{ 267{
279 int i; 268 int i;
280 uint8_t corner[8], edge[12]; 269 uint8_t corner[8], edge[12];
281 270
271 if (buf_size < NISSY_SIZE_B32) {
272 LOG("Cannot write cube in B32 format: buffer size must be "
273 "at least %" PRIu64 " bytes, but the provided one is %"
274 PRIu64 " bytes.\n", NISSY_SIZE_B32, buf_size);
275 return NISSY_ERROR_BUFFER_SIZE;
276 }
277
282 pieces(&cube, corner, edge); 278 pieces(&cube, corner, edge);
283 279
284 for (i = 0; i < 8; i++) 280 for (i = 0; i < 8; i++)
@@ -290,14 +286,23 @@ writecube_B32(cube_t cube, char *buf)
290 buf[i+9] = edgetob32(edge[i]); 286 buf[i+9] = edgetob32(edge[i]);
291 287
292 buf[21] = '\0'; 288 buf[21] = '\0';
289
290 return NISSY_OK;
293} 291}
294 292
295STATIC void 293STATIC int64_t
296writecube_H48(cube_t cube, char *buf) 294writecube_H48(cube_t cube, uint64_t buf_size, char *buf)
297{ 295{
298 uint8_t piece, perm, orient, corner[8], edge[12]; 296 uint8_t piece, perm, orient, corner[8], edge[12];
299 int i; 297 int i;
300 298
299 if (buf_size < NISSY_SIZE_H48) {
300 LOG("Cannot write cube in H48 format: buffer size must be "
301 "at least %" PRIu64 " bytes, but the provided one is %"
302 PRIu64 " bytes.\n", NISSY_SIZE_H48, buf_size);
303 return NISSY_ERROR_BUFFER_SIZE;
304 }
305
301 pieces(&cube, corner, edge); 306 pieces(&cube, corner, edge);
302 307
303 for (i = 0; i < 12; i++) { 308 for (i = 0; i < 12; i++) {
@@ -321,13 +326,15 @@ writecube_H48(cube_t cube, char *buf)
321 } 326 }
322 327
323 buf[48+39] = '\0'; 328 buf[48+39] = '\0';
329
330 return NISSY_OK;
324} 331}
325 332
326STATIC void 333STATIC int64_t
327writecube_LST(cube_t cube, char *buf) 334writecube_LST(cube_t cube, uint64_t buf_size, char *buf)
328{ 335{
329 int i; 336 int i;
330 size_t ptr; 337 uint64_t ptr;
331 uint8_t piece, corner[8], edge[12]; 338 uint8_t piece, corner[8], edge[12];
332 339
333 ptr = 0; 340 ptr = 0;
@@ -335,15 +342,27 @@ writecube_LST(cube_t cube, char *buf)
335 342
336 for (i = 0; i < 8; i++) { 343 for (i = 0; i < 8; i++) {
337 piece = corner[i]; 344 piece = corner[i];
338 ptr += writepiece_LST(piece, buf + ptr); 345 ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr);
346 if (ptr == 0)
347 goto writecube_LST_error;
339 } 348 }
340 349
341 for (i = 0; i < 12; i++) { 350 for (i = 0; i < 12; i++) {
342 piece = edge[i]; 351 piece = edge[i];
343 ptr += writepiece_LST(piece, buf + ptr); 352 ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr);
353 if (ptr == 0)
354 goto writecube_LST_error;
344 } 355 }
345 356
346 *(buf+ptr-2) = 0; 357 *(buf+ptr-2) = '\0';
358
359 return NISSY_OK;
360
361writecube_LST_error:
362 LOG("Cannot write cube in LST: buffer is too small (%" PRIu64
363 " bytes given). The LST format has a variable size, try a "
364 "larger buffer.\n", buf_size);
365 return NISSY_ERROR_BUFFER_SIZE;
347} 366}
348 367
349STATIC uint8_t 368STATIC uint8_t

Generated with cgit - Back to sebastiano.tronto.net