@@ -141,7 +141,7 @@ func (p *Plugin) Exec() error {
141141
142142 // Validate strip prefix pattern and precompile regex once
143143 normalizedStrip := strings .ReplaceAll (p .StripPrefix , "\\ " , "/" )
144- if p .StripPrefix != "" {
144+ if p .StripPrefix != "" && strings . HasPrefix ( normalizedStrip , "/" ) {
145145 if err := validateStripPrefix (p .StripPrefix ); err != nil {
146146 log .WithFields (log.Fields {
147147 "error" : err ,
@@ -152,7 +152,7 @@ func (p *Plugin) Exec() error {
152152 }
153153
154154 var compiled * regexp.Regexp
155- if normalizedStrip != "" && strings .ContainsAny (normalizedStrip , "*?" ) {
155+ if normalizedStrip != "" && strings .HasPrefix ( normalizedStrip , "/" ) && strings . ContainsAny (normalizedStrip , "*?" ) {
156156 var err error
157157 compiled , err = patternToRegex (normalizedStrip )
158158 if err != nil {
@@ -172,30 +172,49 @@ func (p *Plugin) Exec() error {
172172 continue
173173 }
174174
175- // Preview stripping (using precompiled regex when available )
175+ // Preview stripping (wildcard for absolute patterns, literal for relative patterns )
176176 stripped := match
177177 matched := false
178178 if normalizedStrip != "" {
179- var err error
180- stripped , matched , err = stripWildcardPrefixWithRegex (match , normalizedStrip , compiled )
181- if err != nil {
182- log .WithFields (log.Fields {
183- "error" : err ,
184- "path" : match ,
185- "pattern" : p .StripPrefix ,
186- }).Warn ("Failed to strip prefix, using original path" )
187- stripped = match
179+ if strings .HasPrefix (normalizedStrip , "/" ) {
180+ var err error
181+ stripped , matched , err = stripWildcardPrefixWithRegex (match , normalizedStrip , compiled )
182+ if err != nil {
183+ log .WithFields (log.Fields {
184+ "error" : err ,
185+ "path" : match ,
186+ "pattern" : p .StripPrefix ,
187+ }).Warn ("Failed to strip prefix, using original path" )
188+ stripped = match
189+ }
190+ } else {
191+ // Backward-compat: literal TrimPrefix for relative strip_prefix (no leading '/')
192+ m := filepath .ToSlash (match )
193+ trimmed := strings .TrimPrefix (m , normalizedStrip )
194+ if trimmed != m {
195+ matched = true
196+ stripped = trimmed
197+ } else {
198+ stripped = match
199+ }
188200 }
189201 }
190202 if matched {
191203 anyMatched = true
192204 }
193205
194- // Build final key (ensure relative component for join)
195- rel := strings .TrimPrefix (filepath .ToSlash (stripped ), "/" )
196- target := filepath .ToSlash (filepath .Join (p .Target , rel ))
197- if ! strings .HasPrefix (target , "/" ) {
198- target = "/" + target
206+ // Build final key
207+ var target string
208+ if normalizedStrip != "" && ! strings .HasPrefix (normalizedStrip , "/" ) {
209+ // Relative strip_prefix: use master resolveKey behavior
210+ target = resolveKey (p .Target , filepath .ToSlash (match ), p .StripPrefix )
211+ } else {
212+ // Absolute strip_prefix (wildcards): join stripped suffix under target
213+ rel := strings .TrimPrefix (filepath .ToSlash (stripped ), "/" )
214+ target = filepath .ToSlash (filepath .Join (p .Target , rel ))
215+ if ! strings .HasPrefix (target , "/" ) {
216+ target = "/" + target
217+ }
199218 }
200219
201220 contentType := matchExtension (match , p .ContentType )
@@ -376,21 +395,7 @@ func assumeRole(roleArn, roleSessionName, externalID string) *credentials.Creden
376395// resolveKey is a helper function that returns s3 object key where file present at srcPath is uploaded to.
377396// srcPath is assumed to be in forward slash format
378397func resolveKey (target , srcPath , stripPrefix string ) string {
379- // Use wildcard-aware prefix stripping
380- stripped , err := stripWildcardPrefix (srcPath , stripPrefix )
381- if err != nil {
382- // Log error but continue with original path
383- log .WithFields (log.Fields {
384- "error" : err ,
385- "path" : srcPath ,
386- "pattern" : stripPrefix ,
387- }).Warn ("Failed to strip prefix, using original path" )
388- stripped = srcPath
389- }
390- // Ensure we never drop the target when the stripped path is absolute.
391- // Always join with a relative path component.
392- stripped = strings .TrimPrefix (stripped , "/" )
393- key := filepath .Join (target , stripped )
398+ key := filepath .Join (target , strings .TrimPrefix (srcPath , filepath .ToSlash (stripPrefix )))
394399 key = filepath .ToSlash (key )
395400 if ! strings .HasPrefix (key , "/" ) {
396401 key = "/" + key
0 commit comments