Skip to content

Conversation

@Ellpeck
Copy link
Member

@Ellpeck Ellpeck commented Nov 11, 2025

No description provided.

@Ellpeck Ellpeck requested a review from EagleoutIce November 11, 2025 13:55
@Ellpeck
Copy link
Member Author

Ellpeck commented Nov 11, 2025

Hmm I don't know if this is even a potential valid solution at all, but atm it doesn't account for something like

if (2 < 1) { set.seed(17) }
if (1 < 0) { runif(1) }

because both are non-exhaustive branch coverages, but not of the same branches, so .. bleh

@Ellpeck
Copy link
Member Author

Ellpeck commented Nov 11, 2025

yea i dunno i can't figure out how to do this correctly @EagleoutIce :(

// function calls are already taken care of through the LastCall enrichment itself
for(const f of func ?? []) {
if(isConstantArgument(dataflow.graph, f, 0)) {
if(isConstantArgument(dataflow.graph, f, 0) && (dfgElement.cds === f.cds || happensInEveryBranch(f.cds))) {
Copy link
Member

Choose a reason for hiding this comment

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

the happensInEveryBranch should happen under the assumptions of the dfgElement.cds

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you mean by "under the assumptions"?

Copy link
Member

Choose a reason for hiding this comment

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

this should be covered by the tests below :D because technically, i think, we have to remove the dfgElement.cds from f.cds/not consider them if they are on the same path (the if(u) { set.seed() .. if(b) runif() } should catch that)

}))
// filter by calls that aren't preceded by a randomness producer
.filter(element => {
const dfgElement = dataflow.graph.getVertex(element.searchElement.node.info.id) as DataflowGraphVertexInfo;
Copy link
Member

Choose a reason for hiding this comment

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

Can we be sure this exists?

assertLinter('condition true', parser, 'if(TRUE) { set.seed(17); }\nrunif(1);', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
assertLinter('condition unclear', parser, 'if(1 < 0) { set.seed(17); }\nrunif(1);', 'seeded-randomness',
[{ range: [2,1,2,8], function: 'runif', certainty: LintingResultCertainty.Certain }], { consumerCalls: 1, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 1 });
assertLinter('condition unclear after definite seed', parser, 'set.seed(17); if(1 < 0) { set.seed(17); }\nrunif(1);', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
Copy link
Member

Choose a reason for hiding this comment

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

Please use conditionals that are not dead (because we will detect them in the future) stick with uand runif

[{ range: [2,1,2,8], function: 'runif', certainty: LintingResultCertainty.Certain }], { consumerCalls: 1, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
assertLinter('condition true', parser, 'if(TRUE) { set.seed(17); }\nrunif(1);', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
assertLinter('condition unclear', parser, 'if(1 < 0) { set.seed(17); }\nrunif(1);', 'seeded-randomness',
[{ range: [2,1,2,8], function: 'runif', certainty: LintingResultCertainty.Certain }], { consumerCalls: 1, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 1 });
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we demote this from a certain guess?

[{ range: [2,1,2,8], function: 'runif', certainty: LintingResultCertainty.Certain }], { consumerCalls: 1, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 1 });
assertLinter('condition unclear after definite seed', parser, 'set.seed(17); if(1 < 0) { set.seed(17); }\nrunif(1);', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
assertLinter('condition exhaustive', parser, 'if(1 < 0) { set.seed(17); } else { set.seed(18); }\nrunif(1);', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
assertLinter('condition reversed', parser, 'set.seed(17);\nif(1 < 0) { runif(1) }', 'seeded-randomness', [], { consumerCalls: 1, callsWithFunctionProducers: 1, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0 });
Copy link
Member

Choose a reason for hiding this comment

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

Could you also include

  1. loops
  2. nested ifs?
  3. the random use being part of the same if path
  4. nestes ifs with the random use being nested in the if, e.g. if(u) { set.seed() .. if(b) runif() } (which shouldn't trigger)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unseeded randomness not detected if seed function potentially unreachable

3 participants