Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix concatenation of audio captcha wav files #3350

Merged
merged 9 commits into from
Jun 30, 2023
1 change: 1 addition & 0 deletions crates/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ captcha = { workspace = true }
anyhow = { workspace = true }
tracing = { workspace = true }
chrono = { workspace = true }
wav = "1.0.0"

[dev-dependencies]
serial_test = { workspace = true }
Expand Down
31 changes: 24 additions & 7 deletions crates/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use captcha::Captcha;
use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex};
use lemmy_db_schema::source::local_site::LocalSite;
use lemmy_utils::{error::LemmyError, utils::slurs::check_slurs};
use std::io::Cursor;
use wav;

mod comment;
mod comment_report;
Expand All @@ -22,18 +24,33 @@ pub trait Perform {
}

/// 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 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 {
let bytes = letter.unwrap_or_default();
concat_letters.extend(bytes);
let mut cursor = Cursor::new(letter.unwrap_or_default());
let (header, samples) = wav::read(&mut cursor)?;
any_header = Some(header);
let samples16 = samples.as_sixteen();
if samples16.is_none() {
return Err(LemmyError::from_message("couldnt_create_audio_captcha"));
}
concat_samples.extend(samples16.unwrap());
}

// Encode the concatenated result as a wav file
let mut output_buffer = Cursor::new(vec![]);
if any_header.is_none() {
return Err(LemmyError::from_message("couldnt_create_audio_captcha"));
}
let _ = wav::write(any_header.unwrap(),
&wav::BitDepth::Sixteen(concat_samples),
&mut output_buffer);
Copy link
Member

Choose a reason for hiding this comment

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

Are you ignoring an error here? Might have to put ? instead.

Also you need to run cargo +nightly fmt --all

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good catch. Handled that error too, and formatted.


// Convert to base64
base64::encode(concat_letters)
Ok(base64::encode(output_buffer.into_inner()))
}

/// Check size of report and remove whitespace
Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/local_user/get_captcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Perform for GetCaptcha {

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 };
// Stores the captcha item in the db
Expand Down