{"record":{"id":"8c3ed73a362813ab","repo":"sxyazi/yazi","slug":"cannot-take-a-null-pointer","errorCode":null,"errorMessage":"Cannot take a null pointer","messagePattern":"Cannot take a null pointer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-ffi/src/cf_dict.rs","lineNumber":14,"sourceCode":"use std::{ffi::{CStr, OsStr, OsString, c_char, c_void}, mem::ManuallyDrop, os::unix::ffi::OsStrExt, path::PathBuf};\n\nuse anyhow::{Result, bail};\nuse core_foundation_sys::{base::{CFRelease, TCFTypeRef}, dictionary::{CFDictionaryGetValueIfPresent, CFDictionaryRef}, string::CFStringRef};\nuse objc2::{msg_send, runtime::AnyObject};\n\nuse super::cf_string::CFString;\n\npub struct CFDict(CFDictionaryRef);\n\nimpl CFDict {\n\tpub fn take(dict: CFDictionaryRef) -> Result<Self> {\n\t\tif dict.is_null() {\n\t\t\tbail!(\"Cannot take a null pointer\");\n\t\t}\n\t\tOk(Self(dict))\n\t}\n\n\tfn value(&self, key: &str) -> Result<*const c_void> {\n\t\tlet key_ = CFString::new(key)?;\n\t\tlet mut value = std::ptr::null();\n\t\tif unsafe { CFDictionaryGetValueIfPresent(self.0, key_.as_void_ptr(), &mut value) } == 0\n\t\t\t|| value.is_null()\n\t\t{\n\t\t\tbail!(\"Cannot get the value for the key `{key}`\");\n\t\t}\n\t\tOk(value)\n\t}\n\n\tpub fn bool(&self, key: &str) -> Result<bool> {\n\t\tlet value = self.value(key)?;\n\t\t#[allow(unexpected_cfgs)]","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-ffi/src/cf_dict.rs#L1-L32","documentation":"CFDict::take (yazi-ffi/src/cf_dict.rs:14) wraps a CoreFoundation CFDictionaryRef. A null CFDictionaryRef is not a valid dictionary (it indicates the caller's lookup, e.g. a Launch Services or plist copy, failed), so `take` refuses to wrap it and bails to prevent later null dereferences.","triggerScenarios":"Calling `CFDict::take` with a null `CFDictionaryRef` — typically the result of a failed CF API call such as `CFBundleCopyInfoDictionaryForURL`, `LSCopyApplicationURLsForBundleIdentifier`, or a macOS system API that returns NULL on failure.","commonSituations":"Reading metadata of a nonexistent or uninstalled macOS application/bundle, a file without an Info.plist, or not checking the null return of the upstream CF function before wrapping it.","solutions":["Check the underlying CF API's return value/error before calling take; handle the null case as 'metadata not available'.","Verify the target file/bundle exists and is a valid macOS application or plist source.","Catch this Result and fall back to defaults instead of propagating, since missing CF metadata is usually non-fatal."],"exampleFix":"// before\nlet dict = CFDict::take(unsafe { LSCopyApplicationURLsForBundleId(id, null_mut()) })?;\n// after\nmatch unsafe { LSCopyApplicationURLsForBundleId(id, null_mut()) } {\n    p if !p.is_null() => CFDict::take(p)?,\n    _ => return Ok(Default::default()), // app not installed; no metadata\n}","handlingStrategy":"type-guard","validationCode":"// macOS: check the CF call succeeded before wrapping\nlet dict_ref = unsafe { CFBundleCopyInfoDictionaryForURL(url) };\nif dict_ref.is_null() {\n    return Ok(Default::default()); // no metadata, not an error\n}\nlet dict = CFDict::take(dict_ref)?;","typeGuard":"fn is_valid_dict(p: CFDictionaryRef) -> bool {\n    !p.is_null()\n}","tryCatchPattern":"match CFDict::take(raw) {\n    Ok(dict) => use(dict),\n    Err(_) => use_defaults(), // null CFDictionaryRef == metadata unavailable\n}","preventionTips":["Always null-check CF returns (they signal failure with NULL, not an error code) before wrapping.","Verify the bundle/file exists before querying its metadata.","Treat missing CF metadata as a default-value case, not a hard failure."],"tags":["macos","core-foundation","null-pointer","ffi"],"backgroundTag":"null-pointer-from-c-api","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}