Fix concatenation of audio captcha wav files (#3350)
* Fix concatenation of audio captcha wav files * Log errors rather than crashing * Return Result from captcha_as_wav_base64 * Change to return LemmyError * Check for wav write error, format * Remove unused import * Rewrite to avoid clippy warnings
This commit is contained in:
parent
7d3894d5dd
commit
fcc010b5dc
3 changed files with 34 additions and 8 deletions
|
@ -30,6 +30,7 @@ captcha = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
|
wav = "1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -3,6 +3,7 @@ use captcha::Captcha;
|
||||||
use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex};
|
use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex};
|
||||||
use lemmy_db_schema::source::local_site::LocalSite;
|
use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_utils::{error::LemmyError, utils::slurs::check_slurs};
|
use lemmy_utils::{error::LemmyError, utils::slurs::check_slurs};
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
mod comment;
|
mod comment;
|
||||||
mod comment_report;
|
mod comment_report;
|
||||||
|
@ -22,18 +23,42 @@ pub trait Perform {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the captcha to a base64 encoded wav audio file
|
/// Converts the captcha to a base64 encoded wav audio file
|
||||||
pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String {
|
pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> Result<String, LemmyError> {
|
||||||
let letters = captcha.as_wav();
|
let letters = captcha.as_wav();
|
||||||
|
|
||||||
let mut concat_letters: Vec<u8> = Vec::new();
|
// Decode each wav file, concatenate the samples
|
||||||
|
let mut concat_samples: Vec<i16> = Vec::new();
|
||||||
|
let mut any_header: Option<wav::Header> = None;
|
||||||
for letter in letters {
|
for letter in letters {
|
||||||
let bytes = letter.unwrap_or_default();
|
let mut cursor = Cursor::new(letter.unwrap_or_default());
|
||||||
concat_letters.extend(bytes);
|
let (header, samples) = wav::read(&mut cursor)?;
|
||||||
|
any_header = Some(header);
|
||||||
|
if let Some(samples16) = samples.as_sixteen() {
|
||||||
|
concat_samples.extend(samples16);
|
||||||
|
} else {
|
||||||
|
return Err(LemmyError::from_message("couldnt_create_audio_captcha"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to base64
|
// Encode the concatenated result as a wav file
|
||||||
base64::encode(concat_letters)
|
let mut output_buffer = Cursor::new(vec![]);
|
||||||
|
let header = match any_header {
|
||||||
|
Some(header) => header,
|
||||||
|
None => return Err(LemmyError::from_message("couldnt_create_audio_captcha")),
|
||||||
|
};
|
||||||
|
let wav_write_result = wav::write(
|
||||||
|
header,
|
||||||
|
&wav::BitDepth::Sixteen(concat_samples),
|
||||||
|
&mut output_buffer,
|
||||||
|
);
|
||||||
|
if let Err(e) = wav_write_result {
|
||||||
|
return Err(LemmyError::from_error_message(
|
||||||
|
e,
|
||||||
|
"couldnt_create_audio_captcha",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(base64::encode(output_buffer.into_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check size of report and remove whitespace
|
/// Check size of report and remove whitespace
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl Perform for GetCaptcha {
|
||||||
|
|
||||||
let png = captcha.as_base64().expect("failed to generate captcha");
|
let png = captcha.as_base64().expect("failed to generate captcha");
|
||||||
|
|
||||||
let wav = captcha_as_wav_base64(&captcha);
|
let wav = captcha_as_wav_base64(&captcha)?;
|
||||||
|
|
||||||
let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
|
let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
|
||||||
// Stores the captcha item in the db
|
// Stores the captcha item in the db
|
||||||
|
|
Loading…
Reference in a new issue