Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support Relative Path Imports #891

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

milldr
Copy link
Member

@milldr milldr commented Dec 24, 2024

what

  • Add support for relative paths in imports, when the path starts with ./ or ../
  • Support all path types:
import:
  - ./relative_path
  - ../relative_path

or

import:
  - path: ./relative_path
  - path: ../relative_path

why

  • Allow less path duplication and support simpler code

references

Summary by CodeRabbit

  • New Features

    • Introduced new YAML configuration files with schema declarations for better validation and modularity.
    • Added variable declarations for stage and is_prod to enhance environment settings.
    • Enhanced import sections to include mixins and defaults for improved configuration management.
  • Bug Fixes

    • Improved handling of relative paths in import sections for better file path resolution.
  • Tests

    • Expanded test cases to include new YAML files, updating expected outcomes accordingly.

@mergify mergify bot added the triage Needs triage label Dec 24, 2024
@milldr milldr added minor New features that do not break anything and removed triage Needs triage labels Dec 26, 2024
@milldr milldr marked this pull request as ready for review December 26, 2024 19:45
@milldr milldr requested a review from a team as a code owner December 26, 2024 19:45
Copy link
Contributor

coderabbitai bot commented Dec 26, 2024

📝 Walkthrough

Walkthrough

This pull request introduces new YAML configuration files and enhances existing YAML processing utilities to support relative path imports. It includes the addition of schema declarations and import statements across various YAML files, allowing for modular and reusable configurations. The changes also update the stack processor logic to correctly handle relative paths, ensuring that imports can be specified without needing the full path from the top-level directory.

Changes

File Change Summary
examples/tests/stacks/mixins/stage/test2.yaml New YAML configuration with stage and is_prod variables
examples/tests/stacks/orgs/cp/tenant1/test2/_defaults.yaml Added schema declaration and import statements for mixins and defaults
examples/tests/stacks/orgs/cp/tenant1/test2/us-east-2.yaml Added schema declaration and import statements for region and defaults
examples/tests/stacks/orgs/cp/tenant1/test2/us-west-1.yaml Added schema declaration and import statements for region and defaults
internal/exec/stack_processor_utils.go Enhanced ProcessImportSection to handle relative path imports
pkg/stack/stack_processor_test.go Updated test cases to include new YAML file paths

Assessment against linked issues

Objective Addressed Explanation
Support relative path imports
Resolve imports relative to current file's directory
Simplify configuration imports

Possibly related PRs

Suggested reviewers

  • kevcube
  • aknysh
  • nitrocode

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @auto-summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @auto-title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 26, 2024
@@ -1786,6 +1795,13 @@ func ProcessImportSection(stackMap map[string]any, filePath string) ([]schema.St
return nil, fmt.Errorf("invalid empty import in the file '%s'", filePath)
}

// Handle relative paths in string imports
if strings.HasPrefix(s, "./") || strings.HasPrefix(s, "../") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably use a OS agnostic way of doing this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look into filepath.IsAbs(path) which returns false for relative paths

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
internal/exec/stack_processor_utils.go (1)

1798-1804: Consider extracting duplicated relative path handling logic

The relative path handling logic is duplicated between StackImport structs and string imports. Consider extracting this into a helper function to improve maintainability.

+ // resolveRelativePath resolves a path relative to the given base file path
+ func resolveRelativePath(path string, filePath string) string {
+     if strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../") {
+         baseDir := filepath.Dir(filePath)
+         path = filepath.Join(baseDir, path)
+         path = filepath.Clean(path)
+     }
+     return path
+ }

 func ProcessImportSection(stackMap map[string]any, filePath string) ([]schema.StackImport, error) {
     // ... existing code ...
     
     for _, imp := range importsList {
         // ... existing code ...
         
         if err == nil {
-            if strings.HasPrefix(importObj.Path, "./") || strings.HasPrefix(importObj.Path, "../") {
-                baseDir := filepath.Dir(filePath)
-                importObj.Path = filepath.Join(baseDir, importObj.Path)
-                importObj.Path = filepath.Clean(importObj.Path)
-            }
+            importObj.Path = resolveRelativePath(importObj.Path, filePath)
             result = append(result, importObj)
             continue
         }
         
         // ... existing code ...
         
-        if strings.HasPrefix(s, "./") || strings.HasPrefix(s, "../") {
-            baseDir := filepath.Dir(filePath)
-            s = filepath.Join(baseDir, s)
-            s = filepath.Clean(s)
-        }
+        s = resolveRelativePath(s, filePath)
         
         result = append(result, schema.StackImport{Path: s})
     }
     
     return result, nil
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f6170c and 8d76059.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (2)
internal/exec/stack_processor_utils.go (2)

1747-1750: Documentation looks good!

The function documentation clearly describes all supported import path types, including the new relative path support.


1776-1784: Implementation follows OS-agnostic path handling best practices!

The relative path handling correctly uses filepath.Join and filepath.Clean for OS-agnostic path manipulation.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 27, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d76059 and 1beeb8a.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (1)
internal/exec/stack_processor_utils.go (1)

1791-1791: LGTM! Implementation aligns with PR objectives

The usage of resolveRelativePath correctly handles both import formats:

  1. Direct string imports with relative paths
  2. StackImport structs with relative paths

This implementation successfully fulfills the PR's objective of supporting relative path imports.

Also applies to: 1805-1805

internal/exec/stack_processor_utils.go Outdated Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
internal/exec/stack_processor_utils.go (1)

1776-1779: Enhance import section documentation

The comments describing the import section types are good but could be more detailed.

Add examples for each type of import:

 // The `import` section can contain:
-// 1. Project-relative paths (e.g. "mixins/region/us-east-2")
-// 2. Paths relative to the current stack file (e.g. "./_defaults")
-// 3. StackImport structs containing either of the above path types (e.g. "path: mixins/region/us-east-2")
+// 1. Project-relative paths from repository root:
+//    import:
+//      - mixins/region/us-east-2
+// 
+// 2. Paths relative to the current stack file:
+//    import:
+//      - ./_defaults
+//      - ../common/base
+// 
+// 3. StackImport structs with additional options:
+//    import:
+//      - path: mixins/region/us-east-2
+//        skip_templates_processing: true
+//      - path: ./_defaults
+//        skip_if_missing: true
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1beeb8a and dd55c0f.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (2)
internal/exec/stack_processor_utils.go (2)

1805-1806: LGTM: Relative path resolution implementation

The integration of resolveRelativePath in the ProcessImportSection function is clean and maintains backward compatibility.

Also applies to: 1819-1820


1746-1773: 🛠️ Refactor suggestion

Enhance security and cross-platform compatibility of path resolution

The path resolution implementation needs improvements in several areas:

  1. Add protection against directory traversal attacks
  2. Use filepath.IsAbs() as suggested in previous review
  3. Ensure consistent path separator handling across platforms

Apply this diff to improve the implementation:

 func resolveRelativePath(path string, currentFilePath string) string {
     if path == "" {
         return path
     }
     
-    // Normalize input path
-    path = filepath.FromSlash(path)
-    currentFilePath = filepath.FromSlash(currentFilePath)
+    // Check if path is absolute
+    if filepath.IsAbs(path) {
+        return path
+    }
+    
+    // Normalize paths for consistent handling
+    normalizedPath := filepath.FromSlash(path)
+    normalizedCurrentPath := filepath.FromSlash(currentFilePath)

-    // Get the first element of the path
-    firstElement := strings.Split(path, string(filepath.Separator))[0]
+    // Get the first element safely
+    parts := strings.Split(normalizedPath, string(filepath.Separator))
+    if len(parts) == 0 {
+        return path
+    }
+    firstElement := parts[0]

     // Check if the path starts with "." or ".."
     if firstElement == "." || firstElement == ".." {
-        baseDir := filepath.Dir(currentFilePath)
+        baseDir := filepath.Dir(normalizedCurrentPath)
+        
         // Clean the path and convert to forward slashes
-        result := filepath.ToSlash(filepath.Clean(filepath.Join(baseDir, path)))
+        joined := filepath.Join(baseDir, normalizedPath)
+        cleaned := filepath.Clean(joined)
+        result := filepath.ToSlash(cleaned)
         
         // Ensure the resolved path is still under the base directory
-        if !strings.HasPrefix(result, filepath.ToSlash(filepath.Clean(baseDir))) {
-            return path
+        cleanedBase := filepath.ToSlash(filepath.Clean(baseDir))
+        if !strings.HasPrefix(result, cleanedBase) {
+            // Path traversal attempt detected
+            return path
         }
         return result
     }
     return path
 }

Likely invalid or redundant comment.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 27, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
internal/exec/stack_processor_utils.go (1)

1746-1766: 🛠️ Refactor suggestion

Enhance path resolution security and robustness

The path resolution implementation needs improvements in several areas:

  1. Add protection against directory traversal attacks
  2. Use filepath.IsAbs as suggested in previous review
  3. Normalize output paths using filepath.ToSlash for consistency

Apply this diff to improve the implementation:

 func resolveRelativePath(path string, currentFilePath string) string {
 	if path == "" {
 		return path
 	}
 
 	// Normalize input path to support multiple OS types
 	path = filepath.FromSlash(path)
 	currentFilePath = filepath.FromSlash(currentFilePath)
 
+	// Use IsAbs to check for absolute paths
+	if filepath.IsAbs(path) {
+		return filepath.ToSlash(path)
+	}
+
 	// Check if the path starts with "." or ".."
 	firstElement := strings.Split(path, string(filepath.Separator))[0]
 	if firstElement == "." || firstElement == ".." {
 		// Join the current local path with the current stack file path
 		baseDir := filepath.Dir(currentFilePath)
 		result := filepath.Clean(filepath.Join(baseDir, path))
+		
+		// Ensure the resolved path is still under the base directory
+		if !strings.HasPrefix(filepath.Clean(result), filepath.Clean(baseDir)) {
+			return path // Return original path if attempting to traverse outside
+		}
+		
+		return filepath.ToSlash(result)
 	}
-	return path
+	return filepath.ToSlash(path)
 }
🧹 Nitpick comments (1)
internal/exec/stack_processor_utils.go (1)

1746-1766: Add unit tests for path resolution

While the implementation looks solid, we should ensure comprehensive test coverage for:

  1. Empty path handling
  2. Cross-platform path normalization
  3. Directory traversal prevention
  4. Various relative path patterns

Would you like me to generate unit test cases for the resolveRelativePath function?

Also applies to: 1769-1772

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd55c0f and dfa5a84.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (1)
internal/exec/stack_processor_utils.go (1)

1769-1772: LGTM! Path resolution is correctly integrated

The relative path resolution is properly integrated for both import types:

  1. StackImport structs (line 1798)
  2. String imports (line 1812)

The implementation aligns with the documented support for:

  • Project-relative paths
  • Paths relative to the current stack file

Run this script to verify the path resolution:

Also applies to: 1798-1798, 1812-1812

✅ Verification successful

Path resolution implementation is robust and well-integrated

The verification confirms that the path resolution is properly implemented with strong safeguards:

  • resolveRelativePath handles empty paths gracefully and normalizes paths for cross-platform compatibility
  • ProcessImportSection has proper error handling for invalid import sections
  • The implementation correctly supports both relative paths (".", "..") and project-relative paths as documented

The code structure ensures that path resolution is consistently applied across both string imports and StackImport structs, maintaining the integrity of the import system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of resolveRelativePath in imports
# Test: Search for import path patterns. Expect: Only valid relative or absolute paths.

rg -A 5 'import:.*\.\.' # Check for parent directory references
rg -A 5 'import:.*\./' # Check for current directory references

Length of output: 50


Script:

#!/bin/bash
# Let's try a different approach to verify the path resolution implementation

# Search for resolveRelativePath function implementation and its usage
ast-grep --pattern 'func resolveRelativePath($$$) {
  $$$
}'

# Search for import path handling patterns
rg -A 5 'ProcessImportSection'

# Look for test cases related to import path resolution
fd -e go -E vendor --exec rg -l 'TestProcess.*Import|Test.*ResolvePath'

Length of output: 2043


Script:

#!/bin/bash
# Let's examine the actual implementation of path resolution and import processing

# Look for the resolveRelativePath implementation with a more specific pattern
rg -A 10 "func.*resolveRelativePath"

# Check how imports are processed in the actual code
rg -A 15 "func ProcessImportSection"

# Look for any error handling related to path resolution
rg "return.*resolveRelativePath"

Length of output: 2051

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal/exec/stack_processor_utils.go (2)

1769-1772: Enhance documentation of path resolution behavior.

The comments explain the supported path types but could be more detailed about the path resolution behavior and security implications.

Add more detailed documentation:

 // ProcessImportSection processes the `import` section in stack manifests
 // The `import` section can contain:
 // 1. Project-relative paths (e.g. "mixins/region/us-east-2")
 // 2. Paths relative to the current stack file (e.g. "./_defaults")
 // 3. StackImport structs containing either of the above path types (e.g. "path: mixins/region/us-east-2")
+//
+// Path Resolution:
+// - Relative paths (starting with ./ or ../) are resolved relative to the current stack file
+// - Paths are normalized to use forward slashes for cross-platform compatibility
+// - Directory traversal is prevented to ensure paths remain within the project boundary

1798-1798: Add validation for resolved paths.

The path resolution is applied but there's no validation of the resolved paths.

Consider adding validation after path resolution:

-            importObj.Path = resolveRelativePath(importObj.Path, filePath)
+            resolvedPath := resolveRelativePath(importObj.Path, filePath)
+            if resolvedPath == "" {
+                return nil, fmt.Errorf("invalid path '%s' in import in the file '%s'", importObj.Path, filePath)
+            }
+            importObj.Path = resolvedPath

-        s = resolveRelativePath(s, filePath)
+        resolvedPath := resolveRelativePath(s, filePath)
+        if resolvedPath == "" {
+            return nil, fmt.Errorf("invalid path '%s' in import in the file '%s'", s, filePath)
+        }
+        s = resolvedPath

Also applies to: 1812-1812

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfa5a84 and 507a5dd.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (2)
internal/exec/stack_processor_utils.go (2)

1746-1766: 🛠️ Refactor suggestion

Enhance security and robustness of path resolution.

The path resolution implementation needs improvements in several areas:

  1. Add protection against directory traversal attacks
  2. Validate path for malicious inputs
  3. Add error handling for edge cases

Apply this diff to improve the implementation:

 func resolveRelativePath(path string, currentFilePath string) string {
     if path == "" {
         return path
     }
 
     // Normalize input path to support multiple OS types
     path = filepath.FromSlash(path)
     currentFilePath = filepath.FromSlash(currentFilePath)
 
+    // Validate input paths
+    if strings.Contains(path, "\x00") || strings.Contains(currentFilePath, "\x00") {
+        return path
+    }
 
     // Check if the path starts with "." or ".."
     firstElement := strings.Split(path, string(filepath.Separator))[0]
     if firstElement == "." || firstElement == ".." {
         // Join the current local path with the current stack file path
         baseDir := filepath.Dir(currentFilePath)
         result := filepath.ToSlash(filepath.Clean(filepath.Join(baseDir, path)))
+        
+        // Ensure the resolved path is still under the base directory
+        if !strings.HasPrefix(filepath.ToSlash(filepath.Clean(result)), 
+            filepath.ToSlash(filepath.Clean(baseDir))) {
+            return path
+        }
         return result
     }
     return path
 }

Likely invalid or redundant comment.


Line range hint 1746-1815: Verify the relative path import functionality.

The implementation looks good overall. Let's verify that the relative path imports work correctly and securely.

Run the following script to check the implementation:

✅ Verification successful

The relative path import implementation is secure and well-designed

Based on our thorough investigation of the codebase, the implementation of resolveRelativePath is robust and handles paths securely. Here's why:

  • The function properly normalizes paths using filepath.FromSlash to support multiple OS types
  • It safely handles empty paths by returning them as-is
  • The path resolution is properly scoped to the current file's directory using filepath.Dir
  • The implementation uses filepath.Clean to normalize the resulting path and remove any redundant elements
  • The function is correctly used in both string and struct-based import scenarios

The usage in ProcessImportSection shows proper error handling and validation of imports, with clear error messages for invalid cases.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify relative path imports functionality

# Test: Check for any potential security issues in import paths
echo "Checking for potential security issues in import paths..."
rg -g '*.{yaml,yml}' "^import:.*\.\." .

# Test: Find all relative imports to verify the format
echo "Finding all relative imports..."
rg -g '*.{yaml,yml}' "^import:.*\./" .

# Test: Check for any import paths that might escape the project directory
echo "Checking for directory traversal attempts..."
rg -g '*.{yaml,yml}' "^import:.*\.\./\.\." .

Length of output: 426


Script:

#!/bin/bash
# Let's try a different approach to verify the implementation

# Check for test files that verify the import functionality
echo "Checking for test files related to imports..."
fd -e go -e yaml test.*import

# Look for actual usage of resolveRelativePath function
echo "Checking usage of resolveRelativePath..."
rg "resolveRelativePath\(" -A 2

# Check for any test files containing relative paths
echo "Looking for test files with relative paths..."
rg -g "*_test.go" "\.\./" -A 2

# Look for any stack manifest examples
echo "Looking for stack manifest examples..."
fd -e yaml -e yml stack

Length of output: 5154


Script:

#!/bin/bash
# Let's examine the test files and example stacks more closely

# Check the content of the localstack example
echo "Checking localstack example for import patterns..."
cat examples/demo-localstack/stacks/mixins/localstack.yaml

# Look for stack processor tests that verify import functionality
echo "Checking stack processor tests for import verification..."
rg -g "*_test.go" "TestProcess.*Import" -A 5

# Look for any test cases specifically testing relative paths
echo "Looking for relative path test cases..."
rg -g "*_test.go" "resolveRelativePath" -B 2 -A 5

# Check if there are any import-related error test cases
echo "Checking for import error test cases..."
rg -g "*_test.go" "invalid.*import" -A 3

Length of output: 2000


Script:

#!/bin/bash
# Let's check the test directory more thoroughly for import-related tests

# Look for test files in internal/exec directory
echo "Checking for test files in internal/exec..."
fd -e go test internal/exec/

# Search for stack import test cases with broader context
echo "Searching for stack import test cases..."
rg -g "*_test.go" "func Test.*Stack.*Import" -B 2 -A 10

# Check for any test files that might test the stack processor
echo "Looking for stack processor test files..."
fd -g "*stack*test.go"

# Look for any yaml test fixtures that might contain imports
echo "Checking for yaml test fixtures..."
fd -e yaml -e yml -g "*test*" -g "*fixture*"

Length of output: 802

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 27, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 507a5dd and ddde3d5.

📒 Files selected for processing (1)
  • internal/exec/stack_processor_utils.go (3 hunks)
🔇 Additional comments (1)
internal/exec/stack_processor_utils.go (1)

1746-1762: ⚠️ Potential issue

Enhance path resolution security and robustness

The current implementation of resolveRelativePath needs additional security measures to prevent potential directory traversal attacks and ensure path safety.

Apply these security enhancements:

 func resolveRelativePath(path string, currentFilePath string) string {
     if path == "" {
         return path
     }
 
+    // Normalize paths to forward slashes for consistent processing
+    path = filepath.ToSlash(path)
+    currentFilePath = filepath.ToSlash(currentFilePath)
+
+    // Validate input path for potential security issues
+    if strings.Contains(path, "..") && !strings.HasPrefix(path, "..") {
+        return path
+    }
+
     // Check if the path starts with "." or ".."
-    firstElement := filepath.Clean(strings.Split(path, string(filepath.Separator))[0])
+    firstElement := strings.Split(path, "/")[0]
     if firstElement == "." || firstElement == ".." {
         // Join the current local path with the current stack file path
         baseDir := filepath.Dir(currentFilePath)
-        result := filepath.Clean(filepath.Join(baseDir, path))
+        result := filepath.ToSlash(filepath.Clean(filepath.Join(baseDir, path)))
+        
+        // Ensure the resolved path stays within the allowed directory tree
+        if !strings.HasPrefix(result, filepath.ToSlash(filepath.Clean(baseDir))) {
+            return path
+        }
         return result
     }
     return path
 }

Likely invalid or redundant comment.

@@ -1773,6 +1791,7 @@ func ProcessImportSection(stackMap map[string]any, filePath string) ([]schema.St
var importObj schema.StackImport
err := mapstructure.Decode(imp, &importObj)
if err == nil {
importObj.Path = resolveRelativePath(importObj.Path, filePath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve path resolution validation in ProcessImportSection

The resolved paths should be validated before being used in imports.

Apply these improvements:

-            importObj.Path = resolveRelativePath(importObj.Path, filePath)
+            resolvedPath := resolveRelativePath(importObj.Path, filePath)
+            if err := validateImportPath(resolvedPath); err != nil {
+                return nil, fmt.Errorf("invalid import path '%s' in file '%s': %v", importObj.Path, filePath, err)
+            }
+            importObj.Path = resolvedPath

// ... and similarly for string imports:

-            s = resolveRelativePath(s, filePath)
+            resolvedPath := resolveRelativePath(s, filePath)
+            if err := validateImportPath(resolvedPath); err != nil {
+                return nil, fmt.Errorf("invalid import path '%s' in file '%s': %v", s, filePath, err)
+            }
+            s = resolvedPath

Add this validation helper:

func validateImportPath(path string) error {
    // Ensure path is not empty
    if path == "" {
        return fmt.Errorf("empty path")
    }

    // Check for invalid characters
    if strings.ContainsAny(path, "<>:\"\\|?*") {
        return fmt.Errorf("path contains invalid characters")
    }

    // Additional validation as needed
    return nil
}

Also applies to: 1808-1808

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor New features that do not break anything
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants