Skip to content

Commit 8b12815

Browse files
committed
protect against bad inputs
1 parent 8df63c3 commit 8b12815

1 file changed

Lines changed: 65 additions & 29 deletions

File tree

src/jres_internal_types.cpp

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ Availability to_internal_availability(JresAvailability availability) {
7070
}
7171

7272
SolverInput from_c_input(const JresSolverInput* c_input) {
73+
if (!c_input) {
74+
throw std::runtime_error("Input pointer is null");
75+
}
76+
7377
SolverInput input;
7478

7579
input.consecutiveStints = c_input->consecutiveStints;
@@ -79,36 +83,68 @@ SolverInput from_c_input(const JresSolverInput* c_input) {
7983
input.firstStintDriver = input.strings.get_id(c_input->firstStintDriver);
8084
}
8185

82-
for (int i = 0; i < c_input->teamMembers_len; ++i) {
83-
TeamMember member;
84-
member.nameId = input.strings.get_id(c_input->teamMembers[i].name);
85-
member.isDriver = c_input->teamMembers[i].isDriver;
86-
member.isSpotter = c_input->teamMembers[i].isSpotter;
87-
member.tzOffset = c_input->teamMembers[i].tzOffset;
88-
input.teamMembers.push_back(member);
89-
}
90-
91-
for (int i = 0; i < c_input->stints_len; ++i) {
92-
Stint stint;
93-
stint.id = c_input->stints[i].id;
94-
auto startTp = TimeHelpers::stringToTimePoint(c_input->stints[i].startTime);
95-
auto endTp = TimeHelpers::stringToTimePoint(c_input->stints[i].endTime);
96-
stint.startTime = std::chrono::system_clock::to_time_t(startTp);
97-
stint.endTime = std::chrono::system_clock::to_time_t(endTp);
98-
input.stints.push_back(stint);
99-
}
100-
101-
for (int i = 0; i < c_input->availability_len; ++i) {
102-
ID memberId = input.strings.get_id(c_input->availability[i].name);
103-
for (int j = 0; j < c_input->availability[i].availability_len; ++j) {
104-
std::string time = c_input->availability[i].availability[j].time;
105-
auto tp = TimeHelpers::stringToTimePoint(time);
106-
std::time_t t = std::chrono::system_clock::to_time_t(tp);
107-
// Normalize to hour bucket
108-
std::time_t key = TimeHelpers::roundToHour(t);
86+
if (c_input->teamMembers_len > 0) {
87+
if (!c_input->teamMembers) {
88+
throw std::runtime_error("teamMembers is null but length is > 0");
89+
}
90+
for (int i = 0; i < c_input->teamMembers_len; ++i) {
91+
if (!c_input->teamMembers[i].name) {
92+
throw std::runtime_error("Team member name is null");
93+
}
94+
TeamMember member;
95+
member.nameId = input.strings.get_id(c_input->teamMembers[i].name);
96+
member.isDriver = c_input->teamMembers[i].isDriver;
97+
member.isSpotter = c_input->teamMembers[i].isSpotter;
98+
member.tzOffset = c_input->teamMembers[i].tzOffset;
99+
input.teamMembers.push_back(member);
100+
}
101+
}
102+
103+
if (c_input->stints_len > 0) {
104+
if (!c_input->stints) {
105+
throw std::runtime_error("stints is null but length is > 0");
106+
}
107+
for (int i = 0; i < c_input->stints_len; ++i) {
108+
if (!c_input->stints[i].startTime || !c_input->stints[i].endTime) {
109+
throw std::runtime_error("Stint start/end time is null");
110+
}
111+
Stint stint;
112+
stint.id = c_input->stints[i].id;
113+
auto startTp = TimeHelpers::stringToTimePoint(c_input->stints[i].startTime);
114+
auto endTp = TimeHelpers::stringToTimePoint(c_input->stints[i].endTime);
115+
stint.startTime = std::chrono::system_clock::to_time_t(startTp);
116+
stint.endTime = std::chrono::system_clock::to_time_t(endTp);
117+
input.stints.push_back(stint);
118+
}
119+
}
120+
121+
if (c_input->availability_len > 0) {
122+
if (!c_input->availability) {
123+
throw std::runtime_error("availability is null but length is > 0");
124+
}
125+
for (int i = 0; i < c_input->availability_len; ++i) {
126+
if (!c_input->availability[i].name) {
127+
throw std::runtime_error("Availability member name is null");
128+
}
129+
ID memberId = input.strings.get_id(c_input->availability[i].name);
109130

110-
JresAvailability availability = c_input->availability[i].availability[j].availability;
111-
input.availability[memberId][key] = to_internal_availability(availability);
131+
if (c_input->availability[i].availability_len > 0 && !c_input->availability[i].availability) {
132+
throw std::runtime_error("Availability entries array is null");
133+
}
134+
135+
for (int j = 0; j < c_input->availability[i].availability_len; ++j) {
136+
if (!c_input->availability[i].availability[j].time) {
137+
throw std::runtime_error("Availability time string is null");
138+
}
139+
std::string time = c_input->availability[i].availability[j].time;
140+
auto tp = TimeHelpers::stringToTimePoint(time);
141+
std::time_t t = std::chrono::system_clock::to_time_t(tp);
142+
// Normalize to hour bucket
143+
std::time_t key = TimeHelpers::roundToHour(t);
144+
145+
JresAvailability availability = c_input->availability[i].availability[j].availability;
146+
input.availability[memberId][key] = to_internal_availability(availability);
147+
}
112148
}
113149
}
114150

0 commit comments

Comments
 (0)