1
- use bstr:: { BStr , BString } ;
1
+ use bstr:: { BStr , BString , ByteSlice } ;
2
2
3
3
///
4
4
#[ allow( clippy:: empty_docs) ]
@@ -70,7 +70,10 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
70
70
}
71
71
72
72
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 ( ) {
74
77
match byte {
75
78
b'\\' | b'^' | b':' | b'[' | b'?' | b' ' | b'~' | b'\0' ..=b'\x1F' | b'\x7F' => {
76
79
if let Some ( out) = out. as_mut ( ) {
@@ -121,9 +124,36 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
121
124
}
122
125
}
123
126
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
+
124
143
if let Some ( out) = out. as_mut ( ) {
125
144
out. push ( * c)
126
145
}
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
+ }
127
157
}
128
158
}
129
159
previous = * byte;
@@ -137,30 +167,21 @@ pub(crate) fn name_inner(input: &BStr, mode: Mode) -> Result<Option<BString>, na
137
167
out. remove ( 0 ) ;
138
168
}
139
169
}
140
- if input[ 0 ] == b'.' {
170
+ if out . as_ref ( ) . map_or ( input, |b| b . as_bstr ( ) ) [ 0 ] == b'.' {
141
171
if let Some ( out) = out. as_mut ( ) {
142
172
out[ 0 ] = b'-' ;
143
173
} else {
144
174
return Err ( name:: Error :: StartsWithDot ) ;
145
175
}
146
176
}
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'.' {
148
179
if let Some ( out) = out. as_mut ( ) {
149
180
let last = out. len ( ) - 1 ;
150
181
out[ last] = b'-' ;
151
182
} else {
152
183
return Err ( name:: Error :: EndsWithDot ) ;
153
184
}
154
185
}
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
- }
165
186
Ok ( out)
166
187
}
0 commit comments