From 61454c6d4017412f2c826efc45a746977137b6ee Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 10 May 2022 19:05:10 -0700 Subject: [PATCH 1/9] Fix copy-paste issue ("Commit" -> "Tree") --- src/tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tree.rs b/src/tree.rs index 3d6b290c52..6fe72d8192 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -199,7 +199,7 @@ impl<'repo> Tree<'repo> { unsafe { &*(self as *const _ as *const Object<'repo>) } } - /// Consumes Commit to be returned as an `Object` + /// Consumes this Tree to be returned as an `Object` pub fn into_object(self) -> Object<'repo> { assert_eq!(mem::size_of_val(&self), mem::size_of::>()); unsafe { mem::transmute(self) } From fe7188586a58eb5b8beacfb14eedf1d511afabf3 Mon Sep 17 00:00:00 2001 From: Adam Szkoda Date: Tue, 31 May 2022 16:33:55 +0200 Subject: [PATCH 2/9] Add a binding for tag_annotation_create() (#845) --- src/repo.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/repo.rs b/src/repo.rs index 92fa948305..3aeac2f1f5 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1818,6 +1818,38 @@ impl Repository { } } + /// Create a new tag in the repository from an object without creating a reference. + /// + /// The message will not be cleaned up. + /// + /// The tag name will be checked for validity. You must avoid the characters + /// '~', '^', ':', ' \ ', '?', '[', and '*', and the sequences ".." and " @ + /// {" which have special meaning to revparse. + pub fn tag_annotation_create( + &self, + name: &str, + target: &Object<'_>, + tagger: &Signature<'_>, + message: &str, + ) -> Result { + let name = CString::new(name)?; + let message = CString::new(message)?; + let mut raw_oid = raw::git_oid { + id: [0; raw::GIT_OID_RAWSZ], + }; + unsafe { + try_call!(raw::git_tag_annotation_create( + &mut raw_oid, + self.raw, + name, + target.raw(), + tagger.raw(), + message + )); + Ok(Binding::from_raw(&raw_oid as *const _)) + } + } + /// Create a new lightweight tag pointing at a target object /// /// A new direct reference will be created pointing to this target object. From fe55127a9f0fcf00b0fd9dc5611e373c5a2d18c3 Mon Sep 17 00:00:00 2001 From: koenw Date: Wed, 1 Jun 2022 16:06:08 +0200 Subject: [PATCH 3/9] Fix typo in PushOptions docs (#846) --- src/remote.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/remote.rs b/src/remote.rs index 4db06e7e11..d2a73858f7 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -608,13 +608,13 @@ impl<'cb> PushOptions<'cb> { } } - /// Set the callbacks to use for the fetch operation. + /// Set the callbacks to use for the push operation. pub fn remote_callbacks(&mut self, cbs: RemoteCallbacks<'cb>) -> &mut Self { self.callbacks = Some(cbs); self } - /// Set the proxy options to use for the fetch operation. + /// Set the proxy options to use for the push operation. pub fn proxy_options(&mut self, opts: ProxyOptions<'cb>) -> &mut Self { self.proxy = Some(opts); self From d5a56e9be2b3d708748946ca0b9dfba00835eac0 Mon Sep 17 00:00:00 2001 From: Volodymyr Fialko Date: Mon, 13 Jun 2022 15:39:29 +0200 Subject: [PATCH 4/9] Add bindings for git email create (#847) Add bindings for `git_email_create_from_diff()` and `git_email_create_from_commit()`. Deprecate `git_diff_format_email()` to reflect upstream changes. --- libgit2-sys/lib.rs | 41 ++++++++++ src/diff.rs | 9 +++ src/email.rs | 183 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + 4 files changed, 235 insertions(+) create mode 100644 src/email.rs diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 259d5e8df1..d5150ffa45 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -1992,6 +1992,28 @@ pub struct git_message_trailer_array { pub _trailer_block: *mut c_char, } +#[repr(C)] +pub struct git_email_create_options { + pub version: c_uint, + pub flags: u32, + pub diff_opts: git_diff_options, + pub diff_find_opts: git_diff_find_options, + pub subject_prefix: *const c_char, + pub start_number: usize, + pub reroll_number: usize, +} + +pub const GIT_EMAIL_CREATE_OPTIONS_VERSION: c_uint = 1; + +git_enum! { + pub enum git_email_create_flags_t { + GIT_EMAIL_CREATE_DEFAULT = 0, + GIT_EMAIL_CREATE_OMIT_NUMBERS = 1 << 0, + GIT_EMAIL_CREATE_ALWAYS_NUMBER = 1 << 1, + GIT_EMAIL_CREATE_NO_RENAMES = 1 << 2, + } +} + extern "C" { // threads pub fn git_libgit2_init() -> c_int; @@ -4106,6 +4128,25 @@ extern "C" { replace_email: *const c_char, ) -> c_int; + // email + pub fn git_email_create_from_diff( + out: *mut git_buf, + diff: *mut git_diff, + patch_idx: usize, + patch_count: usize, + commit_id: *const git_oid, + summary: *const c_char, + body: *const c_char, + author: *const git_signature, + given_opts: *const git_email_create_options, + ) -> c_int; + + pub fn git_email_create_from_commit( + out: *mut git_buf, + commit: *mut git_commit, + given_opts: *const git_email_create_options, + ) -> c_int; + pub fn git_trace_set(level: git_trace_level_t, cb: git_trace_cb) -> c_int; } diff --git a/src/diff.rs b/src/diff.rs index 0df6f85ea8..3d5b42d9dc 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -254,6 +254,8 @@ impl<'repo> Diff<'repo> { /// Create an e-mail ready patch from a diff. /// /// Matches the format created by `git format-patch` + #[doc(hidden)] + #[deprecated(note = "refactored to `Email::from_diff` to match upstream")] pub fn format_email( &mut self, patch_no: usize, @@ -277,6 +279,7 @@ impl<'repo> Diff<'repo> { raw_opts.body = message.as_ptr() as *const _; raw_opts.author = commit.author().raw(); let buf = Buf::new(); + #[allow(deprecated)] unsafe { try_call!(raw::git_diff_format_email(buf.raw(), self.raw, &*raw_opts)); } @@ -1480,6 +1483,11 @@ impl DiffFindOptions { } // TODO: expose git_diff_similarity_metric + + /// Acquire a pointer to the underlying raw options. + pub unsafe fn raw(&mut self) -> *const raw::git_diff_find_options { + &self.raw + } } impl Default for DiffFormatEmailOptions { @@ -1775,6 +1783,7 @@ mod tests { None, ) .unwrap(); + #[allow(deprecated)] let actual_email = diff.format_email(1, 1, &updated_commit, None).unwrap(); let actual_email = actual_email.as_str().unwrap(); assert!( diff --git a/src/email.rs b/src/email.rs new file mode 100644 index 0000000000..d3ebc03842 --- /dev/null +++ b/src/email.rs @@ -0,0 +1,183 @@ +use std::ffi::CString; +use std::{mem, ptr}; + +use crate::util::Binding; +use crate::{raw, Buf, Commit, DiffFindOptions, DiffOptions, Error, IntoCString}; +use crate::{Diff, Oid, Signature}; + +/// A structure to represent patch in mbox format for sending via email +pub struct Email { + buf: Buf, +} + +/// Options for controlling the formatting of the generated e-mail. +pub struct EmailCreateOptions { + diff_options: DiffOptions, + diff_find_options: DiffFindOptions, + subject_prefix: Option, + raw: raw::git_email_create_options, +} + +impl Default for EmailCreateOptions { + fn default() -> Self { + // Defaults options created in corresponding to `GIT_EMAIL_CREATE_OPTIONS_INIT` + let default_options = raw::git_email_create_options { + version: raw::GIT_EMAIL_CREATE_OPTIONS_VERSION, + flags: raw::GIT_EMAIL_CREATE_DEFAULT as u32, + diff_opts: unsafe { mem::zeroed() }, + diff_find_opts: unsafe { mem::zeroed() }, + subject_prefix: ptr::null(), + start_number: 1, + reroll_number: 0, + }; + let mut diff_options = DiffOptions::new(); + diff_options.show_binary(true).context_lines(3); + Self { + diff_options, + diff_find_options: DiffFindOptions::new(), + subject_prefix: None, + raw: default_options, + } + } +} + +impl EmailCreateOptions { + /// Creates a new set of email create options + /// + /// By default, options include rename detection and binary + /// diffs to match `git format-patch`. + pub fn new() -> Self { + Self::default() + } + + fn flag(&mut self, opt: raw::git_email_create_flags_t, val: bool) -> &mut Self { + let opt = opt as u32; + if val { + self.raw.flags |= opt; + } else { + self.raw.flags &= !opt; + } + self + } + + /// Flag indicating whether patch numbers are included in the subject prefix. + pub fn omit_numbers(&mut self, omit: bool) -> &mut Self { + self.flag(raw::GIT_EMAIL_CREATE_OMIT_NUMBERS, omit) + } + + /// Flag indicating whether numbers included in the subject prefix even when + /// the patch is for a single commit (1/1). + pub fn always_number(&mut self, always: bool) -> &mut Self { + self.flag(raw::GIT_EMAIL_CREATE_ALWAYS_NUMBER, always) + } + + /// Flag indicating whether rename or similarity detection are ignored. + pub fn ignore_renames(&mut self, ignore: bool) -> &mut Self { + self.flag(raw::GIT_EMAIL_CREATE_NO_RENAMES, ignore) + } + + /// Get mutable access to `DiffOptions` that are used for creating diffs. + pub fn diff_options(&mut self) -> &mut DiffOptions { + &mut self.diff_options + } + + /// Get mutable access to `DiffFindOptions` that are used for finding + /// similarities within diffs. + pub fn diff_find_options(&mut self) -> &mut DiffFindOptions { + &mut self.diff_find_options + } + + /// Set the subject prefix + /// + /// The default value for this is "PATCH". If set to an empty string ("") + /// then only the patch numbers will be shown in the prefix. + /// If the subject_prefix is empty and patch numbers are not being shown, + /// the prefix will be omitted entirely. + pub fn subject_prefix(&mut self, t: T) -> &mut Self { + self.subject_prefix = Some(t.into_c_string().unwrap()); + self + } + + /// Set the starting patch number; this cannot be 0. + /// + /// The default value for this is 1. + pub fn start_number(&mut self, number: usize) -> &mut Self { + self.raw.start_number = number; + self + } + + /// Set the "re-roll" number. + /// + /// The default value for this is 0 (no re-roll). + pub fn reroll_number(&mut self, number: usize) -> &mut Self { + self.raw.reroll_number = number; + self + } + + /// Acquire a pointer to the underlying raw options. + /// + /// This function is unsafe as the pointer is only valid so long as this + /// structure is not moved, modified, or used elsewhere. + unsafe fn raw(&mut self) -> *const raw::git_email_create_options { + self.raw.subject_prefix = self + .subject_prefix + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or(ptr::null()); + self.raw.diff_opts = ptr::read(self.diff_options.raw()); + self.raw.diff_find_opts = ptr::read(self.diff_find_options.raw()); + &self.raw as *const _ + } +} + +impl Email { + /// Returns a byte slice with stored e-mail patch in. `Email` could be + /// created by one of the `from_*` functions. + pub fn as_slice(&self) -> &[u8] { + &self.buf + } + + /// Create a diff for a commit in mbox format for sending via email. + pub fn from_diff( + diff: &Diff<'_>, + patch_idx: usize, + patch_count: usize, + commit_id: &Oid, + summary: T, + body: T, + author: &Signature<'_>, + opts: &mut EmailCreateOptions, + ) -> Result { + let buf = Buf::new(); + let summary = summary.into_c_string()?; + let body = body.into_c_string()?; + unsafe { + try_call!(raw::git_email_create_from_diff( + buf.raw(), + Binding::raw(diff), + patch_idx, + patch_count, + Binding::raw(commit_id), + summary.as_ptr(), + body.as_ptr(), + Binding::raw(author), + opts.raw() + )); + Ok(Self { buf }) + } + } + + /// Create a diff for a commit in mbox format for sending via email. + /// The commit must not be a merge commit. + pub fn from_commit(commit: &Commit<'_>, opts: &mut EmailCreateOptions) -> Result { + let buf = Buf::new(); + unsafe { + try_call!(raw::git_email_create_from_commit( + buf.raw(), + commit.raw(), + opts.raw() + )); + Ok(Self { buf }) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index cdc3648d83..a9ec38d20d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,6 +93,7 @@ pub use crate::describe::{Describe, DescribeFormatOptions, DescribeOptions}; pub use crate::diff::{Deltas, Diff, DiffDelta, DiffFile, DiffOptions}; pub use crate::diff::{DiffBinary, DiffBinaryFile, DiffBinaryKind}; pub use crate::diff::{DiffFindOptions, DiffHunk, DiffLine, DiffLineType, DiffStats}; +pub use crate::email::{Email, EmailCreateOptions}; pub use crate::error::Error; pub use crate::index::{ Index, IndexConflict, IndexConflicts, IndexEntries, IndexEntry, IndexMatchedPath, @@ -675,6 +676,7 @@ mod config; mod cred; mod describe; mod diff; +mod email; mod error; mod index; mod indexer; From 61f8afdd52e0168145dcc21b18d8824467d4d1c7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 7 Jul 2022 07:59:01 -0700 Subject: [PATCH 5/9] Use custom config entry iterator. (#854) --- src/config.rs | 111 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/src/config.rs b/src/config.rs index 573fa358b7..580af833ae 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,8 +23,39 @@ pub struct ConfigEntry<'cfg> { } /// An iterator over the `ConfigEntry` values of a `Config` structure. +/// +/// Due to lifetime restrictions, `ConfigEntries` does not implement the +/// standard [`Iterator`] trait. It provides a [`next`] function which only +/// allows access to one entry at a time. [`for_each`] is available as a +/// convenience function. +/// +/// [`next`]: ConfigEntries::next +/// [`for_each`]: ConfigEntries::for_each +/// +/// # Example +/// +/// ``` +/// // Example of how to collect all entries. +/// use git2::Config; +/// +/// let config = Config::new()?; +/// let iter = config.entries(None)?; +/// let mut entries = Vec::new(); +/// iter +/// .for_each(|entry| { +/// let name = entry.name().unwrap().to_string(); +/// let value = entry.value().unwrap_or("").to_string(); +/// entries.push((name, value)) +/// })?; +/// for entry in &entries { +/// println!("{} = {}", entry.0, entry.1); +/// } +/// # Ok::<(), git2::Error>(()) +/// +/// ``` pub struct ConfigEntries<'cfg> { raw: *mut raw::git_config_iterator, + current: Option>, _marker: marker::PhantomData<&'cfg Config>, } @@ -280,15 +311,18 @@ impl Config { /// the variable name: the section and variable parts are lower-cased. The /// subsection is left unchanged. /// + /// Due to lifetime restrictions, the returned value does not implement + /// the standard [`Iterator`] trait. See [`ConfigEntries`] for more. + /// /// # Example /// /// ``` - /// # #![allow(unstable)] /// use git2::Config; /// /// let cfg = Config::new().unwrap(); /// - /// for entry in &cfg.entries(None).unwrap() { + /// let mut entries = cfg.entries(None).unwrap(); + /// while let Some(entry) = entries.next() { /// let entry = entry.unwrap(); /// println!("{} => {}", entry.name().unwrap(), entry.value().unwrap()); /// } @@ -317,6 +351,9 @@ impl Config { /// The regular expression is applied case-sensitively on the normalized form of /// the variable name: the section and variable parts are lower-cased. The /// subsection is left unchanged. + /// + /// Due to lifetime restrictions, the returned value does not implement + /// the standard [`Iterator`] trait. See [`ConfigEntries`] for more. pub fn multivar(&self, name: &str, regexp: Option<&str>) -> Result, Error> { let mut ret = ptr::null_mut(); let name = CString::new(name)?; @@ -550,6 +587,7 @@ impl<'cfg> Binding for ConfigEntries<'cfg> { unsafe fn from_raw(raw: *mut raw::git_config_iterator) -> ConfigEntries<'cfg> { ConfigEntries { raw, + current: None, _marker: marker::PhantomData, } } @@ -558,24 +596,33 @@ impl<'cfg> Binding for ConfigEntries<'cfg> { } } -// entries are only valid until the iterator is freed, so this impl is for -// `&'b T` instead of `T` to have a lifetime to tie them to. -// -// It's also not implemented for `&'b mut T` so we can have multiple entries -// (ok). -impl<'cfg, 'b> Iterator for &'b ConfigEntries<'cfg> { - type Item = Result, Error>; - fn next(&mut self) -> Option, Error>> { +impl<'cfg> ConfigEntries<'cfg> { + /// Advances the iterator and returns the next value. + /// + /// Returns `None` when iteration is finished. + pub fn next(&mut self) -> Option, Error>> { let mut raw = ptr::null_mut(); + drop(self.current.take()); unsafe { try_call_iter!(raw::git_config_next(&mut raw, self.raw)); - Some(Ok(ConfigEntry { + let entry = ConfigEntry { owned: false, raw, _marker: marker::PhantomData, - })) + }; + self.current = Some(entry); + Some(Ok(self.current.as_ref().unwrap())) } } + + /// Calls the given closure for each remaining entry in the iterator. + pub fn for_each)>(mut self, mut f: F) -> Result<(), Error> { + while let Some(entry) = self.next() { + let entry = entry?; + f(entry); + } + Ok(()) + } } impl<'cfg> Drop for ConfigEntries<'cfg> { @@ -628,7 +675,8 @@ mod tests { assert_eq!(cfg.get_i64("foo.k3").unwrap(), 2); assert_eq!(cfg.get_str("foo.k4").unwrap(), "bar"); - for entry in &cfg.entries(None).unwrap() { + let mut entries = cfg.entries(None).unwrap(); + while let Some(entry) = entries.next() { let entry = entry.unwrap(); entry.name(); entry.value(); @@ -649,39 +697,42 @@ mod tests { cfg.set_multivar("foo.baz", "^$", "oki").unwrap(); // `entries` filters by name - let mut entries: Vec = cfg - .entries(Some("foo.bar")) + let mut entries: Vec = Vec::new(); + cfg.entries(Some("foo.bar")) .unwrap() - .into_iter() - .map(|entry| entry.unwrap().value().unwrap().into()) - .collect(); + .for_each(|entry| entries.push(entry.value().unwrap().to_string())) + .unwrap(); entries.sort(); assert_eq!(entries, ["baz", "quux", "qux"]); // which is the same as `multivar` without a regex - let mut multivals: Vec = cfg - .multivar("foo.bar", None) + let mut multivals = Vec::new(); + cfg.multivar("foo.bar", None) .unwrap() - .into_iter() - .map(|entry| entry.unwrap().value().unwrap().into()) - .collect(); + .for_each(|entry| multivals.push(entry.value().unwrap().to_string())) + .unwrap(); multivals.sort(); assert_eq!(multivals, entries); // yet _with_ a regex, `multivar` filters by value - let mut quxish: Vec = cfg - .multivar("foo.bar", Some("qu.*x")) + let mut quxish = Vec::new(); + cfg.multivar("foo.bar", Some("qu.*x")) .unwrap() - .into_iter() - .map(|entry| entry.unwrap().value().unwrap().into()) - .collect(); + .for_each(|entry| quxish.push(entry.value().unwrap().to_string())) + .unwrap(); quxish.sort(); assert_eq!(quxish, ["quux", "qux"]); cfg.remove_multivar("foo.bar", ".*").unwrap(); - assert_eq!(cfg.entries(Some("foo.bar")).unwrap().count(), 0); - assert_eq!(cfg.multivar("foo.bar", None).unwrap().count(), 0); + let count = |entries: super::ConfigEntries<'_>| -> usize { + let mut c = 0; + entries.for_each(|_| c += 1).unwrap(); + c + }; + + assert_eq!(count(cfg.entries(Some("foo.bar")).unwrap()), 0); + assert_eq!(count(cfg.multivar("foo.bar", None).unwrap()), 0); } #[test] From e86aaf5af78ace4b36bc6ff17bb2316762e67069 Mon Sep 17 00:00:00 2001 From: David Knaack Date: Mon, 9 May 2022 09:32:15 +0200 Subject: [PATCH 6/9] update libgit2 to newer snapshot CVE 2022-24765 Co-Authored-By: Eric Huss <43198+ehuss@users.noreply.github.com> --- Cargo.toml | 4 ++-- git2-curl/Cargo.toml | 2 +- libgit2-sys/Cargo.toml | 2 +- libgit2-sys/build.rs | 29 +++++++++++++++++++++-------- libgit2-sys/lib.rs | 5 ++++- libgit2-sys/libgit2 | 2 +- src/error.rs | 3 +++ src/lib.rs | 4 +++- src/opts.rs | 13 +++++++++++++ 9 files changed, 49 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 92db148433..27d9a92638 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git2" -version = "0.14.4" +version = "0.15.0" authors = ["Josh Triplett ", "Alex Crichton "] license = "MIT OR Apache-2.0" readme = "README.md" @@ -20,7 +20,7 @@ url = "2.0" bitflags = "1.1.0" libc = "0.2" log = "0.4.8" -libgit2-sys = { path = "libgit2-sys", version = "0.13.4" } +libgit2-sys = { path = "libgit2-sys", version = "0.14.0" } [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies] openssl-sys = { version = "0.9.0", optional = true } diff --git a/git2-curl/Cargo.toml b/git2-curl/Cargo.toml index a52bc21cfe..e249c7bca9 100644 --- a/git2-curl/Cargo.toml +++ b/git2-curl/Cargo.toml @@ -16,7 +16,7 @@ edition = "2018" curl = "0.4.33" url = "2.0" log = "0.4" -git2 = { path = "..", version = "0.14", default-features = false } +git2 = { path = "..", version = "0.15", default-features = false } [dev-dependencies] civet = "0.11" diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index 7edd14f199..77112d409c 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libgit2-sys" -version = "0.13.4+1.4.2" +version = "0.14.0+1.4.4" authors = ["Josh Triplett ", "Alex Crichton "] links = "git2" build = "build.rs" diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index ef0468b40e..28207a9ba7 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -14,11 +14,7 @@ fn main() { let try_to_use_system_libgit2 = !vendored && !zlib_ng_compat; if try_to_use_system_libgit2 { let mut cfg = pkg_config::Config::new(); - if let Ok(lib) = cfg - .range_version("1.4.0".."1.5.0") - .print_system_libs(false) - .probe("libgit2") - { + if let Ok(lib) = cfg.range_version("1.4.4".."1.5.0").probe("libgit2") { for include in &lib.include_paths { println!("cargo:root={}", include.display()); } @@ -162,9 +158,26 @@ fn main() { cfg.define("SHA1DC_NO_STANDARD_INCLUDES", "1"); cfg.define("SHA1DC_CUSTOM_INCLUDE_SHA1_C", "\"common.h\""); cfg.define("SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C", "\"common.h\""); - cfg.file("libgit2/src/util/hash/sha1/collisiondetect.c"); - cfg.file("libgit2/src/util/hash/sha1/sha1dc/sha1.c"); - cfg.file("libgit2/src/util/hash/sha1/sha1dc/ubc_check.c"); + cfg.file("libgit2/src/util/hash/collisiondetect.c"); + cfg.file("libgit2/src/util/hash/sha1dc/sha1.c"); + cfg.file("libgit2/src/util/hash/sha1dc/ubc_check.c"); + + if https { + if windows { + features.push_str("#define GIT_SHA256_WIN32 1\n"); + cfg.file("libgit2/src/util/hash/win32.c"); + } else if target.contains("apple") { + features.push_str("#define GIT_SHA256_COMMON_CRYPTO 1\n"); + cfg.file("libgit2/src/util/hash/common_crypto.c"); + } else { + features.push_str("#define GIT_SHA256_OPENSSL 1\n"); + cfg.file("libgit2/src/util/hash/openssl.c"); + } + } else { + features.push_str("#define GIT_SHA256_BUILTIN 1\n"); + cfg.file("libgit2/src/util/hash/builtin.c"); + cfg.file("libgit2/src/util/hash/rfc6234/sha224-256.c"); + } if let Some(path) = env::var_os("DEP_Z_INCLUDE") { cfg.include(path); diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index d5150ffa45..a113a29526 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/libgit2-sys/0.13")] +#![doc(html_root_url = "https://docs.rs/libgit2-sys/0.14")] #![allow(non_camel_case_types, unused_extern_crates)] // This is required to link libz when libssh2-sys is not included. @@ -195,6 +195,7 @@ git_enum! { GIT_EMISMATCH = -33, GIT_EINDEXDIRTY = -34, GIT_EAPPLYFAIL = -35, + GIT_EOWNER = -36, } } @@ -1894,6 +1895,8 @@ git_enum! { GIT_OPT_SET_ODB_LOOSE_PRIORITY, GIT_OPT_GET_EXTENSIONS, GIT_OPT_SET_EXTENSIONS, + GIT_OPT_GET_OWNER_VALIDATION, + GIT_OPT_SET_OWNER_VALIDATION, } } diff --git a/libgit2-sys/libgit2 b/libgit2-sys/libgit2 index 2a0d0bd19b..53cfad9e4b 160000 --- a/libgit2-sys/libgit2 +++ b/libgit2-sys/libgit2 @@ -1 +1 @@ -Subproject commit 2a0d0bd19b5d13e2ab7f3780e094404828cbb9a7 +Subproject commit 53cfad9e4b0faeb4e2f6385cafd5298cbb81b82b diff --git a/src/error.rs b/src/error.rs index f3ad9ad0e9..779d785adf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -127,6 +127,7 @@ impl Error { raw::GIT_EMISMATCH => super::ErrorCode::HashsumMismatch, raw::GIT_EINDEXDIRTY => super::ErrorCode::IndexDirty, raw::GIT_EAPPLYFAIL => super::ErrorCode::ApplyFail, + raw::GIT_EOWNER => super::ErrorCode::Owner, _ => super::ErrorCode::GenericError, } } @@ -163,6 +164,7 @@ impl Error { ErrorCode::HashsumMismatch => raw::GIT_EMISMATCH, ErrorCode::IndexDirty => raw::GIT_EINDEXDIRTY, ErrorCode::ApplyFail => raw::GIT_EAPPLYFAIL, + ErrorCode::Owner => raw::GIT_EOWNER, }; } @@ -293,6 +295,7 @@ impl Error { GIT_EMISMATCH, GIT_EINDEXDIRTY, GIT_EAPPLYFAIL, + GIT_EOWNER, ) } diff --git a/src/lib.rs b/src/lib.rs index a9ec38d20d..c297ffe444 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ //! source `Repository`, to ensure that they do not outlive the repository //! itself. -#![doc(html_root_url = "https://docs.rs/git2/0.14")] +#![doc(html_root_url = "https://docs.rs/git2/0.15")] #![allow(trivial_numeric_casts, trivial_casts)] #![deny(missing_docs)] #![warn(rust_2018_idioms)] @@ -215,6 +215,8 @@ pub enum ErrorCode { IndexDirty, /// Patch application failed ApplyFail, + /// The object is not owned by the current user + Owner, } /// An enumeration of possible categories of things that can have diff --git a/src/opts.rs b/src/opts.rs index a89df4e1c9..dc902aee63 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -178,6 +178,19 @@ where Ok(()) } +/// Set wheter or not to verify ownership before performing a repository. +/// Enabled by default, but disabling this can lead to code execution vulnerabilities. +pub unsafe fn set_verify_owner_validation(enabled: bool) -> Result<(), Error> { + let error = raw::git_libgit2_opts( + raw::GIT_OPT_SET_OWNER_VALIDATION as libc::c_int, + enabled as libc::c_int, + ); + // This function cannot actually fail, but the function has an error return + // for other options that can. + debug_assert!(error >= 0); + Ok(()) +} + #[cfg(test)] mod test { use super::*; From 8871f8e9b38f600a499a4dd636840930c04b65bd Mon Sep 17 00:00:00 2001 From: David Knaack Date: Thu, 14 Jul 2022 09:44:09 +0200 Subject: [PATCH 7/9] bump libgit2 to 1.5.0 --- libgit2-sys/Cargo.toml | 2 +- libgit2-sys/build.rs | 2 +- libgit2-sys/libgit2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index 77112d409c..1f5fe34e4d 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libgit2-sys" -version = "0.14.0+1.4.4" +version = "0.14.0+1.5.0" authors = ["Josh Triplett ", "Alex Crichton "] links = "git2" build = "build.rs" diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 28207a9ba7..442b196de0 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -14,7 +14,7 @@ fn main() { let try_to_use_system_libgit2 = !vendored && !zlib_ng_compat; if try_to_use_system_libgit2 { let mut cfg = pkg_config::Config::new(); - if let Ok(lib) = cfg.range_version("1.4.4".."1.5.0").probe("libgit2") { + if let Ok(lib) = cfg.range_version("1.4.4".."1.6.0").probe("libgit2") { for include in &lib.include_paths { println!("cargo:root={}", include.display()); } diff --git a/libgit2-sys/libgit2 b/libgit2-sys/libgit2 index 53cfad9e4b..fbea439d4b 160000 --- a/libgit2-sys/libgit2 +++ b/libgit2-sys/libgit2 @@ -1 +1 @@ -Subproject commit 53cfad9e4b0faeb4e2f6385cafd5298cbb81b82b +Subproject commit fbea439d4b6fc91c6b619d01b85ab3b7746e4c19 From 46674cebd9089a6cf78e077fa621347f076705b1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 19 Jul 2022 09:03:05 -0700 Subject: [PATCH 8/9] Fix warning about unused_must_use for Box::from_raw (#860) --- src/odb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb.rs b/src/odb.rs index f64a52c7e4..66166913fe 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -514,7 +514,7 @@ impl<'repo> Drop for OdbPackwriter<'repo> { None => (), }; - Box::from_raw(self.progress_payload_ptr); + drop(Box::from_raw(self.progress_payload_ptr)); } } } From e6aa6666b9f0f9110adf5bad56ea1d1dfa119d1c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 19 Jul 2022 09:03:38 -0700 Subject: [PATCH 9/9] Bump git2-curl version. (#861) --- git2-curl/Cargo.toml | 2 +- git2-curl/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/git2-curl/Cargo.toml b/git2-curl/Cargo.toml index e249c7bca9..3dc80e4246 100644 --- a/git2-curl/Cargo.toml +++ b/git2-curl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git2-curl" -version = "0.15.0" +version = "0.16.0" authors = ["Josh Triplett ", "Alex Crichton "] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/git2-rs" diff --git a/git2-curl/src/lib.rs b/git2-curl/src/lib.rs index e8c2aac9d8..480c51c982 100644 --- a/git2-curl/src/lib.rs +++ b/git2-curl/src/lib.rs @@ -15,7 +15,7 @@ //! > **NOTE**: At this time this crate likely does not support a `git push` //! > operation, only clones. -#![doc(html_root_url = "https://docs.rs/git2-curl/0.15")] +#![doc(html_root_url = "https://docs.rs/git2-curl/0.16")] #![deny(missing_docs)] #![warn(rust_2018_idioms)] #![cfg_attr(test, deny(warnings))]