22
22
//! read: Some(buf_read),
23
23
//! userdata: &mut file as *mut _ as *mut std::os::raw::c_void
24
24
//! };
25
- //! let mut rv = mp4parse_capi::Mp4parseStatus::Invalid ;
25
+ //! let mut parser = std::ptr::null_mut() ;
26
26
//! unsafe {
27
- //! let parser = mp4parse_capi::mp4parse_new(&io, &mut rv );
27
+ //! let rv = mp4parse_capi::mp4parse_new(&io, &mut parser );
28
28
//! assert_eq!(rv, mp4parse_capi::Mp4parseStatus::Ok);
29
29
//! assert!(!parser.is_null());
30
30
//! mp4parse_capi::mp4parse_free(parser);
@@ -417,76 +417,66 @@ impl Read for Mp4parseIo {
417
417
///
418
418
/// # Safety
419
419
///
420
- /// This function is unsafe because it dereferences the io pointer given to it.
421
- /// The caller should ensure that the `Mp4ParseIo` struct passed in is a valid
422
- /// pointer. The caller should also ensure the members of io are valid: the
423
- /// `read` function should be sanely implemented, and the `userdata` pointer
424
- /// should be valid. The `status_out` is also dereferenced and must point to
425
- /// a valid Mp4parseStatus.
426
- ///
427
- /// On a successful the variable pointed to by `status_out` will be set to
428
- /// `Mp4parseStatus::Ok` and the return value will be a non-NULL pointer to
429
- /// an `Mp4parseParser`. If there is any sort of error, the return value will
430
- /// be NULL and the type of error will be set in the variable pointed to by
431
- /// `status_out`, ensuring the consumer never has access to potentially invalid
432
- /// parsed data.
420
+ /// This function is unsafe because it dereferences the `io` and `parser_out`
421
+ /// pointers given to it. The caller should ensure that the `Mp4ParseIo`
422
+ /// struct passed in is a valid pointer. The caller should also ensure the
423
+ /// members of io are valid: the `read` function should be sanely implemented,
424
+ /// and the `userdata` pointer should be valid. The `parser_out` should be a
425
+ /// valid pointer to a location containing a null pointer. Upon successful
426
+ /// return (`Mp4parseStatus::Ok`), that location will contain the address of
427
+ /// an `Mp4parseParser` allocated by this function.
433
428
///
434
429
/// To avoid leaking memory, any successful return of this function must be
435
430
/// paired with a call to `mp4parse_free`. In the event of error, no memory
436
431
/// will be allocated and `mp4parse_free` must *not* be called.
437
432
#[ no_mangle]
438
433
pub unsafe extern "C" fn mp4parse_new (
439
434
io : * const Mp4parseIo ,
440
- status_out : * mut Mp4parseStatus ,
441
- ) -> * mut Mp4parseParser {
442
- mp4parse_new_common ( io, status_out )
435
+ parser_out : * mut * mut Mp4parseParser ,
436
+ ) -> Mp4parseStatus {
437
+ mp4parse_new_common ( io, parser_out )
443
438
}
444
439
445
440
/// Allocate an `Mp4parseAvifParser*` to read from the supplied `Mp4parseIo`.
446
441
///
447
- /// See mp4parse_new; this function is identical except that it returns a
448
- /// pointer to an `Mp4parseAvifParser`, which (when non-null ) must be paired
449
- /// with a call to mp4parse_avif_free.
442
+ /// See mp4parse_new; this function is identical except that it allocates an
443
+ /// `Mp4parseAvifParser`, which (when successful ) must be paired with a call
444
+ /// to mp4parse_avif_free.
450
445
///
451
446
/// # Safety
452
447
///
453
448
/// Same as mp4parse_new.
454
449
#[ no_mangle]
455
450
pub unsafe extern "C" fn mp4parse_avif_new (
456
451
io : * const Mp4parseIo ,
457
- status_out : * mut Mp4parseStatus ,
458
- ) -> * mut Mp4parseAvifParser {
459
- mp4parse_new_common ( io, status_out )
452
+ parser_out : * mut * mut Mp4parseAvifParser ,
453
+ ) -> Mp4parseStatus {
454
+ mp4parse_new_common ( io, parser_out )
460
455
}
461
456
462
457
unsafe fn mp4parse_new_common < P : ContextParser > (
463
458
io : * const Mp4parseIo ,
464
- status_out : * mut Mp4parseStatus ,
465
- ) -> * mut P {
459
+ parser_out : * mut * mut P ,
460
+ ) -> Mp4parseStatus {
466
461
// Validate arguments from C.
467
- if io. is_null ( ) || ( * io) . userdata . is_null ( ) || ( * io) . read . is_none ( ) || status_out. is_null ( ) {
468
- set_if_non_null ( status_out, Mp4parseStatus :: BadArg ) ;
469
- std:: ptr:: null_mut ( )
462
+ if io. is_null ( )
463
+ || ( * io) . userdata . is_null ( )
464
+ || ( * io) . read . is_none ( )
465
+ || parser_out. is_null ( )
466
+ || !( * parser_out) . is_null ( )
467
+ {
468
+ Mp4parseStatus :: BadArg
470
469
} else {
471
470
match mp4parse_new_common_safe ( & mut ( * io) . clone ( ) ) {
472
471
Ok ( parser) => {
473
- set_if_non_null ( status_out, Mp4parseStatus :: Ok ) ;
474
- parser
475
- }
476
- Err ( status) => {
477
- set_if_non_null ( status_out, status) ;
478
- std:: ptr:: null_mut ( )
472
+ * parser_out = parser;
473
+ Mp4parseStatus :: Ok
479
474
}
475
+ Err ( status) => status,
480
476
}
481
477
}
482
478
}
483
479
484
- unsafe fn set_if_non_null < T > ( ptr : * mut T , val : T ) {
485
- if !ptr. is_null ( ) {
486
- * ptr = val;
487
- }
488
- }
489
-
490
480
fn mp4parse_new_common_safe < T : Read , P : ContextParser > (
491
481
io : & mut T ,
492
482
) -> Result < * mut P , Mp4parseStatus > {
@@ -1618,12 +1608,12 @@ fn get_track_count_null_parser() {
1618
1608
#[ test]
1619
1609
fn arg_validation ( ) {
1620
1610
unsafe {
1621
- let parser = mp4parse_new ( std:: ptr:: null ( ) , std:: ptr:: null_mut ( ) ) ;
1622
- assert ! ( parser . is_null ( ) ) ;
1611
+ let rv = mp4parse_new ( std:: ptr:: null ( ) , std:: ptr:: null_mut ( ) ) ;
1612
+ assert_eq ! ( rv , Mp4parseStatus :: BadArg ) ;
1623
1613
1624
1614
// Passing a null Mp4parseIo is an error.
1625
- let mut rv = Mp4parseStatus :: Invalid ;
1626
- let parser = mp4parse_new ( std:: ptr:: null ( ) , & mut rv ) ;
1615
+ let mut parser = std :: ptr :: null_mut ( ) ;
1616
+ let rv = mp4parse_new ( std:: ptr:: null ( ) , & mut parser ) ;
1627
1617
assert_eq ! ( rv, Mp4parseStatus :: BadArg ) ;
1628
1618
assert ! ( parser. is_null( ) ) ;
1629
1619
@@ -1634,8 +1624,8 @@ fn arg_validation() {
1634
1624
read : None ,
1635
1625
userdata : null_mut,
1636
1626
} ;
1637
- let mut rv = Mp4parseStatus :: Invalid ;
1638
- let parser = mp4parse_new ( & io, & mut rv ) ;
1627
+ let mut parser = std :: ptr :: null_mut ( ) ;
1628
+ let rv = mp4parse_new ( & io, & mut parser ) ;
1639
1629
assert_eq ! ( rv, Mp4parseStatus :: BadArg ) ;
1640
1630
assert ! ( parser. is_null( ) ) ;
1641
1631
@@ -1644,8 +1634,8 @@ fn arg_validation() {
1644
1634
read : None ,
1645
1635
userdata : & mut dummy_value as * mut _ as * mut std:: os:: raw:: c_void ,
1646
1636
} ;
1647
- let mut rv = Mp4parseStatus :: Invalid ;
1648
- let parser = mp4parse_new ( & io, & mut rv ) ;
1637
+ let mut parser = std :: ptr :: null_mut ( ) ;
1638
+ let rv = mp4parse_new ( & io, & mut parser ) ;
1649
1639
assert_eq ! ( rv, Mp4parseStatus :: BadArg ) ;
1650
1640
assert ! ( parser. is_null( ) ) ;
1651
1641
@@ -1680,6 +1670,18 @@ fn arg_validation() {
1680
1670
}
1681
1671
}
1682
1672
1673
+ #[ test]
1674
+ fn parser_input_must_be_null ( ) {
1675
+ let mut dummy_value = 42 ;
1676
+ let io = Mp4parseIo {
1677
+ read : Some ( error_read) ,
1678
+ userdata : & mut dummy_value as * mut _ as * mut std:: os:: raw:: c_void ,
1679
+ } ;
1680
+ let mut parser = 0xDEADBEEF as * mut _ ;
1681
+ let rv = unsafe { mp4parse_new ( & io, & mut parser) } ;
1682
+ assert_eq ! ( rv, Mp4parseStatus :: BadArg ) ;
1683
+ }
1684
+
1683
1685
#[ test]
1684
1686
fn arg_validation_with_parser ( ) {
1685
1687
unsafe {
@@ -1688,8 +1690,8 @@ fn arg_validation_with_parser() {
1688
1690
read : Some ( error_read) ,
1689
1691
userdata : & mut dummy_value as * mut _ as * mut std:: os:: raw:: c_void ,
1690
1692
} ;
1691
- let mut rv = Mp4parseStatus :: Invalid ;
1692
- let parser = mp4parse_new ( & io, & mut rv ) ;
1693
+ let mut parser = std :: ptr :: null_mut ( ) ;
1694
+ let rv = mp4parse_new ( & io, & mut parser ) ;
1693
1695
assert_eq ! ( rv, Mp4parseStatus :: Io ) ;
1694
1696
assert ! ( parser. is_null( ) ) ;
1695
1697
@@ -1738,35 +1740,15 @@ fn arg_validation_with_parser() {
1738
1740
}
1739
1741
}
1740
1742
1741
- #[ test]
1742
- fn get_track_count_poisoned_parser ( ) {
1743
- unsafe {
1744
- let mut dummy_value = 42 ;
1745
- let io = Mp4parseIo {
1746
- read : Some ( error_read) ,
1747
- userdata : & mut dummy_value as * mut _ as * mut std:: os:: raw:: c_void ,
1748
- } ;
1749
- let mut rv = Mp4parseStatus :: Invalid ;
1750
- let parser = mp4parse_new ( & io, & mut rv) ;
1751
- assert_eq ! ( rv, Mp4parseStatus :: Io ) ;
1752
- assert ! ( parser. is_null( ) ) ;
1753
-
1754
- let mut count: u32 = 0 ;
1755
- let rv = mp4parse_get_track_count ( parser, & mut count) ;
1756
- assert_eq ! ( rv, Mp4parseStatus :: BadArg ) ;
1757
- }
1758
- }
1759
-
1760
1743
#[ cfg( test) ]
1761
1744
fn parse_minimal_mp4 ( ) -> * mut Mp4parseParser {
1762
1745
let mut file = std:: fs:: File :: open ( "../mp4parse/tests/minimal.mp4" ) . unwrap ( ) ;
1763
1746
let io = Mp4parseIo {
1764
1747
read : Some ( valid_read) ,
1765
1748
userdata : & mut file as * mut _ as * mut std:: os:: raw:: c_void ,
1766
1749
} ;
1767
- let mut rv = Mp4parseStatus :: Invalid ;
1768
- let parser;
1769
- unsafe { parser = mp4parse_new ( & io, & mut rv) }
1750
+ let mut parser = std:: ptr:: null_mut ( ) ;
1751
+ let rv = unsafe { mp4parse_new ( & io, & mut parser) } ;
1770
1752
assert_eq ! ( Mp4parseStatus :: Ok , rv) ;
1771
1753
parser
1772
1754
}
0 commit comments