1- use bstr:: { BStr , BString } ;
1+ use bstr:: { BStr , BString , ByteSlice } ;
22
33///
44#[ allow( clippy:: empty_docs) ]
@@ -70,7 +70,10 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
7070 }
7171
7272 let mut previous = 0 ;
73- for byte in input. iter ( ) {
73+ let mut component_start;
74+ let mut component_end = 0 ;
75+ let last = input. len ( ) - 1 ;
76+ for ( byte_pos, byte) in input. iter ( ) . enumerate ( ) {
7477 match byte {
7578 b'\\' | b'^' | b':' | b'[' | b'?' | b' ' | b'~' | b'\0' ..=b'\x1F' | b'\x7F' => {
7679 if let Some ( out) = out. as_mut ( ) {
@@ -121,9 +124,36 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
121124 }
122125 }
123126 c => {
127+ if * c == b'/' {
128+ component_start = component_end;
129+ component_end = byte_pos;
130+
131+ if input[ component_start..component_end] . ends_with_str ( ".lock" ) {
132+ if let Some ( out) = out. as_mut ( ) {
133+ while out. ends_with ( b".lock" ) {
134+ let len_without_suffix = out. len ( ) - b".lock" . len ( ) ;
135+ out. truncate ( len_without_suffix) ;
136+ }
137+ } else {
138+ return Err ( name:: Error :: LockFileSuffix ) ;
139+ }
140+ }
141+ }
142+
124143 if let Some ( out) = out. as_mut ( ) {
125144 out. push ( * c)
126145 }
146+
147+ if byte_pos == last && input[ component_end + 1 ..] . ends_with_str ( ".lock" ) {
148+ if let Some ( out) = out. as_mut ( ) {
149+ while out. ends_with ( b".lock" ) {
150+ let len_without_suffix = out. len ( ) - b".lock" . len ( ) ;
151+ out. truncate ( len_without_suffix) ;
152+ }
153+ } else {
154+ return Err ( name:: Error :: LockFileSuffix ) ;
155+ }
156+ }
127157 }
128158 }
129159 previous = * byte;
@@ -137,30 +167,21 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
137167 out. remove ( 0 ) ;
138168 }
139169 }
140- if input[ 0 ] == b'.' {
170+ if out . as_ref ( ) . map_or ( input, |b| b . as_bstr ( ) ) [ 0 ] == b'.' {
141171 if let Some ( out) = out. as_mut ( ) {
142172 out[ 0 ] = b'-' ;
143173 } else {
144174 return Err ( name:: Error :: StartsWithDot ) ;
145175 }
146176 }
147- if input[ input. len ( ) - 1 ] == b'.' {
177+ let last = out. as_ref ( ) . map_or ( input, |b| b. as_bstr ( ) ) . len ( ) - 1 ;
178+ if out. as_ref ( ) . map_or ( input, |b| b. as_bstr ( ) ) [ last] == b'.' {
148179 if let Some ( out) = out. as_mut ( ) {
149180 let last = out. len ( ) - 1 ;
150181 out[ last] = b'-' ;
151182 } else {
152183 return Err ( name:: Error :: EndsWithDot ) ;
153184 }
154185 }
155- if input. ends_with ( b".lock" ) {
156- if let Some ( out) = out. as_mut ( ) {
157- while out. ends_with ( b".lock" ) {
158- let len_without_suffix = out. len ( ) - b".lock" . len ( ) ;
159- out. truncate ( len_without_suffix) ;
160- }
161- } else {
162- return Err ( name:: Error :: LockFileSuffix ) ;
163- }
164- }
165186 Ok ( out)
166187}
0 commit comments