solver-c: harden parser/io and numerical output entrypoints
Improve stdin/file JSON ingestion safety and guard output paths against edge-case assumptions so solver binaries fail predictably instead of risking malformed reads. Made-with: Cursor
This commit is contained in:
@@ -9,30 +9,49 @@
|
||||
#define JSON_MAX_SIZE (4 * 1024 * 1024)
|
||||
|
||||
int solver_read_json_stdin(char **buffer_out, size_t *length_out) {
|
||||
size_t cap = JSON_READ_CHUNK;
|
||||
size_t cap = JSON_READ_CHUNK + 1;
|
||||
size_t len = 0;
|
||||
char *buf = (char *)malloc(cap);
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
for (;;) {
|
||||
size_t n = fread(buf + len, 1, JSON_READ_CHUNK, stdin);
|
||||
len += n;
|
||||
if (n < JSON_READ_CHUNK) {
|
||||
break;
|
||||
}
|
||||
if (len + JSON_READ_CHUNK > JSON_MAX_SIZE) {
|
||||
free(buf);
|
||||
return -2;
|
||||
}
|
||||
if (len + JSON_READ_CHUNK > cap) {
|
||||
cap *= 2;
|
||||
char *nb = (char *)realloc(buf, cap);
|
||||
size_t remaining = (cap > len) ? (cap - len - 1) : 0;
|
||||
if (remaining == 0) {
|
||||
if (cap > JSON_MAX_SIZE) {
|
||||
free(buf);
|
||||
return -2;
|
||||
}
|
||||
size_t next_cap = cap * 2;
|
||||
if (next_cap > JSON_MAX_SIZE + 1) {
|
||||
next_cap = JSON_MAX_SIZE + 1;
|
||||
}
|
||||
if (next_cap <= cap) {
|
||||
free(buf);
|
||||
return -2;
|
||||
}
|
||||
char *nb = (char *)realloc(buf, next_cap);
|
||||
if (!nb) {
|
||||
free(buf);
|
||||
return -3;
|
||||
}
|
||||
buf = nb;
|
||||
cap = next_cap;
|
||||
remaining = cap - len - 1;
|
||||
}
|
||||
size_t to_read = remaining < JSON_READ_CHUNK ? remaining : JSON_READ_CHUNK;
|
||||
size_t n = fread(buf + len, 1, to_read, stdin);
|
||||
len += n;
|
||||
if (ferror(stdin)) {
|
||||
free(buf);
|
||||
return -4;
|
||||
}
|
||||
if (n < to_read) {
|
||||
break;
|
||||
}
|
||||
if (len >= JSON_MAX_SIZE) {
|
||||
free(buf);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
buf[len] = '\0';
|
||||
|
||||
@@ -4,6 +4,40 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int read_json_file(const char *path, char **buf_out) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
return -1;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
long sz = ftell(fp);
|
||||
if (sz < 0) {
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_SET) != 0) {
|
||||
fclose(fp);
|
||||
return -4;
|
||||
}
|
||||
char *buf = (char *)malloc((size_t)sz + 1);
|
||||
if (!buf) {
|
||||
fclose(fp);
|
||||
return -5;
|
||||
}
|
||||
size_t n = fread(buf, 1, (size_t)sz, fp);
|
||||
fclose(fp);
|
||||
if (n != (size_t)sz) {
|
||||
free(buf);
|
||||
return -6;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
*buf_out = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_json_output(const SolverInputs *inputs, const SolverOutputs *outputs) {
|
||||
printf("{\n");
|
||||
printf(" \"pointCount\": %d,\n", outputs->point_count);
|
||||
@@ -33,8 +67,12 @@ static void print_json_output(const SolverInputs *inputs, const SolverOutputs *o
|
||||
}
|
||||
printf(" ],\n");
|
||||
|
||||
double pmin = outputs->pump_position_m[0];
|
||||
double pmax = outputs->pump_position_m[0];
|
||||
double pmin = 0.0;
|
||||
double pmax = 0.0;
|
||||
if (outputs->point_count > 0) {
|
||||
pmin = outputs->pump_position_m[0];
|
||||
pmax = outputs->pump_position_m[0];
|
||||
}
|
||||
for (int i = 1; i < outputs->point_count; i++) {
|
||||
if (outputs->pump_position_m[i] < pmin) pmin = outputs->pump_position_m[i];
|
||||
if (outputs->pump_position_m[i] > pmax) pmax = outputs->pump_position_m[i];
|
||||
@@ -143,18 +181,11 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
} else if (argc == 2) {
|
||||
/* allow file path for tests */
|
||||
FILE *fp = fopen(argv[1], "rb");
|
||||
if (!fp) {
|
||||
int rr = read_json_file(argv[1], &buf);
|
||||
if (rr != 0) {
|
||||
fprintf(stderr, "usage: solver_main --stdin OR solver_main <path.json>\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long sz = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
buf = (char *)malloc((size_t)sz + 1);
|
||||
fread(buf, 1, (size_t)sz, fp);
|
||||
fclose(fp);
|
||||
buf[sz] = '\0';
|
||||
} else {
|
||||
fprintf(stderr, "usage: solver_main --stdin OR solver_main <path.json>\n");
|
||||
return 1;
|
||||
|
||||
@@ -4,6 +4,40 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int read_json_file(const char *path, char **buf_out) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
return -1;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
long sz = ftell(fp);
|
||||
if (sz < 0) {
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_SET) != 0) {
|
||||
fclose(fp);
|
||||
return -4;
|
||||
}
|
||||
char *buf = (char *)malloc((size_t)sz + 1);
|
||||
if (!buf) {
|
||||
fclose(fp);
|
||||
return -5;
|
||||
}
|
||||
size_t n = fread(buf, 1, (size_t)sz, fp);
|
||||
fclose(fp);
|
||||
if (n != (size_t)sz) {
|
||||
free(buf);
|
||||
return -6;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
*buf_out = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_json_output(const SolverInputs *inputs, const SolverOutputs *outputs) {
|
||||
printf("{\n");
|
||||
printf(" \"pointCount\": %d,\n", outputs->point_count);
|
||||
@@ -33,8 +67,12 @@ static void print_json_output(const SolverInputs *inputs, const SolverOutputs *o
|
||||
}
|
||||
printf(" ],\n");
|
||||
|
||||
double pmin = outputs->pump_position_m[0];
|
||||
double pmax = outputs->pump_position_m[0];
|
||||
double pmin = 0.0;
|
||||
double pmax = 0.0;
|
||||
if (outputs->point_count > 0) {
|
||||
pmin = outputs->pump_position_m[0];
|
||||
pmax = outputs->pump_position_m[0];
|
||||
}
|
||||
for (int i = 1; i < outputs->point_count; i++) {
|
||||
if (outputs->pump_position_m[i] < pmin) pmin = outputs->pump_position_m[i];
|
||||
if (outputs->pump_position_m[i] > pmax) pmax = outputs->pump_position_m[i];
|
||||
@@ -142,18 +180,11 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
} else if (argc == 2) {
|
||||
FILE *fp = fopen(argv[1], "rb");
|
||||
if (!fp) {
|
||||
int rr = read_json_file(argv[1], &buf);
|
||||
if (rr != 0) {
|
||||
fprintf(stderr, "usage: solver_fea_main --stdin OR solver_fea_main <path.json>\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long sz = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
buf = (char *)malloc((size_t)sz + 1);
|
||||
fread(buf, 1, (size_t)sz, fp);
|
||||
fclose(fp);
|
||||
buf[sz] = '\0';
|
||||
} else {
|
||||
fprintf(stderr, "usage: solver_fea_main --stdin OR solver_fea_main <path.json>\n");
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user