Skip to content

Commit d2ee2df

Browse files
authored
cargo-credential-libsecret: give FFI correctly-sized object (#15767)
### What does this PR try to resolve? The type is ```c typedef struct { const gchar *name; SecretSchemaFlags flags; SecretSchemaAttribute attributes[32]; /* <private> */ gint reserved; gpointer reserved1; gpointer reserved2; gpointer reserved3; gpointer reserved4; gpointer reserved5; gpointer reserved6; gpointer reserved7; } SecretSchema; ``` so the current object we give it is 8 pointers too short It's incredibly lucky that libsecret, at this time, only uses `reserved`, and not in any of the functions we call Also, some obvious cleanups while I was there and comparing with [my implementation](https://github.com/nabijaczleweli/cargo-update/blob/v17.0.0/src/ops/mod.rs#L1443) from [cargo-update 17.0.0](https://github.com/nabijaczleweli/cargo-update/releases/v17.0.0). ### How to test and review this PR? Observe https://sources.debian.org/src/libsecret/0.20.5-3/libsecret/secret-schema.h/#L43 I suppose?
2 parents 5b295b7 + ed85b79 commit d2ee2df

File tree

1 file changed

+61
-47
lines changed
  • credential/cargo-credential-libsecret/src

1 file changed

+61
-47
lines changed

credential/cargo-credential-libsecret/src/lib.rs

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ mod linux {
2222
#[allow(non_camel_case_types)]
2323
type gboolean = c_int;
2424

25+
#[allow(non_camel_case_types)]
26+
type gint = c_int;
27+
28+
#[allow(non_camel_case_types)]
29+
type gpointer = *mut ();
30+
2531
type GQuark = u32;
2632

2733
#[repr(C)]
@@ -41,6 +47,14 @@ mod linux {
4147
name: *const gchar,
4248
flags: SecretSchemaFlags,
4349
attributes: [SecretSchemaAttribute; 32],
50+
reserved: gint,
51+
reserved1: gpointer,
52+
reserved2: gpointer,
53+
reserved3: gpointer,
54+
reserved4: gpointer,
55+
reserved5: gpointer,
56+
reserved6: gpointer,
57+
reserved7: gpointer,
4458
}
4559

4660
#[repr(C)]
@@ -97,13 +111,21 @@ mod linux {
97111
attr_type: SecretSchemaAttributeType::String,
98112
}; 32];
99113
attributes[0] = SecretSchemaAttribute {
100-
name: b"url\0".as_ptr() as *const gchar,
114+
name: c"url".as_ptr() as *const gchar,
101115
attr_type: SecretSchemaAttributeType::String,
102116
};
103117
SecretSchema {
104-
name: b"org.rust-lang.cargo.registry\0".as_ptr() as *const gchar,
118+
name: c"org.rust-lang.cargo.registry".as_ptr() as *const gchar,
105119
flags: SecretSchemaFlags::None,
106120
attributes,
121+
reserved: 0,
122+
reserved1: null_mut(),
123+
reserved2: null_mut(),
124+
reserved3: null_mut(),
125+
reserved4: null_mut(),
126+
reserved5: null_mut(),
127+
reserved6: null_mut(),
128+
reserved7: null_mut(),
107129
}
108130
}
109131

@@ -145,60 +167,55 @@ mod linux {
145167
}
146168

147169
let index_url_c = CString::new(registry.index_url).unwrap();
170+
let mut error: *mut GError = null_mut();
171+
let attr_url = c"url".as_ptr() as *const gchar;
172+
let schema = schema();
148173
match action {
149-
cargo_credential::Action::Get(_) => {
150-
let mut error: *mut GError = null_mut();
151-
let attr_url = CString::new("url").unwrap();
152-
let schema = schema();
153-
unsafe {
154-
let token_c = secret_password_lookup_sync(
155-
&schema,
156-
null_mut(),
157-
&mut error,
158-
attr_url.as_ptr(),
159-
index_url_c.as_ptr(),
160-
null() as *const gchar,
161-
);
162-
if !error.is_null() {
163-
return Err(format!(
164-
"failed to get token: {}",
165-
CStr::from_ptr((*error).message)
166-
.to_str()
167-
.unwrap_or_default()
168-
)
169-
.into());
170-
}
171-
if token_c.is_null() {
172-
return Err(Error::NotFound);
173-
}
174-
let token = Secret::from(
175-
CStr::from_ptr(token_c)
174+
cargo_credential::Action::Get(_) => unsafe {
175+
let token_c = secret_password_lookup_sync(
176+
&schema,
177+
null_mut(),
178+
&mut error,
179+
attr_url,
180+
index_url_c.as_ptr(),
181+
null() as *const gchar,
182+
);
183+
if !error.is_null() {
184+
return Err(format!(
185+
"failed to get token: {}",
186+
CStr::from_ptr((*error).message)
176187
.to_str()
177-
.map_err(|e| format!("expected utf8 token: {}", e))?
178-
.to_string(),
179-
);
180-
Ok(CredentialResponse::Get {
181-
token,
182-
cache: CacheControl::Session,
183-
operation_independent: true,
184-
})
188+
.unwrap_or_default()
189+
)
190+
.into());
185191
}
186-
}
192+
if token_c.is_null() {
193+
return Err(Error::NotFound);
194+
}
195+
let token = Secret::from(
196+
CStr::from_ptr(token_c)
197+
.to_str()
198+
.map_err(|e| format!("expected utf8 token: {}", e))?
199+
.to_string(),
200+
);
201+
Ok(CredentialResponse::Get {
202+
token,
203+
cache: CacheControl::Session,
204+
operation_independent: true,
205+
})
206+
},
187207
cargo_credential::Action::Login(options) => {
188208
let label = label(registry.name.unwrap_or(registry.index_url));
189209
let token = CString::new(read_token(options, registry)?.expose()).unwrap();
190-
let mut error: *mut GError = null_mut();
191-
let attr_url = CString::new("url").unwrap();
192-
let schema = schema();
193210
unsafe {
194211
secret_password_store_sync(
195212
&schema,
196-
b"default\0".as_ptr() as *const gchar,
213+
c"default".as_ptr() as *const gchar,
197214
label.as_ptr(),
198215
token.as_ptr(),
199216
null_mut(),
200217
&mut error,
201-
attr_url.as_ptr(),
218+
attr_url,
202219
index_url_c.as_ptr(),
203220
null() as *const gchar,
204221
);
@@ -215,15 +232,12 @@ mod linux {
215232
Ok(CredentialResponse::Login)
216233
}
217234
cargo_credential::Action::Logout => {
218-
let schema = schema();
219-
let mut error: *mut GError = null_mut();
220-
let attr_url = CString::new("url").unwrap();
221235
unsafe {
222236
secret_password_clear_sync(
223237
&schema,
224238
null_mut(),
225239
&mut error,
226-
attr_url.as_ptr(),
240+
attr_url,
227241
index_url_c.as_ptr(),
228242
null() as *const gchar,
229243
);

0 commit comments

Comments
 (0)