| 284 | } |
| 285 | |
| 286 | func reducePathComponents(components []string) []string { |
| 287 | if len(components) == 0 { |
| 288 | return []string{} |
| 289 | } |
| 290 | reduced := []string{components[0]} |
| 291 | for i := 1; i < len(components); i++ { |
| 292 | component := components[i] |
| 293 | if component == "" { |
| 294 | continue |
| 295 | } |
| 296 | if component == "." { |
| 297 | continue |
| 298 | } |
| 299 | if component == ".." { |
| 300 | if len(reduced) > 1 { |
| 301 | if reduced[len(reduced)-1] != ".." { |
| 302 | reduced = reduced[:len(reduced)-1] |
| 303 | continue |
| 304 | } |
| 305 | } else if reduced[0] != "" { |
| 306 | continue |
| 307 | } |
| 308 | } |
| 309 | reduced = append(reduced, component) |
| 310 | } |
| 311 | return reduced |
| 312 | } |
| 313 | |
| 314 | // Combines and resolves paths. If a path is absolute, it replaces any previous path. Any |
| 315 | // `.` and `..` path components are resolved. Trailing directory separators are preserved. |