comparison rust/hg-cpython/src/dirstate/dirstate_map.rs @ 43208:1ca3823aeefd

rust-cpython: add wrapper around decapsule_make_dirstate_tuple() There are a couple of safety issues. First, the returned function pointer must be unsafe. Second, its return value must be a raw pointer (i.e. python27_sys::PyObject), not a cpython::PyObject. The wrapper function will address these issues.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 13 Oct 2019 16:55:17 +0900
parents b3dda04e851b
children 478d0b1bf0c5
comparison
equal deleted inserted replaced
43207:4aa9f3a1c1df 43208:1ca3823aeefd
14 14
15 use cpython::{ 15 use cpython::{
16 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject, 16 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
17 PyResult, PyTuple, Python, PythonObject, ToPyObject, 17 PyResult, PyTuple, Python, PythonObject, ToPyObject,
18 }; 18 };
19 use libc::c_char;
20 19
21 use crate::{ 20 use crate::{
22 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, 21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
23 dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs}, 22 dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
24 ref_sharing::{PyLeakedRef, PySharedRefCell}, 23 ref_sharing::{PyLeakedRef, PySharedRefCell},
25 }; 24 };
26 use hg::{ 25 use hg::{
27 utils::hg_path::{HgPath, HgPathBuf}, 26 utils::hg_path::{HgPath, HgPathBuf},
28 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, 27 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
64 default: Option<PyObject> = None 63 default: Option<PyObject> = None
65 ) -> PyResult<Option<PyObject>> { 64 ) -> PyResult<Option<PyObject>> {
66 let key = key.extract::<PyBytes>(py)?; 65 let key = key.extract::<PyBytes>(py)?;
67 match self.inner(py).borrow().get(HgPath::new(key.data(py))) { 66 match self.inner(py).borrow().get(HgPath::new(key.data(py))) {
68 Some(entry) => { 67 Some(entry) => {
69 // Explicitly go through u8 first, then cast to 68 Ok(Some(make_dirstate_tuple(py, entry)?))
70 // platform-specific `c_char`.
71 let state: u8 = entry.state.into();
72 Ok(Some(decapsule_make_dirstate_tuple(py)?(
73 state as c_char,
74 entry.mode,
75 entry.size,
76 entry.mtime,
77 )))
78 }, 69 },
79 None => Ok(default) 70 None => Ok(default)
80 } 71 }
81 } 72 }
82 73
301 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> { 292 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
302 let key = key.extract::<PyBytes>(py)?; 293 let key = key.extract::<PyBytes>(py)?;
303 let key = HgPath::new(key.data(py)); 294 let key = HgPath::new(key.data(py));
304 match self.inner(py).borrow().get(key) { 295 match self.inner(py).borrow().get(key) {
305 Some(entry) => { 296 Some(entry) => {
306 // Explicitly go through u8 first, then cast to 297 Ok(make_dirstate_tuple(py, entry)?)
307 // platform-specific `c_char`.
308 let state: u8 = entry.state.into();
309 Ok(decapsule_make_dirstate_tuple(py)?(
310 state as c_char,
311 entry.mode,
312 entry.size,
313 entry.mtime,
314 ))
315 }, 298 },
316 None => Err(PyErr::new::<exc::KeyError, _>( 299 None => Err(PyErr::new::<exc::KeyError, _>(
317 py, 300 py,
318 String::from_utf8_lossy(key.as_bytes()), 301 String::from_utf8_lossy(key.as_bytes()),
319 )), 302 )),
491 fn translate_key_value( 474 fn translate_key_value(
492 py: Python, 475 py: Python,
493 res: (&HgPathBuf, &DirstateEntry), 476 res: (&HgPathBuf, &DirstateEntry),
494 ) -> PyResult<Option<(PyBytes, PyObject)>> { 477 ) -> PyResult<Option<(PyBytes, PyObject)>> {
495 let (f, entry) = res; 478 let (f, entry) = res;
496
497 // Explicitly go through u8 first, then cast to
498 // platform-specific `c_char`.
499 let state: u8 = entry.state.into();
500 Ok(Some(( 479 Ok(Some((
501 PyBytes::new(py, f.as_ref()), 480 PyBytes::new(py, f.as_ref()),
502 decapsule_make_dirstate_tuple(py)?( 481 make_dirstate_tuple(py, entry)?,
503 state as c_char,
504 entry.mode,
505 entry.size,
506 entry.mtime,
507 ),
508 ))) 482 )))
509 } 483 }
510 } 484 }
511 485
512 py_shared_ref!(DirstateMap, RustDirstateMap, inner, inner_shared); 486 py_shared_ref!(DirstateMap, RustDirstateMap, inner, inner_shared);