Reject dice pool expressions over 100 elements.

This commit is contained in:
projectmoon 2020-10-16 22:02:25 +00:00 committed by ProjectMoon
parent d0a1f59ec7
commit 3b70891b0a
2 changed files with 35 additions and 1 deletions

View File

@ -11,6 +11,9 @@ use thiserror::Error;
pub enum DiceRollingError {
#[error("variable not found: {0}")]
VariableNotFound(String),
#[error("dice pool expression too large")]
ExpressionTooLarge,
}
#[derive(Debug, PartialEq, Eq, Clone)]
@ -370,6 +373,10 @@ fn roll_dice<R: DieRoller>(
pool: &DicePoolWithContext,
roller: &mut R,
) -> Result<RolledDicePool, BotError> {
if pool.0.amounts.len() > 100 {
return Err(DiceRollingError::ExpressionTooLarge.into());
}
let num_dice = calculate_dice_amount(&pool)?;
let rolls: Vec<i32> = (0..num_dice)
.flat_map(|_| roll_die(roller, &pool.0))
@ -531,6 +538,33 @@ mod tests {
assert_eq!(5, roll.num_dice);
}
#[test]
fn rejects_large_expression_test() {
let db = Database::new(&sled::open(tempdir().unwrap()).unwrap());
let ctx = Context::new(&db, "roomid", "username", "message");
let mut amounts = vec![];
for _ in 0..500 {
amounts.push(Amount {
operator: Operator::Plus,
element: Element::Number(1),
});
}
let pool = DicePool::new(amounts, DicePoolModifiers::default());
let pool_with_ctx = DicePoolWithContext(&pool, &ctx);
let mut roller = SequentialDieRoller::new(vec![1, 2, 3, 4, 5]);
let result = roll_dice(&pool_with_ctx, &mut roller);
assert!(matches!(
result,
Err(BotError::DiceRollingError(
DiceRollingError::ExpressionTooLarge
))
));
}
#[test]
fn can_resolve_variables_test() {
let db = Database::new(&sled::open(tempdir().unwrap()).unwrap());

View File

@ -57,7 +57,7 @@ pub enum BotError {
DiceParsingError(#[from] crate::cofd::parser::DiceParsingError),
#[error("dice pool roll error: {0}")]
DicePoolError(#[from] DiceRollingError),
DiceRollingError(#[from] DiceRollingError),
#[error("variable parsing error: {0}")]
VariableParsingError(#[from] crate::variables::VariableParsingError),