@@ -202,11 +202,15 @@ fn is_valid_package_name(name: &str) -> bool {
202202 return false ;
203203 }
204204
205- // Check reserved keywords.
206- if reserved_keywords ( ) . any ( |kw| kw == name) {
205+ if is_leo_keyword ( name) {
206+ tracing:: error!( "Aleo names cannot be a Leo keyword." ) ;
207+ return false ;
208+ }
209+
210+ if is_aleo_keyword ( name) {
207211 tracing:: error!(
208212 "Aleo names cannot be a SnarkVM reserved keyword. Reserved keywords are: {}." ,
209- reserved_keywords ( ) . collect:: <Vec <_>>( ) . join( ", " )
213+ aleo_reserved_keywords ( ) . collect:: <Vec <_>>( ) . join( ", " )
210214 ) ;
211215 return false ;
212216 }
@@ -223,7 +227,7 @@ fn is_valid_package_name(name: &str) -> bool {
223227/// Get the list of all reserved and restricted keywords from snarkVM.
224228/// These keywords cannot be used as program names.
225229/// See: https://github.com/ProvableHQ/snarkVM/blob/046a2964f75576b2c4afbab9aa9eabc43ceb6dc3/synthesizer/program/src/lib.rs#L192
226- pub fn reserved_keywords ( ) -> impl Iterator < Item = & ' static str > {
230+ pub fn aleo_reserved_keywords ( ) -> impl Iterator < Item = & ' static str > {
227231 use snarkvm:: prelude:: { Program , TestnetV0 } ;
228232
229233 // Flatten RESTRICTED_KEYWORDS by ignoring ConsensusVersion
@@ -232,6 +236,14 @@ pub fn reserved_keywords() -> impl Iterator<Item = &'static str> {
232236 Program :: < TestnetV0 > :: KEYWORDS . iter ( ) . copied ( ) . chain ( restricted)
233237}
234238
239+ fn is_leo_keyword ( name : & str ) -> bool {
240+ leo_parser_rowan:: is_keyword ( name)
241+ }
242+
243+ fn is_aleo_keyword ( name : & str ) -> bool {
244+ aleo_reserved_keywords ( ) . any ( |kw| kw == name)
245+ }
246+
235247/// Creates a configured ureq agent for Leo network requests.
236248///
237249/// Disables `http_status_as_error` so 4xx/5xx responses return `Ok(Response)`
@@ -351,3 +363,31 @@ pub fn filename_no_aleo_extension(path: &Path) -> Option<&str> {
351363fn filename_no_extension < ' a > ( path : & ' a Path , extension : & ' static str ) -> Option < & ' a str > {
352364 path. file_name ( ) . and_then ( |os_str| os_str. to_str ( ) ) . and_then ( |s| s. strip_suffix ( extension) )
353365}
366+
367+ #[ cfg( test) ]
368+ mod tests {
369+ use super :: { Package , is_valid_library_name, is_valid_program_name} ;
370+
371+ #[ test]
372+ fn package_names_reject_leo_keywords ( ) {
373+ assert ! ( !is_valid_program_name( "in.aleo" ) ) ;
374+ assert ! ( !is_valid_library_name( "in" ) ) ;
375+ }
376+
377+ #[ test]
378+ fn package_names_accept_keyword_prefixes ( ) {
379+ assert ! ( is_valid_program_name( "inside.aleo" ) ) ;
380+ assert ! ( is_valid_library_name( "inside" ) ) ;
381+ }
382+
383+ #[ test]
384+ fn package_initialize_rejects_leo_keyword_program_names ( ) {
385+ let dir = std:: env:: temp_dir ( ) . join ( format ! ( "leo_keyword_program_name_{}" , std:: process:: id( ) ) ) ;
386+ let _ = std:: fs:: remove_dir_all ( & dir) ;
387+ std:: fs:: create_dir_all ( & dir) . unwrap ( ) ;
388+
389+ assert ! ( Package :: initialize( "in" , & dir, false ) . is_err( ) ) ;
390+
391+ std:: fs:: remove_dir_all ( & dir) . unwrap ( ) ;
392+ }
393+ }
0 commit comments