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:
Dominic Mazzoni 2023-06-30 03:36:38 -07:00 committed by GitHub
parent 7d3894d5dd
commit fcc010b5dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 8 deletions

View file

@ -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 }

View file

@ -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

View file

@ -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