Skip to content

Commit

Permalink
Merge pull request #1534 from forcedotcom/release-4.3.1
Browse files Browse the repository at this point in the history
RELEASE @W-16153325@ Conducting v4.3.2 patch release
  • Loading branch information
jfeingold35 authored Jul 3, 2024
2 parents 3e8e7c9 + 2cdd033 commit 1b58848
Show file tree
Hide file tree
Showing 11 changed files with 1,153 additions and 920 deletions.
40 changes: 28 additions & 12 deletions .github/workflows/create-release-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ jobs:
with:
node-version: 'lts/*' # Always use Node LTS for building dependencies.
- run: yarn
# Increment the version as desired.
- name: Increment version
# Increment the version as desired locally, without actually commiting anything.
- name: Locally increment version
run: |
# A workflow dispatch event lets the user specify what release type they want.
if [[ "${{ github.event_name }}" = "workflow_dispatch" ]]; then
Expand All @@ -72,22 +72,25 @@ jobs:
fi
# Increment the version as needed.
npm --no-git-tag-version version $RELEASE_TYPE
# Create the new branch as a direct copy of `dev` and push it to GitHub so the API can
# interact with it later.
- id: create-branch
# The branch protection rule for `release-x.y.z` branches prevents pushing commits directly. To work around this,
# we create an interim branch that we _can_ push commits to, and we'll do our version bookkeeping in that branch
# instead.
- id: create-interim-branch
name: Create interim branch
run: |
NEW_VERSION=$(jq -r ".version" package.json)
git checkout -b release-$NEW_VERSION
# Push the branch immediately without committing anything.
git push --set-upstream origin release-$NEW_VERSION
# Output the branch name so we can use it in later jobs.
echo "branch_name=release-$NEW_VERSION" >> "$GITHUB_OUTPUT"
# Update our dependencies.
INTERIM_BRANCH_NAME=${NEW_VERSION}-interim
# Create and check out the interim branch.
git checkout -b $INTERIM_BRANCH_NAME
# Immediately push the interim branch with no changes, so GraphQL can push to it later.
git push --set-upstream origin $INTERIM_BRANCH_NAME
# Update dependencies.
- run: |
yarn upgrade
node tools/UpdateRetireJsVulns.js
# Use the GraphQL API to create a signed commit with the various changes.
- run: |
- name: Commit to interim branch
run: |
# GraphQL needs to know what branch to push to.
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# GraphQL needs a message for the commit.
Expand Down Expand Up @@ -130,6 +133,19 @@ jobs:
}
}
}'
# Now that we've done our bookkeeping commits on the interim branch, use it as the base for the real release branch.
- name: Create release branch
id: create-branch
run: |
# The commit happened on the remote end, not ours, so we need to clean the directory and pull.
git checkout -- .
git pull
# Now we can create the actual release branch.
NEW_VERSION=$(jq -r ".version" package.json)
git checkout -b release-$NEW_VERSION
git push --set-upstream origin release-$NEW_VERSION
# Output the branch name so we can use it in later jobs.
echo "branch_name=release-$NEW_VERSION" >> "$GITHUB_OUTPUT"
# Run all the various tests against the newly created branch.
test-release-branch:
needs: create-release-branch
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/production-heartbeat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
- run: mkdir smoke-test-results

# === Set our environment variables, either using default values or the repo's secrets ===
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@salesforce/sfdx-scanner",
"description": "Static code scanner that applies quality and security rules to Apex code, and provides feedback.",
"version": "4.3.0",
"version": "4.3.2",
"author": "Salesforce Code Analyzer Team",
"bugs": "https://github.com/forcedotcom/sfdx-scanner/issues",
"dependencies": {
Expand Down
159 changes: 159 additions & 0 deletions retire-js/RetireJsVulns.json
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,59 @@
"https://tiny.cloud/docs/tinymce/6/6.7.3-release-notes/"
]
},
{
"atOrAbove": "0",
"below": "5.11.0",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noneditable_regexp option",
"CVE": [
"CVE-2024-38356"
],
"githubID": "GHSA-9hcv-j9pv-qmph"
},
"info": [
"https://github.com/advisories/GHSA-9hcv-j9pv-qmph",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-9hcv-j9pv-qmph",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38356",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/latest/7.2-release-notes/#overview"
]
},
{
"atOrAbove": "0",
"below": "5.11.0",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noscript elements",
"CVE": [
"CVE-2024-38357"
],
"githubID": "GHSA-w9jx-4g6g-rp7x"
},
"info": [
"https://github.com/advisories/GHSA-w9jx-4g6g-rp7x",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-w9jx-4g6g-rp7x",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38357",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview"
]
},
{
"atOrAbove": "6.0.0",
"below": "6.3.1",
Expand Down Expand Up @@ -1638,6 +1691,59 @@
"https://www.tiny.cloud/docs/tinymce/7/7.0-release-notes/#sandbox_iframes-editor-option-is-now-defaulted-to-true"
]
},
{
"atOrAbove": "6.0.0",
"below": "6.8.4",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noneditable_regexp option",
"CVE": [
"CVE-2024-38356"
],
"githubID": "GHSA-9hcv-j9pv-qmph"
},
"info": [
"https://github.com/advisories/GHSA-9hcv-j9pv-qmph",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-9hcv-j9pv-qmph",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38356",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/latest/7.2-release-notes/#overview"
]
},
{
"atOrAbove": "6.0.0",
"below": "6.8.4",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noscript elements",
"CVE": [
"CVE-2024-38357"
],
"githubID": "GHSA-w9jx-4g6g-rp7x"
},
"info": [
"https://github.com/advisories/GHSA-w9jx-4g6g-rp7x",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-w9jx-4g6g-rp7x",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38357",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview"
]
},
{
"atOrAbove": "0",
"below": "7.0.0",
Expand All @@ -1661,6 +1767,59 @@
"https://www.tiny.cloud/docs/tinymce/6/6.8.1-release-notes/#new-convert_unsafe_embeds-option-that-controls-whether-object-and-embed-elements-will-be-converted-to-more-restrictive-alternatives-namely-img-for-image-mime-types-video-for-video-mime-types-audio-audio-mime-types-or-iframe-for-other-or-unspecified-mime-types",
"https://www.tiny.cloud/docs/tinymce/7/7.0-release-notes/#convert_unsafe_embeds-editor-option-is-now-defaulted-to-true"
]
},
{
"atOrAbove": "7.0.0",
"below": "7.2.0",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noneditable_regexp option",
"CVE": [
"CVE-2024-38356"
],
"githubID": "GHSA-9hcv-j9pv-qmph"
},
"info": [
"https://github.com/advisories/GHSA-9hcv-j9pv-qmph",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-9hcv-j9pv-qmph",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38356",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/latest/7.2-release-notes/#overview"
]
},
{
"atOrAbove": "7.0.0",
"below": "7.2.0",
"cwe": [
"CWE-79"
],
"severity": "medium",
"identifiers": {
"summary": "TinyMCE Cross-Site Scripting (XSS) vulnerability using noscript elements",
"CVE": [
"CVE-2024-38357"
],
"githubID": "GHSA-w9jx-4g6g-rp7x"
},
"info": [
"https://github.com/advisories/GHSA-w9jx-4g6g-rp7x",
"https://github.com/tinymce/tinymce/security/advisories/GHSA-w9jx-4g6g-rp7x",
"https://nvd.nist.gov/vuln/detail/CVE-2024-38357",
"https://github.com/tinymce/tinymce/commit/5acb741665a98e83d62b91713c800abbff43b00d",
"https://github.com/tinymce/tinymce/commit/a9fb858509f86dacfa8b01cfd34653b408983ac0",
"https://github.com/tinymce/tinymce",
"https://owasp.org/www-community/attacks/xss",
"https://www.tiny.cloud/docs/tinymce/6/6.8.4-release-notes/#overview",
"https://www.tiny.cloud/docs/tinymce/7/7.2-release-notes/#overview"
]
}
],
"extractors": {
Expand Down
8 changes: 4 additions & 4 deletions src/lib/DefaultRuleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class DefaultRuleManager implements RuleManager {
return this.catalog.getRulesMatchingFilters(filters);
}

async runRulesMatchingCriteria(filters: RuleFilter[], targets: string[], runOptions: RunOptions, engineOptions: EngineOptions): Promise<Results> {
async runRulesMatchingCriteria(filters: RuleFilter[], targets: string[], runOptions: RunOptions, engineOptions: EngineOptions, projectDir?: string): Promise<Results> {
// Declare a variable that we can later use to store the engine results, as well as something to help us track
// which engines actually ran.
let ruleResults: RuleResult[] = [];
Expand All @@ -100,7 +100,7 @@ export class DefaultRuleManager implements RuleManager {
// them all in. Note that some engines (pmd) need groups while others (eslint) need the rules.
const engineGroups = ruleGroups.filter(g => g.engine === e.getName());
const engineRules = rules.filter(r => r.engine === e.getName());
const engineTargets = await this.unpackTargets(e, targets, matchedTargets);
const engineTargets = await this.unpackTargets(e, targets, matchedTargets, projectDir);
this.logger.trace(`For ${e.getName()}, found ${engineGroups.length} groups, ${engineRules.length} rules, ${engineTargets.length} targets`);

if (e.shouldEngineRun(engineGroups, engineRules, engineTargets, engineOptions)) {
Expand Down Expand Up @@ -247,7 +247,7 @@ export class DefaultRuleManager implements RuleManager {
*
* Any items from the 'targets' array that result in a match are added to the 'matchedTargets' Set.
*/
protected async unpackTargets(engine: RuleEngine, targets: string[], matchedTargets: Set<string>): Promise<RuleTarget[]> {
protected async unpackTargets(engine: RuleEngine, targets: string[], matchedTargets: Set<string>, projectDir?: string): Promise<RuleTarget[]> {
const ruleTargets: RuleTarget[] = [];
// Ask engines for their desired target patterns.
const engineTargets = await engine.getTargetPatterns();
Expand Down Expand Up @@ -283,7 +283,7 @@ export class DefaultRuleManager implements RuleManager {

// We want to use a path matcher that can filter based on the engine's target patterns and any negative globs
// provided to us.
const pm = new PathMatcher([...engineTargets, ...negativePatterns]);
const pm = new PathMatcher([...engineTargets, ...negativePatterns], projectDir);
for (const target of positivePatterns) {
// Used to detect if the target resulted in a match
const ruleTargetsInitialLength: number = ruleTargets.length;
Expand Down
8 changes: 5 additions & 3 deletions src/lib/InputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface InputProcessor {

resolveTargetPaths(inputs: Inputs): string[];

resolveProjectDirPaths(inputs: Inputs): string[];
resolveProjectDirPaths(inputs: Inputs, displayResolvedProjectDir?: boolean): string[];

createRunOptions(inputs: Inputs, isDfa: boolean): RunOptions;

Expand All @@ -45,7 +45,7 @@ export class InputProcessorImpl implements InputProcessor {
return (inputs.path as string[]).map(p => path.resolve(untildify(p)));
}

public resolveProjectDirPaths(inputs: Inputs): string[] {
public resolveProjectDirPaths(inputs: Inputs, displayResolvedProjectDir: boolean = true): string[] {
// If projectdir is provided, then return it since at this point it has already been validated to exist
if (inputs.projectdir && (inputs.projectdir as string[]).length > 0) {
return (inputs.projectdir as string[]).map(p => path.resolve(normalize(untildify(p))))
Expand All @@ -58,7 +58,9 @@ export class InputProcessorImpl implements InputProcessor {
const commonParentFolder = getFirstCommonParentFolder(this.getAllTargetFiles(inputs));
let projectFolder: string = findFolderThatContainsSfdxProjectFile(commonParentFolder);
projectFolder = projectFolder.length > 0 ? projectFolder : commonParentFolder
this.displayInfoOnlyOnce('info.resolvedProjectDir', [projectFolder])
if (displayResolvedProjectDir) {
this.displayInfoOnlyOnce('info.resolvedProjectDir', [projectFolder])
}
return [projectFolder];
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/RuleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ export interface RuleManager {
/**
* @param engineOptions - see RuleEngine#run
*/
runRulesMatchingCriteria(filters: RuleFilter[], target: string[], runOptions: RunOptions, engineOptions: EngineOptions): Promise<Results>;
runRulesMatchingCriteria(filters: RuleFilter[], target: string[], runOptions: RunOptions, engineOptions: EngineOptions, projectDir?: string): Promise<Results>;
}
4 changes: 3 additions & 1 deletion src/lib/actions/AbstractRunAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ export abstract class AbstractRunAction implements Action {
const resultsProcessor: ResultsProcessor = this.resultsProcessorFactory.createResultsProcessor(
this.display, outputOptions, jsonReturnValueHolder);

const primaryProjectDir: string = this.inputProcessor.resolveProjectDirPaths(inputs, false)[0];

// TODO: Inject RuleManager as a dependency to improve testability by removing coupling to runtime implementation
const ruleManager: RuleManager = await Controller.createRuleManager();

try {
const results: Results = await ruleManager.runRulesMatchingCriteria(filters, targetPaths, runOptions, engineOptions);
const results: Results = await ruleManager.runRulesMatchingCriteria(filters, targetPaths, runOptions, engineOptions, primaryProjectDir);
this.logger.trace(`Processing output with format ${outputOptions.format}`);
await resultsProcessor.processResults(results);
return jsonReturnValueHolder.get();
Expand Down
Loading

0 comments on commit 1b58848

Please sign in to comment.