Skip to content

Commit 7f3326e

Browse files
authored
Merge pull request #91 from rekka/fix-63
Fix #63: do not panic into C
2 parents 4cec394 + daeb229 commit 7f3326e

File tree

3 files changed

+52
-32
lines changed

3 files changed

+52
-32
lines changed

src/engines/mod.rs

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -383,15 +383,9 @@ impl<'a, I: 'a + IoProvider> ExecutionState<'a, I> {
383383
}
384384
}
385385

386-
fn input_seek(&mut self, handle: *mut InputHandle, pos: SeekFrom) -> u64 {
386+
fn input_seek(&mut self, handle: *mut InputHandle, pos: SeekFrom) -> Result<u64> {
387387
let rhandle: &mut InputHandle = unsafe { &mut *handle };
388-
match rhandle.try_seek(pos) {
389-
Ok(pos) => pos,
390-
Err(e) => {
391-
tt_warning!(self.status, "input seek failed"; e);
392-
0
393-
}
394-
}
388+
rhandle.try_seek(pos)
395389
}
396390

397391
fn input_read(&mut self, handle: *mut InputHandle, buf: &mut [u8]) -> Result<()> {
@@ -422,8 +416,10 @@ impl<'a, I: 'a + IoProvider> ExecutionState<'a, I> {
422416
return false;
423417
}
424418
}
419+
// TODO: Handle the error better. This indicates a bug in the engine.
420+
tt_error!(self.status, "serious internal bug: unexpected handle in input close: {:?}", handle);
425421

426-
panic!("unexpected handle {:?}", handle);
422+
true
427423
}
428424
}
429425

@@ -472,21 +468,21 @@ extern {
472468

473469
// Entry points for the C/C++ API functions.
474470

475-
fn issue_warning<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, text: *const libc::c_char) {
471+
extern fn issue_warning<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, text: *const libc::c_char) {
476472
let es = unsafe { &mut *es };
477473
let rtext = unsafe { CStr::from_ptr(text) };
478474

479475
tt_warning!(es.status, "{}", rtext.to_string_lossy());
480476
}
481477

482-
fn issue_error<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, text: *const libc::c_char) {
478+
extern fn issue_error<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, text: *const libc::c_char) {
483479
let es = unsafe { &mut *es };
484480
let rtext = unsafe { CStr::from_ptr(text) };
485481

486482
tt_error!(es.status, "{}", rtext.to_string_lossy());
487483
}
488484

489-
fn get_file_md5<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, path: *const libc::c_char, digest: *mut u8) -> libc::c_int {
485+
extern fn get_file_md5<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, path: *const libc::c_char, digest: *mut u8) -> libc::c_int {
490486
let es = unsafe { &mut *es };
491487
let rpath = osstr_from_cstr(unsafe { CStr::from_ptr(path) });
492488
let rdest = unsafe { slice::from_raw_parts_mut(digest, 16) };
@@ -498,7 +494,7 @@ fn get_file_md5<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, path: *c
498494
}
499495
}
500496

501-
fn get_data_md5<'a, I: 'a + IoProvider>(_es: *mut ExecutionState<'a, I>, data: *const u8, len: libc::size_t, digest: *mut u8) -> libc::c_int {
497+
extern fn get_data_md5<'a, I: 'a + IoProvider>(_es: *mut ExecutionState<'a, I>, data: *const u8, len: libc::size_t, digest: *mut u8) -> libc::c_int {
502498
//let es = unsafe { &mut *es };
503499
let rdata = unsafe { slice::from_raw_parts(data, len) };
504500
let rdest = unsafe { slice::from_raw_parts_mut(digest, 16) };
@@ -511,21 +507,21 @@ fn get_data_md5<'a, I: 'a + IoProvider>(_es: *mut ExecutionState<'a, I>, data: *
511507
0
512508
}
513509

514-
fn output_open<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, name: *const libc::c_char, is_gz: libc::c_int) -> *const libc::c_void {
510+
extern fn output_open<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, name: *const libc::c_char, is_gz: libc::c_int) -> *const libc::c_void {
515511
let es = unsafe { &mut *es };
516512
let rname = osstr_from_cstr(&unsafe { CStr::from_ptr(name) });
517513
let ris_gz = is_gz != 0;
518514

519515
es.output_open(&rname, ris_gz) as *const _
520516
}
521517

522-
fn output_open_stdout<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, ) -> *const libc::c_void {
518+
extern fn output_open_stdout<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, ) -> *const libc::c_void {
523519
let es = unsafe { &mut *es };
524520

525521
es.output_open_stdout() as *const _
526522
}
527523

528-
fn output_putc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, c: libc::c_int) -> libc::c_int {
524+
extern fn output_putc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, c: libc::c_int) -> libc::c_int {
529525
let es = unsafe { &mut *es };
530526
let rhandle = handle as *mut OutputHandle;
531527
let rc = c as u8;
@@ -537,7 +533,7 @@ fn output_putc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *
537533
}
538534
}
539535

540-
fn output_write<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, data: *const u8, len: libc::size_t) -> libc::size_t {
536+
extern fn output_write<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, data: *const u8, len: libc::size_t) -> libc::size_t {
541537
let es = unsafe { &mut *es };
542538
let rhandle = handle as *mut OutputHandle;
543539
let rdata = unsafe { slice::from_raw_parts(data, len) };
@@ -551,7 +547,7 @@ fn output_write<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle:
551547
}
552548
}
553549

554-
fn output_flush<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
550+
extern fn output_flush<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
555551
let es = unsafe { &mut *es };
556552
let rhandle = handle as *mut OutputHandle;
557553

@@ -562,7 +558,7 @@ fn output_flush<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle:
562558
}
563559
}
564560

565-
fn output_close<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
561+
extern fn output_close<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
566562
let es = unsafe { &mut *es };
567563

568564
if handle == 0 as *mut _ {
@@ -579,7 +575,7 @@ fn output_close<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle:
579575
}
580576

581577

582-
fn input_open<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, name: *const libc::c_char, format: libc::c_int, is_gz: libc::c_int) -> *const libc::c_void {
578+
extern fn input_open<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, name: *const libc::c_char, format: libc::c_int, is_gz: libc::c_int) -> *const libc::c_void {
583579
let es = unsafe { &mut *es };
584580
let rname = osstr_from_cstr(unsafe { CStr::from_ptr(name) });
585581
let rformat = c_format_to_rust(format);
@@ -593,34 +589,48 @@ fn input_open<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, name: *con
593589
}
594590
}
595591

596-
fn input_open_primary<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>) -> *const libc::c_void {
592+
extern fn input_open_primary<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>) -> *const libc::c_void {
597593
let es = unsafe { &mut *es };
598594

599595
es.input_open_primary() as *const _
600596
}
601597

602-
fn input_get_size<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::size_t {
598+
extern fn input_get_size<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::size_t {
603599
let es = unsafe { &mut *es };
604600
let rhandle = handle as *mut InputHandle;
605601

606602
es.input_get_size(rhandle)
607603
}
608604

609-
fn input_seek<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, offset: libc::ssize_t, whence: libc::c_int) -> libc::size_t {
605+
extern fn input_seek<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, offset: libc::ssize_t, whence: libc::c_int, internal_error: *mut libc::c_int) -> libc::size_t {
610606
let es = unsafe { &mut *es };
611607
let rhandle = handle as *mut InputHandle;
612608

613609
let rwhence = match whence {
614610
libc::SEEK_SET => SeekFrom::Start(offset as u64),
615611
libc::SEEK_CUR => SeekFrom::Current(offset as i64),
616612
libc::SEEK_END => SeekFrom::End(offset as i64),
617-
_ => panic!("Unexpected \"whence\" parameter to fseek() wrapper: {}", whence),
613+
_ => {
614+
tt_error!(es.status, "serious internal bug: unexpected \"whence\" parameter to fseek() wrapper: {}",
615+
whence);
616+
unsafe {
617+
*internal_error = 1;
618+
}
619+
return 0;
620+
}
618621
};
619622

620-
es.input_seek(rhandle, rwhence) as libc::size_t
623+
match es.input_seek(rhandle, rwhence) {
624+
Ok(pos) => pos as libc::size_t,
625+
Err(e) => {
626+
// TODO: Handle the error better. Report the error properly to the caller?
627+
tt_error!(es.status, "input seek failed"; e);
628+
0
629+
}
630+
}
621631
}
622632

623-
fn input_getc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
633+
extern fn input_getc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
624634
let es = unsafe { &mut *es };
625635
let rhandle = handle as *mut InputHandle;
626636

@@ -637,7 +647,7 @@ fn input_getc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *m
637647
}
638648
}
639649

640-
fn input_ungetc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, ch: libc::c_int) -> libc::c_int {
650+
extern fn input_ungetc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, ch: libc::c_int) -> libc::c_int {
641651
let es = unsafe { &mut *es };
642652
let rhandle = handle as *mut InputHandle;
643653

@@ -650,7 +660,7 @@ fn input_ungetc<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle:
650660
}
651661
}
652662

653-
fn input_read<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, data: *mut u8, len: libc::size_t) -> libc::ssize_t {
663+
extern fn input_read<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void, data: *mut u8, len: libc::size_t) -> libc::ssize_t {
654664
let es = unsafe { &mut *es };
655665
let rhandle = handle as *mut InputHandle;
656666
let rdata = unsafe { slice::from_raw_parts_mut(data, len) };
@@ -664,7 +674,7 @@ fn input_read<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *m
664674
}
665675
}
666676

667-
fn input_close<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
677+
extern fn input_close<'a, I: 'a + IoProvider>(es: *mut ExecutionState<'a, I>, handle: *mut libc::c_void) -> libc::c_int {
668678
let es = unsafe { &mut *es };
669679

670680
if handle == 0 as *mut _ {

tectonic/core-bridge.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,13 @@ ttstub_input_get_size(rust_input_handle_t handle)
220220
size_t
221221
ttstub_input_seek(rust_input_handle_t handle, ssize_t offset, int whence)
222222
{
223-
return TGB->input_seek(TGB->context, handle, offset, whence);
223+
int internal_error = 0;
224+
size_t rv = TGB->input_seek(TGB->context, handle, offset, whence, &internal_error);
225+
if (internal_error) {
226+
// Nonzero indicates a serious internal error.
227+
longjmp(jump_buffer, 1);
228+
}
229+
return rv;
224230
}
225231

226232
ssize_t
@@ -244,5 +250,9 @@ ttstub_input_ungetc(rust_input_handle_t handle, int ch)
244250
int
245251
ttstub_input_close(rust_input_handle_t handle)
246252
{
247-
return TGB->input_close(TGB->context, handle);
253+
if (TGB->input_close(TGB->context, handle)) {
254+
// Nonzero return value indicates a serious internal error.
255+
longjmp(jump_buffer, 1);
256+
}
257+
return 0;
248258
}

tectonic/core-bridge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ typedef struct tt_bridge_api_t {
6868
rust_input_handle_t (*input_open)(void *context, char const *path, tt_input_format_type format, int is_gz);
6969
rust_input_handle_t (*input_open_primary)(void *context);
7070
size_t (*input_get_size)(void *context, rust_input_handle_t handle);
71-
size_t (*input_seek)(void *context, rust_input_handle_t handle, ssize_t offset, int whence);
71+
size_t (*input_seek)(void *context, rust_input_handle_t handle, ssize_t offset, int whence, int* internal_error);
7272
ssize_t (*input_read)(void *context, rust_input_handle_t handle, char *data, size_t len);
7373
int (*input_getc)(void *context, rust_input_handle_t handle);
7474
int (*input_ungetc)(void *context, rust_input_handle_t handle, int ch);

0 commit comments

Comments
 (0)