Snap for 9550355 from 7b3816f38c354e37a6c4cdb997c2d263814499db to sdk-release

Change-Id: I956f6103e63646c290a77a28f297bab19c265dba
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 4dbf890..d0e4fff 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "ca9cc93b392fa1d0eb4eb2a60c74b3b3ecff03bb"
+    "sha1": "492df704947be42c30f3bc7947e75244f26a0a45"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index d41ae65..bc8bec7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,11 +23,15 @@
     host_supported: true,
     crate_name: "which",
     cargo_env_compat: true,
-    cargo_pkg_version: "4.2.5",
+    cargo_pkg_version: "4.3.0",
     srcs: ["src/lib.rs"],
     edition: "2018",
     rustlibs: [
         "libeither",
         "liblibc",
     ],
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
 }
diff --git a/Cargo.toml b/Cargo.toml
index 3e5545f..84d671a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,17 +12,27 @@
 [package]
 edition = "2018"
 name = "which"
-version = "4.2.5"
+version = "4.3.0"
 authors = ["Harry Fei <tiziyuanfang@gmail.com>"]
 description = "A Rust equivalent of Unix command \"which\". Locate installed executable in cross platforms."
 documentation = "https://docs.rs/which/"
 readme = "README.md"
-keywords = ["which", "which-rs", "unix", "command"]
-categories = ["os", "filesystem"]
+keywords = [
+    "which",
+    "which-rs",
+    "unix",
+    "command",
+]
+categories = [
+    "os",
+    "filesystem",
+]
 license = "MIT"
 repository = "https://github.com/harryfei/which-rs.git"
+
 [package.metadata.docs.rs]
 all-features = true
+
 [dependencies.either]
 version = "1.6.1"
 
@@ -32,7 +42,9 @@
 [dependencies.regex]
 version = "1.5.5"
 optional = true
+
 [dev-dependencies.tempfile]
 version = "3.3.0"
-[target."cfg(windows)".dependencies.lazy_static]
-version = "1.4.0"
+
+[target."cfg(windows)".dependencies.once_cell]
+version = "1"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index dccbdb4..d8251f8 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "which"
-version = "4.2.5"
+version = "4.3.0"
 edition = "2018"
 authors = ["Harry Fei <tiziyuanfang@gmail.com>"]
 repository = "https://github.com/harryfei/which-rs.git"
@@ -17,7 +17,7 @@
 regex = { version = "1.5.5", optional = true }
 
 [target.'cfg(windows)'.dependencies]
-lazy_static = "1.4.0"
+once_cell = "1"
 
 [dev-dependencies]
 tempfile = "3.3.0"
diff --git a/METADATA b/METADATA
index 9d9dd01..36e9b3e 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/which
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "which"
 description: "A Rust equivalent of Unix command \"which\". Locate installed executable in cross platforms."
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/which/which-4.2.5.crate"
+    value: "https://static.crates.io/crates/which/which-4.3.0.crate"
   }
-  version: "4.2.5"
+  version: "4.3.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2022
-    month: 4
-    day: 18
+    month: 12
+    day: 19
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 96a0732..23bbdf9 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,28 +3,12 @@
   "imports": [
     {
       "path": "external/rust/crates/libsqlite3-sys"
-    }
-  ],
-  "presubmit": [
-    {
-      "name": "keystore2_legacy_blobs_test"
     },
     {
-      "name": "keystore2_test"
+      "path": "system/security/keystore2"
     },
     {
-      "name": "legacykeystore_test"
-    }
-  ],
-  "presubmit-rust": [
-    {
-      "name": "keystore2_legacy_blobs_test"
-    },
-    {
-      "name": "keystore2_test"
-    },
-    {
-      "name": "legacykeystore_test"
+      "path": "system/security/keystore2/legacykeystore"
     }
   ]
 }
diff --git a/src/finder.rs b/src/finder.rs
index 9b64294..858a224 100644
--- a/src/finder.rs
+++ b/src/finder.rs
@@ -9,7 +9,7 @@
 use std::borrow::Borrow;
 use std::env;
 use std::ffi::OsStr;
-#[cfg(feature = "regex")]
+#[cfg(any(feature = "regex", target_os = "windows"))]
 use std::fs;
 use std::iter;
 use std::path::{Path, PathBuf};
@@ -80,7 +80,9 @@
             }
         };
 
-        Ok(binary_path_candidates.filter(move |p| binary_checker.is_valid(p)))
+        Ok(binary_path_candidates
+            .filter(move |p| binary_checker.is_valid(p))
+            .map(correct_casing))
     }
 
     #[cfg(feature = "regex")]
@@ -151,29 +153,31 @@
     where
         P: IntoIterator<Item = PathBuf>,
     {
+        use once_cell::sync::Lazy;
+
         // Sample %PATHEXT%: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
         // PATH_EXTENSIONS is then [".COM", ".EXE", ".BAT", …].
         // (In one use of PATH_EXTENSIONS we skip the dot, but in the other we need it;
         // hence its retention.)
-        lazy_static! {
-            static ref PATH_EXTENSIONS: Vec<String> =
-                env::var("PATHEXT")
-                    .map(|pathext| {
-                        pathext.split(';')
-                            .filter_map(|s| {
-                                if s.as_bytes().first() == Some(&b'.') {
-                                    Some(s.to_owned())
-                                } else {
-                                    // Invalid segment; just ignore it.
-                                    None
-                                }
-                            })
-                            .collect()
-                    })
-                    // PATHEXT not being set or not being a proper Unicode string is exceedingly
-                    // improbable and would probably break Windows badly. Still, don't crash:
-                    .unwrap_or_default();
-        }
+        static PATH_EXTENSIONS: Lazy<Vec<String>> = Lazy::new(|| {
+            env::var("PATHEXT")
+                .map(|pathext| {
+                    pathext
+                        .split(';')
+                        .filter_map(|s| {
+                            if s.as_bytes().first() == Some(&b'.') {
+                                Some(s.to_owned())
+                            } else {
+                                // Invalid segment; just ignore it.
+                                None
+                            }
+                        })
+                        .collect()
+                })
+                // PATHEXT not being set or not being a proper Unicode string is exceedingly
+                // improbable and would probably break Windows badly. Still, don't crash:
+                .unwrap_or_default()
+        });
 
         paths
             .into_iter()
@@ -182,20 +186,47 @@
                 if has_executable_extension(&p, &PATH_EXTENSIONS) {
                     Box::new(iter::once(p))
                 } else {
+                    let bare_file = p.extension().map(|_| p.clone());
                     // Appended paths with windows executable extensions.
-                    // e.g. path `c:/windows/bin` will expend to:
-                    // c:/windows/bin.COM
-                    // c:/windows/bin.EXE
-                    // c:/windows/bin.CMD
+                    // e.g. path `c:/windows/bin[.ext]` will expand to:
+                    // [c:/windows/bin.ext]
+                    // c:/windows/bin[.ext].COM
+                    // c:/windows/bin[.ext].EXE
+                    // c:/windows/bin[.ext].CMD
                     // ...
-                    Box::new(PATH_EXTENSIONS.iter().map(move |e| {
-                        // Append the extension.
-                        let mut p = p.clone().into_os_string();
-                        p.push(e);
+                    Box::new(
+                        bare_file
+                            .into_iter()
+                            .chain(PATH_EXTENSIONS.iter().map(move |e| {
+                                // Append the extension.
+                                let mut p = p.clone().into_os_string();
+                                p.push(e);
 
-                        PathBuf::from(p)
-                    }))
+                                PathBuf::from(p)
+                            })),
+                    )
                 }
             })
     }
 }
+
+#[cfg(target_os = "windows")]
+fn correct_casing(mut p: PathBuf) -> PathBuf {
+    if let (Some(parent), Some(file_name)) = (p.parent(), p.file_name()) {
+        if let Ok(iter) = fs::read_dir(parent) {
+            for e in iter.filter_map(std::result::Result::ok) {
+                if e.file_name().eq_ignore_ascii_case(file_name) {
+                    p.pop();
+                    p.push(e.file_name());
+                    break;
+                }
+            }
+        }
+    }
+    p
+}
+
+#[cfg(not(target_os = "windows"))]
+fn correct_casing(p: PathBuf) -> PathBuf {
+    p
+}
diff --git a/src/lib.rs b/src/lib.rs
index 2b27094..b9026ff 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,10 +14,6 @@
 //!
 //! ```
 
-#[cfg(windows)]
-#[macro_use]
-extern crate lazy_static;
-
 mod checker;
 mod error;
 mod finder;
@@ -38,7 +34,7 @@
 pub use crate::error::*;
 use crate::finder::Finder;
 
-/// Find a exectable binary's path by name.
+/// Find an executable binary's path by name.
 ///
 /// If given an absolute path, returns it if the file exists and is executable.
 ///
diff --git a/tests/basic.rs b/tests/basic.rs
index 59c5fb0..32a1a28 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -67,6 +67,10 @@
             bins.push(mk_bin(&p, BIN_NAME, "cmd").unwrap());
             paths.push(p);
         }
+        let p = tempdir.path().join("win-bin");
+        builder.create(&p).unwrap();
+        bins.push(mk_bin(&p, "win-bin", "exe").unwrap());
+        paths.push(p);
         TestFixture {
             tempdir,
             paths: env::join_paths(paths).unwrap(),
@@ -195,6 +199,17 @@
 }
 
 #[test]
+#[cfg(windows)]
+fn test_which_no_extension() {
+    let f = TestFixture::new();
+    let b = Path::new("win-bin");
+    let which_result = which::which_in(&b, Some(&f.paths), ".").unwrap();
+    // Make sure the extension is the correct case.
+    assert_eq!(which_result.extension(), f.bins[9].extension());
+    assert_eq!(fs::canonicalize(&which_result).unwrap(), f.bins[9])
+}
+
+#[test]
 fn test_which_not_found() {
     let f = TestFixture::new();
     assert!(_which(&f, "a").is_err());
@@ -221,6 +236,7 @@
         .collect::<Vec<_>>();
     #[cfg(windows)]
     {
+        expected.retain(|p| p.file_stem().unwrap() == BIN_NAME);
         expected.retain(|p| p.extension().map(|ext| ext == "exe" || ext == "cmd") == Some(true));
     }
     #[cfg(not(windows))]