fix: add missing UndoAction fields and null checks to prevent memory corruption
Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
30
engine.c
30
engine.c
@@ -201,14 +201,18 @@ void queue_trigger(Engine *engine, int clip_index, bool is_scene, jack_nframes_t
|
||||
engine->queued_triggers = qt;
|
||||
} else {
|
||||
QueuedTrigger *last = engine->queued_triggers;
|
||||
while (last->next) last = last->next;
|
||||
last->next = qt;
|
||||
while (last && last->next) last = last->next; // FIX: add null check for last
|
||||
if (last) { // ADD THIS
|
||||
last->next = qt;
|
||||
} else {
|
||||
engine->queued_triggers = qt; // Fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process queued triggers at quantization boundaries
|
||||
static void process_queued_triggers(Engine *engine, jack_nframes_t nframes) {
|
||||
if (!engine->queued_triggers) return;
|
||||
if (!engine || !engine->queued_triggers) return; // FIX: add engine null check
|
||||
TransportState transport_state = (TransportState)atomic_load(&engine->transport->state_atomic);
|
||||
if (transport_state != TRANSPORT_PLAYING) return;
|
||||
|
||||
@@ -281,6 +285,7 @@ void engine_process_commands(Engine *engine) {
|
||||
case CMD_TRIGGER_CLIP: {
|
||||
if (cmd.index < 0 || cmd.index >= MAX_CLIPS) break;
|
||||
Clip *clip = &engine->clips[cmd.index];
|
||||
if (!clip->buffer) break; // ADD THIS - prevent segfault on freed buffer
|
||||
|
||||
// Record undo action
|
||||
UndoAction action;
|
||||
@@ -503,10 +508,13 @@ void engine_undo(Engine *engine) {
|
||||
switch (action->type) {
|
||||
case ACTION_TRIGGER_CLIP: {
|
||||
int clip_idx = action->index;
|
||||
engine->clips[clip_idx].state = action->previous_state;
|
||||
engine->clips[clip_idx].buffer_size = action->previous_buffer_size;
|
||||
engine->clips[clip_idx].write_position = action->previous_write_position;
|
||||
engine->clips[clip_idx].read_position = action->previous_read_position;
|
||||
if (clip_idx < 0 || clip_idx >= MAX_CLIPS) break;
|
||||
Clip *clip = &engine->clips[clip_idx];
|
||||
if (!clip->buffer) break; // ADD THIS
|
||||
clip->state = action->previous_state;
|
||||
clip->buffer_size = action->previous_buffer_size;
|
||||
clip->write_position = action->previous_write_position;
|
||||
clip->read_position = action->previous_read_position;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -574,8 +582,10 @@ void engine_redo(Engine *engine) {
|
||||
switch (action->type) {
|
||||
case ACTION_TRIGGER_CLIP: {
|
||||
int clip_idx = action->index;
|
||||
// Re-apply the trigger by directly manipulating state
|
||||
if (clip_idx < 0 || clip_idx >= MAX_CLIPS) break;
|
||||
Clip *clip = &engine->clips[clip_idx];
|
||||
if (!clip->buffer) break; // ADD THIS
|
||||
// Re-apply the trigger by directly manipulating state
|
||||
switch (clip->state) {
|
||||
case CLIP_EMPTY:
|
||||
clip->state = CLIP_RECORDING;
|
||||
@@ -699,6 +709,7 @@ int engine_init(Engine *engine, const char *client_name) {
|
||||
// Cleanup on allocation failure
|
||||
for (int j = 0; j < MAX_CLIPS; j++) {
|
||||
free(engine->clips[j].buffer);
|
||||
engine->clips[j].buffer = NULL; // ADD THIS
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -712,7 +723,10 @@ int engine_init(Engine *engine, const char *client_name) {
|
||||
// Cleanup on allocation failure
|
||||
for (int j = 0; j < i; j++) {
|
||||
free(engine->clips[j].buffer);
|
||||
engine->clips[j].buffer = NULL; // ADD THIS
|
||||
}
|
||||
free(engine->transport);
|
||||
engine->transport = NULL; // ADD THIS
|
||||
return -1;
|
||||
}
|
||||
engine->clips[i].buffer_size = 0;
|
||||
|
||||
@@ -112,7 +112,7 @@ double transport_get_bpm(Transport *transport) {
|
||||
|
||||
int transport_process(Transport *transport, jack_nframes_t nframes,
|
||||
void *midi_clock_in_buf, void *midi_clock_out_buf) {
|
||||
if (!transport) return 0;
|
||||
if (!transport) return -1; // ADD THIS
|
||||
|
||||
int clock_ticks_generated = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user