Skip to content

Commit 3673b1d

Browse files
niklasfaleksusszaidoon1
committed
Fix unsoundness via impure AsRef (#705)
* Fix unsoundness via impure AsRef --------- Co-authored-by: Oleksandr Anyshchenko <[email protected]> Co-authored-by: Zaidoon Abd Al Hadi <[email protected]>
1 parent 4777551 commit 3673b1d

File tree

4 files changed

+128
-56
lines changed

4 files changed

+128
-56
lines changed

src/db.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,10 @@ impl<T: ThreadMode, D: DBInner> DBCommon<T, D> {
11041104
{
11051105
let (keys, keys_sizes): (Vec<Box<[u8]>>, Vec<_>) = keys
11061106
.into_iter()
1107-
.map(|k| (Box::from(k.as_ref()), k.as_ref().len()))
1107+
.map(|k| {
1108+
let k = k.as_ref();
1109+
(Box::from(k), k.len())
1110+
})
11081111
.unzip();
11091112
let ptr_keys: Vec<_> = keys.iter().map(|k| k.as_ptr() as *const c_char).collect();
11101113

@@ -1153,7 +1156,10 @@ impl<T: ThreadMode, D: DBInner> DBCommon<T, D> {
11531156
{
11541157
let (cfs_and_keys, keys_sizes): (Vec<(_, Box<[u8]>)>, Vec<_>) = keys
11551158
.into_iter()
1156-
.map(|(cf, key)| ((cf, Box::from(key.as_ref())), key.as_ref().len()))
1159+
.map(|(cf, key)| {
1160+
let key = key.as_ref();
1161+
((cf, Box::from(key)), key.len())
1162+
})
11571163
.unzip();
11581164
let ptr_keys: Vec<_> = cfs_and_keys
11591165
.iter()

src/transactions/transaction.rs

+50-30
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,13 @@ impl<'db, DB> Transaction<'db, DB> {
321321
key: K,
322322
readopts: &ReadOptions,
323323
) -> Result<Option<DBPinnableSlice>, Error> {
324+
let key = key.as_ref();
324325
unsafe {
325326
let val = ffi_try!(ffi::rocksdb_transaction_get_pinned(
326327
self.inner,
327328
readopts.inner,
328-
key.as_ref().as_ptr() as *const c_char,
329-
key.as_ref().len(),
329+
key.as_ptr() as *const c_char,
330+
key.len(),
330331
));
331332
if val.is_null() {
332333
Ok(None)
@@ -359,13 +360,14 @@ impl<'db, DB> Transaction<'db, DB> {
359360
key: K,
360361
readopts: &ReadOptions,
361362
) -> Result<Option<DBPinnableSlice>, Error> {
363+
let key = key.as_ref();
362364
unsafe {
363365
let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_cf(
364366
self.inner,
365367
readopts.inner,
366368
cf.inner(),
367-
key.as_ref().as_ptr() as *const c_char,
368-
key.as_ref().len(),
369+
key.as_ptr() as *const c_char,
370+
key.len(),
369371
));
370372
if val.is_null() {
371373
Ok(None)
@@ -399,12 +401,13 @@ impl<'db, DB> Transaction<'db, DB> {
399401
exclusive: bool,
400402
opts: &ReadOptions,
401403
) -> Result<Option<DBPinnableSlice>, Error> {
404+
let key = key.as_ref();
402405
unsafe {
403406
let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_for_update(
404407
self.inner,
405408
opts.inner,
406-
key.as_ref().as_ptr() as *const c_char,
407-
key.as_ref().len() as size_t,
409+
key.as_ptr() as *const c_char,
410+
key.len() as size_t,
408411
u8::from(exclusive),
409412
));
410413
if val.is_null() {
@@ -461,13 +464,14 @@ impl<'db, DB> Transaction<'db, DB> {
461464
exclusive: bool,
462465
opts: &ReadOptions,
463466
) -> Result<Option<DBPinnableSlice>, Error> {
467+
let key = key.as_ref();
464468
unsafe {
465469
let val = ffi_try!(ffi::rocksdb_transaction_get_pinned_for_update_cf(
466470
self.inner,
467471
opts.inner,
468472
cf.inner(),
469-
key.as_ref().as_ptr() as *const c_char,
470-
key.as_ref().len() as size_t,
473+
key.as_ptr() as *const c_char,
474+
key.len() as size_t,
471475
u8::from(exclusive),
472476
));
473477
if val.is_null() {
@@ -499,7 +503,10 @@ impl<'db, DB> Transaction<'db, DB> {
499503
{
500504
let (keys, keys_sizes): (Vec<Box<[u8]>>, Vec<_>) = keys
501505
.into_iter()
502-
.map(|k| (Box::from(k.as_ref()), k.as_ref().len()))
506+
.map(|key| {
507+
let key = key.as_ref();
508+
(Box::from(key), key.len())
509+
})
503510
.unzip();
504511
let ptr_keys: Vec<_> = keys.iter().map(|k| k.as_ptr() as *const c_char).collect();
505512

@@ -548,7 +555,10 @@ impl<'db, DB> Transaction<'db, DB> {
548555
{
549556
let (cfs_and_keys, keys_sizes): (Vec<(_, Box<[u8]>)>, Vec<_>) = keys
550557
.into_iter()
551-
.map(|(cf, key)| ((cf, Box::from(key.as_ref())), key.as_ref().len()))
558+
.map(|(cf, key)| {
559+
let key = key.as_ref();
560+
((cf, Box::from(key)), key.len())
561+
})
552562
.unzip();
553563
let ptr_keys: Vec<_> = cfs_and_keys
554564
.iter()
@@ -585,13 +595,15 @@ impl<'db, DB> Transaction<'db, DB> {
585595
///
586596
/// [`put_cf`]: Self::put_cf
587597
pub fn put<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) -> Result<(), Error> {
598+
let key = key.as_ref();
599+
let value = value.as_ref();
588600
unsafe {
589601
ffi_try!(ffi::rocksdb_transaction_put(
590602
self.inner,
591-
key.as_ref().as_ptr() as *const c_char,
592-
key.as_ref().len() as size_t,
593-
value.as_ref().as_ptr() as *const c_char,
594-
value.as_ref().len() as size_t,
603+
key.as_ptr() as *const c_char,
604+
key.len() as size_t,
605+
value.as_ptr() as *const c_char,
606+
value.len() as size_t,
595607
));
596608
Ok(())
597609
}
@@ -618,14 +630,16 @@ impl<'db, DB> Transaction<'db, DB> {
618630
key: K,
619631
value: V,
620632
) -> Result<(), Error> {
633+
let key = key.as_ref();
634+
let value = value.as_ref();
621635
unsafe {
622636
ffi_try!(ffi::rocksdb_transaction_put_cf(
623637
self.inner,
624638
cf.inner(),
625-
key.as_ref().as_ptr() as *const c_char,
626-
key.as_ref().len() as size_t,
627-
value.as_ref().as_ptr() as *const c_char,
628-
value.as_ref().len() as size_t,
639+
key.as_ptr() as *const c_char,
640+
key.len() as size_t,
641+
value.as_ptr() as *const c_char,
642+
value.len() as size_t,
629643
));
630644
Ok(())
631645
}
@@ -637,13 +651,15 @@ impl<'db, DB> Transaction<'db, DB> {
637651
///
638652
/// [`merge_cf`]: Self::merge_cf
639653
pub fn merge<K: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, value: V) -> Result<(), Error> {
654+
let key = key.as_ref();
655+
let value = value.as_ref();
640656
unsafe {
641657
ffi_try!(ffi::rocksdb_transaction_merge(
642658
self.inner,
643-
key.as_ref().as_ptr() as *const c_char,
644-
key.as_ref().len() as size_t,
645-
value.as_ref().as_ptr() as *const c_char,
646-
value.as_ref().len() as size_t
659+
key.as_ptr() as *const c_char,
660+
key.len() as size_t,
661+
value.as_ptr() as *const c_char,
662+
value.len() as size_t
647663
));
648664
Ok(())
649665
}
@@ -670,14 +686,16 @@ impl<'db, DB> Transaction<'db, DB> {
670686
key: K,
671687
value: V,
672688
) -> Result<(), Error> {
689+
let key = key.as_ref();
690+
let value = value.as_ref();
673691
unsafe {
674692
ffi_try!(ffi::rocksdb_transaction_merge_cf(
675693
self.inner,
676694
cf.inner(),
677-
key.as_ref().as_ptr() as *const c_char,
678-
key.as_ref().len() as size_t,
679-
value.as_ref().as_ptr() as *const c_char,
680-
value.as_ref().len() as size_t
695+
key.as_ptr() as *const c_char,
696+
key.len() as size_t,
697+
value.as_ptr() as *const c_char,
698+
value.len() as size_t
681699
));
682700
Ok(())
683701
}
@@ -689,11 +707,12 @@ impl<'db, DB> Transaction<'db, DB> {
689707
///
690708
/// [`delete_cf`]: Self::delete_cf
691709
pub fn delete<K: AsRef<[u8]>>(&self, key: K) -> Result<(), Error> {
710+
let key = key.as_ref();
692711
unsafe {
693712
ffi_try!(ffi::rocksdb_transaction_delete(
694713
self.inner,
695-
key.as_ref().as_ptr() as *const c_char,
696-
key.as_ref().len() as size_t
714+
key.as_ptr() as *const c_char,
715+
key.len() as size_t
697716
));
698717
}
699718
Ok(())
@@ -718,12 +737,13 @@ impl<'db, DB> Transaction<'db, DB> {
718737
cf: &impl AsColumnFamilyRef,
719738
key: K,
720739
) -> Result<(), Error> {
740+
let key = key.as_ref();
721741
unsafe {
722742
ffi_try!(ffi::rocksdb_transaction_delete_cf(
723743
self.inner,
724744
cf.inner(),
725-
key.as_ref().as_ptr() as *const c_char,
726-
key.as_ref().len() as size_t
745+
key.as_ptr() as *const c_char,
746+
key.len() as size_t
727747
));
728748
}
729749
Ok(())

src/transactions/transaction_db.rs

+41-24
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,14 @@ impl<T: ThreadMode> TransactionDB<T> {
509509
key: K,
510510
readopts: &ReadOptions,
511511
) -> Result<Option<DBPinnableSlice>, Error> {
512+
let key = key.as_ref();
512513
unsafe {
513514
let val = ffi_try!(ffi::rocksdb_transactiondb_get_pinned_cf(
514515
self.inner,
515516
readopts.inner,
516517
cf.inner(),
517-
key.as_ref().as_ptr() as *const c_char,
518-
key.as_ref().len() as size_t,
518+
key.as_ptr() as *const c_char,
519+
key.len() as size_t,
519520
));
520521
if val.is_null() {
521522
Ok(None)
@@ -546,7 +547,10 @@ impl<T: ThreadMode> TransactionDB<T> {
546547
{
547548
let (keys, keys_sizes): (Vec<Box<[u8]>>, Vec<_>) = keys
548549
.into_iter()
549-
.map(|k| (Box::from(k.as_ref()), k.as_ref().len()))
550+
.map(|key| {
551+
let key = key.as_ref();
552+
(Box::from(key), key.len())
553+
})
550554
.unzip();
551555
let ptr_keys: Vec<_> = keys.iter().map(|k| k.as_ptr() as *const c_char).collect();
552556

@@ -595,7 +599,10 @@ impl<T: ThreadMode> TransactionDB<T> {
595599
{
596600
let (cfs_and_keys, keys_sizes): (Vec<(_, Box<[u8]>)>, Vec<_>) = keys
597601
.into_iter()
598-
.map(|(cf, key)| ((cf, Box::from(key.as_ref())), key.as_ref().len()))
602+
.map(|(cf, key)| {
603+
let key = key.as_ref();
604+
((cf, Box::from(key)), key.len())
605+
})
599606
.unzip();
600607
let ptr_keys: Vec<_> = cfs_and_keys
601608
.iter()
@@ -647,14 +654,16 @@ impl<T: ThreadMode> TransactionDB<T> {
647654
K: AsRef<[u8]>,
648655
V: AsRef<[u8]>,
649656
{
657+
let key = key.as_ref();
658+
let value = value.as_ref();
650659
unsafe {
651660
ffi_try!(ffi::rocksdb_transactiondb_put(
652661
self.inner,
653662
writeopts.inner,
654-
key.as_ref().as_ptr() as *const c_char,
655-
key.as_ref().len() as size_t,
656-
value.as_ref().as_ptr() as *const c_char,
657-
value.as_ref().len() as size_t
663+
key.as_ptr() as *const c_char,
664+
key.len() as size_t,
665+
value.as_ptr() as *const c_char,
666+
value.len() as size_t
658667
));
659668
}
660669
Ok(())
@@ -671,15 +680,17 @@ impl<T: ThreadMode> TransactionDB<T> {
671680
K: AsRef<[u8]>,
672681
V: AsRef<[u8]>,
673682
{
683+
let key = key.as_ref();
684+
let value = value.as_ref();
674685
unsafe {
675686
ffi_try!(ffi::rocksdb_transactiondb_put_cf(
676687
self.inner,
677688
writeopts.inner,
678689
cf.inner(),
679-
key.as_ref().as_ptr() as *const c_char,
680-
key.as_ref().len() as size_t,
681-
value.as_ref().as_ptr() as *const c_char,
682-
value.as_ref().len() as size_t
690+
key.as_ptr() as *const c_char,
691+
key.len() as size_t,
692+
value.as_ptr() as *const c_char,
693+
value.len() as size_t
683694
));
684695
}
685696
Ok(())
@@ -725,14 +736,16 @@ impl<T: ThreadMode> TransactionDB<T> {
725736
K: AsRef<[u8]>,
726737
V: AsRef<[u8]>,
727738
{
739+
let key = key.as_ref();
740+
let value = value.as_ref();
728741
unsafe {
729742
ffi_try!(ffi::rocksdb_transactiondb_merge(
730743
self.inner,
731744
writeopts.inner,
732-
key.as_ref().as_ptr() as *const c_char,
733-
key.as_ref().len() as size_t,
734-
value.as_ref().as_ptr() as *const c_char,
735-
value.as_ref().len() as size_t,
745+
key.as_ptr() as *const c_char,
746+
key.len() as size_t,
747+
value.as_ptr() as *const c_char,
748+
value.len() as size_t,
736749
));
737750
Ok(())
738751
}
@@ -749,15 +762,17 @@ impl<T: ThreadMode> TransactionDB<T> {
749762
K: AsRef<[u8]>,
750763
V: AsRef<[u8]>,
751764
{
765+
let key = key.as_ref();
766+
let value = value.as_ref();
752767
unsafe {
753768
ffi_try!(ffi::rocksdb_transactiondb_merge_cf(
754769
self.inner,
755770
writeopts.inner,
756771
cf.inner(),
757-
key.as_ref().as_ptr() as *const c_char,
758-
key.as_ref().len() as size_t,
759-
value.as_ref().as_ptr() as *const c_char,
760-
value.as_ref().len() as size_t,
772+
key.as_ptr() as *const c_char,
773+
key.len() as size_t,
774+
value.as_ptr() as *const c_char,
775+
value.len() as size_t,
761776
));
762777
Ok(())
763778
}
@@ -780,12 +795,13 @@ impl<T: ThreadMode> TransactionDB<T> {
780795
key: K,
781796
writeopts: &WriteOptions,
782797
) -> Result<(), Error> {
798+
let key = key.as_ref();
783799
unsafe {
784800
ffi_try!(ffi::rocksdb_transactiondb_delete(
785801
self.inner,
786802
writeopts.inner,
787-
key.as_ref().as_ptr() as *const c_char,
788-
key.as_ref().len() as size_t,
803+
key.as_ptr() as *const c_char,
804+
key.len() as size_t,
789805
));
790806
}
791807
Ok(())
@@ -797,13 +813,14 @@ impl<T: ThreadMode> TransactionDB<T> {
797813
key: K,
798814
writeopts: &WriteOptions,
799815
) -> Result<(), Error> {
816+
let key = key.as_ref();
800817
unsafe {
801818
ffi_try!(ffi::rocksdb_transactiondb_delete_cf(
802819
self.inner,
803820
writeopts.inner,
804821
cf.inner(),
805-
key.as_ref().as_ptr() as *const c_char,
806-
key.as_ref().len() as size_t,
822+
key.as_ptr() as *const c_char,
823+
key.len() as size_t,
807824
));
808825
}
809826
Ok(())

0 commit comments

Comments
 (0)