Project import generated by Copybara.

GitOrigin-RevId: 2831ee5d711b49878d06b0379e058687a919c074
Change-Id: I385cafbbd48bf087df67f81fadc36cb0fc8ef5b3
diff --git a/nearby/Cargo.lock b/nearby/Cargo.lock
index 46d9066..e50e7b7 100644
--- a/nearby/Cargo.lock
+++ b/nearby/Cargo.lock
@@ -1395,7 +1395,6 @@
  "crypto_provider",
  "np_adv",
  "sink",
- "thiserror",
 ]
 
 [[package]]
diff --git a/nearby/Cargo.toml b/nearby/Cargo.toml
index 301fe34..4897eaa 100644
--- a/nearby/Cargo.toml
+++ b/nearby/Cargo.toml
@@ -79,7 +79,7 @@
 np_adv = { path = "presence/np_adv" }
 np_adv_dynamic = { path = "presence/np_adv_dynamic" }
 np_ed25519 = { path = "presence/np_ed25519" }
-np_ffi_core = { path = "presence/np_ffi_core" }
+np_ffi_core = { path = "presence/np_ffi_core", default-features=false }
 pourover = { path = "util/pourover" }
 pourover_macro = { path = "util/pourover_macro" }
 pourover_macro_core = { path = "util/pourover_macro_core" }
diff --git a/nearby/crypto/crypto_provider_default/src/lib.rs b/nearby/crypto/crypto_provider_default/src/lib.rs
index dcde771..67f3e7d 100644
--- a/nearby/crypto/crypto_provider_default/src/lib.rs
+++ b/nearby/crypto/crypto_provider_default/src/lib.rs
@@ -18,7 +18,9 @@
 #![no_std]
 
 cfg_if::cfg_if! {
-    if #[cfg(feature = "rustcrypto")] {
+    if #[cfg(all(feature = "rustcrypto", feature = "boringssl"))] {
+        compile_error!("Conflicting crypto_providers specified, must only enable a single crypto provider");
+    } else if #[cfg(feature = "rustcrypto")] {
         pub use crypto_provider_rustcrypto::RustCrypto as CryptoProviderImpl;
     } else if #[cfg(feature = "boringssl")] {
         pub use crypto_provider_boringssl::Boringssl as CryptoProviderImpl;
diff --git a/nearby/presence/CMakeLists.txt b/nearby/presence/CMakeLists.txt
index ec93edd..630d172 100644
--- a/nearby/presence/CMakeLists.txt
+++ b/nearby/presence/CMakeLists.txt
@@ -45,7 +45,7 @@
     FetchContent_Declare(
             googletest
             GIT_REPOSITORY https://github.com/google/googletest.git
-            GIT_TAG release-1.12.1
+            GIT_TAG v1.14.0
     )
     FetchContent_MakeAvailable(googletest)
     enable_testing()
diff --git a/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/mic_decrypt_tests.rs b/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/mic_decrypt_tests.rs
index bf78b7d..b172db6 100644
--- a/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/mic_decrypt_tests.rs
+++ b/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/mic_decrypt_tests.rs
@@ -58,7 +58,7 @@
     let mut section_builder = adv_builder
         .section_builder(MicEncryptedSectionEncoder::<CryptoProviderImpl>::new(
             identity_type,
-            V1Salt::from(*section_salt.as_array_ref()),
+            raw_salt,
             &broadcast_cm,
         ))
         .unwrap();
@@ -318,7 +318,7 @@
     let mut section_builder = adv_builder
         .section_builder(MicEncryptedSectionEncoder::<C>::new(
             identity_type,
-            section_salt,
+            section_salt.into(),
             &broadcast_cm,
         ))
         .unwrap();
@@ -403,7 +403,7 @@
     let mut section_builder = adv_builder
         .section_builder(MicEncryptedSectionEncoder::<CryptoProviderImpl>::new(
             identity_type,
-            section_salt,
+            section_salt.into(),
             &broadcast_cm,
         ))
         .unwrap();
diff --git a/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/signature_decrypt_tests.rs b/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/signature_decrypt_tests.rs
index c5a468f..7801744 100644
--- a/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/signature_decrypt_tests.rs
+++ b/nearby/presence/np_adv/src/extended/deserialize/encrypted_section/signature_decrypt_tests.rs
@@ -21,7 +21,7 @@
 use crate::extended::deserialize::{
     DataElementParseError, DecryptedSection, EncryptionInfo, RawV1Salt, SectionContents,
 };
-use crate::extended::serialize::AdvertisementType;
+use crate::extended::serialize::{AdvertisementType, DeSalt};
 use crate::shared_data::TxPower;
 use crate::{
     credential::v1::*,
@@ -72,7 +72,7 @@
     let mut section_builder = adv_builder
         .section_builder(SignedEncryptedSectionEncoder::<CryptoProviderImpl>::new(
             identity_type,
-            V1Salt::from(*section_salt.as_array_ref()),
+            raw_salt,
             &broadcast_cm,
         ))
         .unwrap();
@@ -379,12 +379,14 @@
     let mut section_builder = adv_builder
         .section_builder(SignedEncryptedSectionEncoder::new(
             identity_type,
-            section_salt,
+            section_salt.into(),
             &broadcast_cm,
         ))
         .unwrap();
 
-    section_builder.add_de_res(|_| TxPower::try_from(2).map(TxPowerDataElement::from)).unwrap();
+    section_builder
+        .add_de_res(|_: DeSalt<C>| TxPower::try_from(2).map(TxPowerDataElement::from))
+        .unwrap();
 
     section_builder.add_to_advertisement();
 
@@ -474,12 +476,16 @@
     let mut section_builder = adv_builder
         .section_builder(SignedEncryptedSectionEncoder::new(
             identity_type,
-            section_salt,
+            section_salt.into(),
             &broadcast_cm,
         ))
         .unwrap();
 
-    section_builder.add_de_res(|_| TxPower::try_from(2).map(TxPowerDataElement::from)).unwrap();
+    section_builder
+        .add_de_res(|_: DeSalt<CryptoProviderImpl>| {
+            TxPower::try_from(2).map(TxPowerDataElement::from)
+        })
+        .unwrap();
 
     mangle_section(&mut section_builder.section);
 
diff --git a/nearby/presence/np_adv/src/extended/deserialize/mod.rs b/nearby/presence/np_adv/src/extended/deserialize/mod.rs
index 8f12a94..a208040 100644
--- a/nearby/presence/np_adv/src/extended/deserialize/mod.rs
+++ b/nearby/presence/np_adv/src/extended/deserialize/mod.rs
@@ -326,7 +326,7 @@
 
 /// A byte buffer the size of a V1 salt.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct RawV1Salt([u8; 16]);
+pub struct RawV1Salt(pub(crate) [u8; 16]);
 
 impl RawV1Salt {
     /// Returns the raw salt bytes as a vec.
diff --git a/nearby/presence/np_adv/src/extended/serialize/mod.rs b/nearby/presence/np_adv/src/extended/serialize/mod.rs
index b70f49d..363862f 100644
--- a/nearby/presence/np_adv/src/extended/serialize/mod.rs
+++ b/nearby/presence/np_adv/src/extended/serialize/mod.rs
@@ -111,6 +111,7 @@
 //!         .try_into().expect("array sizes match")
 //! }
 //! ```
+use crate::extended::deserialize::RawV1Salt;
 use crate::extended::{NP_V1_ADV_MAX_ENCRYPTED_SECTION_COUNT, NP_V1_ADV_MAX_PUBLIC_SECTION_COUNT};
 use crate::{
     credential::{
@@ -539,7 +540,7 @@
 /// using key material derived from an NP identity.
 pub struct SignedEncryptedSectionEncoder<C: CryptoProvider> {
     identity_type: EncryptedIdentityDataElementType,
-    salt: V1Salt<C>,
+    salt: RawV1Salt,
     metadata_key: MetadataKey,
     key_pair: np_ed25519::KeyPair<C>,
     aes_key: Aes128Key,
@@ -553,7 +554,7 @@
         identity_type: EncryptedIdentityDataElementType,
         crypto_material: &B,
     ) -> Self {
-        let salt: V1Salt<C> = rng.gen::<[u8; 16]>().into();
+        let salt = RawV1Salt(rng.gen::<[u8; 16]>());
         Self::new(identity_type, salt, crypto_material)
     }
 
@@ -561,7 +562,7 @@
     /// a provided salt, and some broadcast crypto-material.
     pub(crate) fn new<B: SignedBroadcastCryptoMaterial>(
         identity_type: EncryptedIdentityDataElementType,
-        salt: V1Salt<C>,
+        salt: RawV1Salt,
         crypto_material: &B,
     ) -> Self {
         let metadata_key = crypto_material.metadata_key();
@@ -590,10 +591,7 @@
         section_header: u8,
         section_contents: &mut [u8],
     ) {
-        let encryption_info_bytes = EncryptionInfoDataElement::signature(
-            self.salt.as_slice().try_into().expect("Salt should be 16 bytes"),
-        )
-        .serialize();
+        let encryption_info_bytes = EncryptionInfoDataElement::signature(&self.salt.0).serialize();
         section_contents[0..19].copy_from_slice(&encryption_info_bytes);
 
         let identity_header = identity_de_header(self.identity_type, self.metadata_key);
@@ -640,7 +638,7 @@
     type DerivedSalt = DeSalt<C>;
 
     fn de_salt(&self, de_offset: DataElementOffset) -> Self::DerivedSalt {
-        DeSalt { salt: V1Salt::from(*self.salt.as_array_ref()), de_offset }
+        DeSalt { salt: V1Salt::from(self.salt.0), de_offset }
     }
 }
 
@@ -648,7 +646,7 @@
 /// an NP identity.
 pub struct MicEncryptedSectionEncoder<C: CryptoProvider> {
     identity_type: EncryptedIdentityDataElementType,
-    salt: V1Salt<C>,
+    salt: RawV1Salt,
     metadata_key: MetadataKey,
     aes_key: Aes128Key,
     mic_hmac_key: np_hkdf::NpHmacSha256Key<C>,
@@ -662,14 +660,14 @@
         identity_type: EncryptedIdentityDataElementType,
         crypto_material: &B,
     ) -> Self {
-        let salt: V1Salt<C> = rng.gen::<[u8; 16]>().into();
+        let salt = RawV1Salt(rng.gen::<[u8; 16]>());
         Self::new(identity_type, salt, crypto_material)
     }
 
     /// Build a [MicEncryptedSectionEncoder] from the provided identity info.
     pub(crate) fn new<B: BroadcastCryptoMaterial<V1>>(
         identity_type: EncryptedIdentityDataElementType,
-        salt: V1Salt<C>,
+        salt: RawV1Salt,
         crypto_material: &B,
     ) -> Self {
         let metadata_key = crypto_material.metadata_key();
@@ -687,7 +685,7 @@
     #[cfg(any(test, feature = "testing"))]
     pub fn new_for_testing<B: BroadcastCryptoMaterial<V1>>(
         identity_type: EncryptedIdentityDataElementType,
-        salt: V1Salt<C>,
+        salt: RawV1Salt,
         crypto_material: &B,
     ) -> Self {
         Self::new(identity_type, salt, crypto_material)
@@ -716,10 +714,7 @@
         // 19-20: Identity DE header
         // 21-36: Identity DE contents (metadata key)
         // Encryption Info DE
-        let encryption_info_bytes = EncryptionInfoDataElement::mic(
-            self.salt.as_slice().try_into().expect("Salt should be 16 bytes"),
-        )
-        .serialize();
+        let encryption_info_bytes = EncryptionInfoDataElement::mic(&self.salt.0).serialize();
         section_contents[0..19].copy_from_slice(&encryption_info_bytes);
         // Identity DE
         let identity_header = identity_de_header(self.identity_type, self.metadata_key);
@@ -754,7 +749,7 @@
     }
     type DerivedSalt = DeSalt<C>;
     fn de_salt(&self, de_offset: DataElementOffset) -> Self::DerivedSalt {
-        DeSalt { salt: V1Salt::from(*self.salt.as_array_ref()), de_offset }
+        DeSalt { salt: V1Salt::from(self.salt.0), de_offset }
     }
 }
 
diff --git a/nearby/presence/np_adv/src/extended/serialize/section_tests.rs b/nearby/presence/np_adv/src/extended/serialize/section_tests.rs
index 3a6a5f9..2961fec 100644
--- a/nearby/presence/np_adv/src/extended/serialize/section_tests.rs
+++ b/nearby/presence/np_adv/src/extended/serialize/section_tests.rs
@@ -82,9 +82,7 @@
                 &broadcast_cm,
             ))
             .unwrap();
-        let section_salt = V1Salt::<CryptoProviderImpl>::from(
-            *section_builder.section_encoder.salt.as_array_ref(),
-        );
+        let section_salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
         for de in extra_des.iter() {
             section_builder.add_de(|_| de).unwrap();
@@ -188,9 +186,7 @@
                 &broadcast_cm,
             ))
             .unwrap();
-        let section_salt = V1Salt::<CryptoProviderImpl>::from(
-            *section_builder.section_encoder.salt.as_array_ref(),
-        );
+        let section_salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
         let extra_des = (0..num_des)
             .map(|_| {
@@ -287,8 +283,7 @@
             &broadcast_cm,
         ))
         .unwrap();
-    let salt =
-        V1Salt::<CryptoProviderImpl>::from(*section_builder.section_encoder.salt.as_array_ref());
+    let salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
     section_builder
         .add_de(|de_salt| DummyDataElement {
@@ -384,8 +379,7 @@
             &broadcast_cm,
         ))
         .unwrap();
-    let salt =
-        V1Salt::<CryptoProviderImpl>::from(*section_builder.section_encoder.salt.as_array_ref());
+    let salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
     section_builder
         .add_de(|de_salt| DummyDataElement {
@@ -452,8 +446,7 @@
             &broadcast_cm,
         ))
         .unwrap();
-    let salt =
-        V1Salt::<CryptoProviderImpl>::from(*section_builder.section_encoder.salt.as_array_ref());
+    let salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
     section_builder
         .add_de(|de_salt| DummyDataElement {
@@ -516,8 +509,7 @@
             &broadcast_cm,
         ))
         .unwrap();
-    let salt =
-        V1Salt::<CryptoProviderImpl>::from(*section_builder.section_encoder.salt.as_array_ref());
+    let salt: V1Salt<CryptoProviderImpl> = section_builder.section_encoder.salt.into();
 
     section_builder
         .add_de(|de_salt| DummyDataElement {
@@ -634,7 +626,8 @@
     let metadata_key = MetadataKey([1; 16]);
     let key_seed = [2; 32];
     let adv_header_byte = 0b00100000;
-    let section_salt: V1Salt<CryptoProviderImpl> = [3; 16].into();
+    let raw_salt = [3; 16];
+    let section_salt: V1Salt<CryptoProviderImpl> = raw_salt.into();
     let identity_type = EncryptedIdentityDataElementType::Private;
     let key_seed_hkdf = np_hkdf::NpKeySeedHkdf::<CryptoProviderImpl>::new(&key_seed);
 
@@ -645,7 +638,7 @@
     let mut section_builder = adv_builder
         .section_builder(MicEncryptedSectionEncoder::<CryptoProviderImpl>::new(
             identity_type,
-            V1Salt::from(*section_salt.as_array_ref()),
+            RawV1Salt(raw_salt),
             &broadcast_cm,
         ))
         .unwrap();
@@ -719,7 +712,8 @@
     let metadata_key = MetadataKey([1; 16]);
     let key_seed = [2; 32];
     let adv_header_byte = 0b00100000;
-    let section_salt: V1Salt<CryptoProviderImpl> = [3; 16].into();
+    let raw_salt = [3; 16];
+    let section_salt: V1Salt<CryptoProviderImpl> = raw_salt.into();
     let identity_type = EncryptedIdentityDataElementType::Private;
     let key_seed_hkdf = np_hkdf::NpKeySeedHkdf::<CryptoProviderImpl>::new(&key_seed);
     let key_pair = KeyPair::generate();
@@ -732,7 +726,7 @@
     let mut section_builder = adv_builder
         .section_builder(SignedEncryptedSectionEncoder::<CryptoProviderImpl>::new(
             identity_type,
-            V1Salt::from(*section_salt.as_array_ref()),
+            RawV1Salt(raw_salt),
             &broadcast_cm,
         ))
         .unwrap();
diff --git a/nearby/presence/np_adv/src/extended/serialize/test_vectors.rs b/nearby/presence/np_adv/src/extended/serialize/test_vectors.rs
index d03ad9b..0f5b22a 100644
--- a/nearby/presence/np_adv/src/extended/serialize/test_vectors.rs
+++ b/nearby/presence/np_adv/src/extended/serialize/test_vectors.rs
@@ -16,6 +16,7 @@
 
 extern crate std;
 
+use crate::extended::deserialize::RawV1Salt;
 use crate::extended::serialize::AdvertisementType;
 use crate::{
     credential::{v1::V1, SimpleBroadcastCryptoMaterial},
@@ -30,7 +31,6 @@
 use crypto_provider::{aes::ctr::AES_CTR_NONCE_LEN, aes::AesKey};
 use crypto_provider_default::CryptoProviderImpl;
 use np_hkdf::v1_salt;
-use np_hkdf::v1_salt::V1Salt;
 use rand_ext::rand::{prelude::SliceRandom as _, Rng as _, SeedableRng as _};
 use serde_json::json;
 use std::{fs, io::Read as _, prelude::rust_2021::*, println};
@@ -94,7 +94,7 @@
             let mut section_builder = adv_builder
                 .section_builder(MicEncryptedSectionEncoder::<CryptoProviderImpl>::new(
                     identity_type,
-                    section_salt,
+                    section_salt.into(),
                     &broadcast_cm,
                 ))
                 .unwrap();
@@ -145,11 +145,12 @@
 
         let mut adv_builder = AdvBuilder::new(AdvertisementType::Encrypted);
 
-        let section_salt = v1_salt::V1Salt::<CryptoProviderImpl>::from(rng.gen::<[u8; 16]>());
+        let salt = rng.gen::<[u8; 16]>();
+        let section_salt = v1_salt::V1Salt::<CryptoProviderImpl>::from(salt);
         let mut section_builder = adv_builder
             .section_builder(MicEncryptedSectionEncoder::<CryptoProviderImpl>::new(
                 identity_type,
-                V1Salt::from(*section_salt.as_array_ref()),
+                RawV1Salt(salt),
                 &broadcast_cm,
             ))
             .unwrap();
diff --git a/nearby/presence/np_adv_dynamic/Cargo.toml b/nearby/presence/np_adv_dynamic/Cargo.toml
index 74d6e3a..2e36ec5 100644
--- a/nearby/presence/np_adv_dynamic/Cargo.toml
+++ b/nearby/presence/np_adv_dynamic/Cargo.toml
@@ -11,5 +11,4 @@
 array_view.workspace = true
 np_adv = { workspace = true, features = ["alloc"] }
 crypto_provider.workspace = true
-thiserror.workspace = true
 sink.workspace = true
diff --git a/nearby/presence/np_adv_dynamic/src/extended.rs b/nearby/presence/np_adv_dynamic/src/extended.rs
index 5e1328c..07de504 100644
--- a/nearby/presence/np_adv_dynamic/src/extended.rs
+++ b/nearby/presence/np_adv_dynamic/src/extended.rs
@@ -15,7 +15,7 @@
 use crypto_provider::CryptoProvider;
 use np_adv::{extended::data_elements::*, extended::serialize::*, shared_data::*};
 use sink::Sink;
-use thiserror::Error;
+use std::fmt::{Display, Formatter};
 
 /// An advertisement builder for V1 advertisements where the
 /// presence/absence of salt is determined at run-time instead of compile-time.
@@ -32,17 +32,30 @@
 
 /// Error possibly generated when attempting to add a section to
 /// a BoxedAdvBuilder.
-#[derive(Debug, Error)]
+#[derive(Debug)]
 pub enum BoxedAddSectionError {
     /// An error which was generated by the underlying AdvBuilder wrapped by the BoxedAdvBuilder
-    #[error("{0}")]
     Underlying(AddSectionError),
     /// An error generated when the boxed advertisement builder is unsalted, but the section
     /// identity requires salt.
-    #[error("Error generated when the BoxedAdvBuilder is unsalted, but the section identity requires salt.")]
     IdentityRequiresSaltError,
 }
 
+impl Display for BoxedAddSectionError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        match self {
+            BoxedAddSectionError::Underlying(u) => {
+                write!(f, "{0}", u)
+            }
+            BoxedAddSectionError::IdentityRequiresSaltError => {
+                write!(f, "Error generated when the BoxedAdvBuilder is unsalted, but the section identity requires salt.")
+            }
+        }
+    }
+}
+
+impl std::error::Error for BoxedAddSectionError {}
+
 impl From<AddSectionError> for BoxedAddSectionError {
     fn from(wrapped: AddSectionError) -> Self {
         BoxedAddSectionError::Underlying(wrapped)
diff --git a/nearby/presence/np_adv_dynamic/src/legacy.rs b/nearby/presence/np_adv_dynamic/src/legacy.rs
index 8ffea16..83ce6ab 100644
--- a/nearby/presence/np_adv_dynamic/src/legacy.rs
+++ b/nearby/presence/np_adv_dynamic/src/legacy.rs
@@ -20,7 +20,7 @@
 use np_adv::legacy::*;
 use np_adv::shared_data::*;
 use np_adv::PublicIdentity;
-use thiserror::Error;
+use std::fmt::{Display, Formatter};
 
 /// Wrapper around a V0 advertisement builder which
 /// is agnostic to the kind of identity used in the advertisement.
@@ -112,22 +112,33 @@
 
 /// Possible errors generated when trying to add a DE to a
 /// BoxedAdvBuilder.
-#[derive(Debug, Error)]
+#[derive(Debug)]
 pub enum BoxedAddDataElementError {
     /// Some kind of error in adding the data element which
     /// is not an issue with trying to add a DE of the incorrect
     /// packet flavoring.
-    #[error("{0:?}")]
     UnderlyingError(AddDataElementError),
-    #[error(
-        "Expected packet flavoring for added DEs does not match the actual packet flavor of the DE"
-    )]
     /// Error when attempting to add a DE which requires one
     /// of an (encrypted/plaintext) advertisement, but the
     /// advertisement builder doesn't match this requirement.
     FlavorMismatchError,
 }
 
+impl Display for BoxedAddDataElementError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        match self {
+            BoxedAddDataElementError::UnderlyingError(u) => {
+                write!(f, "{0:?}", u)
+            }
+            BoxedAddDataElementError::FlavorMismatchError => {
+                write!(f, "Expected packet flavoring for added DEs does not match the actual packet flavor of the DE")
+            }
+        }
+    }
+}
+
+impl std::error::Error for BoxedAddDataElementError {}
+
 impl From<AddDataElementError> for BoxedAddDataElementError {
     fn from(add_data_element_error: AddDataElementError) -> Self {
         BoxedAddDataElementError::UnderlyingError(add_data_element_error)
diff --git a/nearby/presence/np_c_ffi/Cargo.toml b/nearby/presence/np_c_ffi/Cargo.toml
index 991a5e0..517c2c5 100644
--- a/nearby/presence/np_c_ffi/Cargo.toml
+++ b/nearby/presence/np_c_ffi/Cargo.toml
@@ -5,7 +5,7 @@
 publish = false
 
 [dependencies]
-np_ffi_core.workspace = true
+np_ffi_core = {workspace = true, default-features=false}
 lock_adapter.workspace = true
 
 [build-dependencies]
@@ -16,6 +16,7 @@
 rustcrypto = ["np_ffi_core/rustcrypto"]
 boringssl = ["np_ffi_core/boringssl"]
 
+
 [lib]
 # boringssl and bssl-sys are built as a static lib, so we need to as well
 crate-type = ["staticlib"]
\ No newline at end of file
diff --git a/nearby/src/license.rs b/nearby/src/license.rs
index 387ca27..d9491b2 100644
--- a/nearby/src/license.rs
+++ b/nearby/src/license.rs
@@ -72,9 +72,9 @@
 }
 
 fn license_ignore_dirs() -> Vec<&'static str> {
+    // These will be checked against the absolute path of each file.
     vec![
         "**/android/build/**",
-        "target/**",
         "**/target/**",
         "**/.idea/**",
         "**/cmake-build/**",
@@ -109,5 +109,16 @@
         "**/*.class",
         "**/fuzz/artifacts/**",
         "**/cmake-build-debug/**",
+        "**/tags",
     ]
 }
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn new_ignore_is_likely_buggy() {
+        for dir in super::license_ignore_dirs() {
+            assert!(dir.starts_with("**/"), "Matching on the root filesystem is likely unintended");
+        }
+    }
+}
diff --git a/nearby/src/main.rs b/nearby/src/main.rs
index f4843be..a38676f 100644
--- a/nearby/src/main.rs
+++ b/nearby/src/main.rs
@@ -92,8 +92,10 @@
             fmt_command.extend(["--set-exit-if-changed".into(), "--dry-run".into()]);
         }
 
-        let java_files: Vec<_> =
-            glob::glob("./**/*.java").unwrap().filter_map(Result::ok).collect();
+        let root_str =
+            glob::Pattern::escape(root.to_str().expect("Non-unicode paths are not supported"));
+        let search = format!("{}/**/*.java", root_str);
+        let java_files: Vec<_> = glob::glob(&search).unwrap().filter_map(Result::ok).collect();
 
         for file_set in java_files.chunks(100) {
             let mut args = fmt_command[1..].to_vec();