Skip to main content

max / makenotwork

server: minor audit polish (5 fixes from Ultra Fuzz Run #1) - validate.rs: render "Must be at least 2 characters" for 1-char slugs across project/collection/blog endpoints; empty stays blank - promo_codes.rs:291: document why the final param_idx increment is elided (unused_assignments) so the next added field knows to restore - main.rs: explicit .with_http_only(true) on SessionManagerLayer - versions.rs: LEAST(SUM, i64::MAX)::BIGINT clamp before cast to guard against pathological row counts overflowing the i64 - billing.rs: tip-refund lookup now logs an explicit error line via inspect_err before propagating Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-25 19:55 UTC
Commit: afb8766ba696be448ddf1bccca1f7ff2eb5ab30d
Parent: e78c5d1
5 files changed, +48 insertions, -8 deletions
@@ -288,7 +288,9 @@ pub async fn update_promo_code(
288 288 }
289 289 if max_uses.is_some() {
290 290 sets.push(format!("max_uses = ${param_idx}"));
291 - // param_idx += 1;
291 + // Final SET clause; param_idx is never read after this point, so the
292 + // increment is elided to avoid an unused_assignments warning. Restore
293 + // it if a new optional field is added below.
292 294 }
293 295
294 296 if sets.is_empty() {
@@ -317,8 +317,11 @@ pub async fn delete_version(pool: &PgPool, version_id: VersionId) -> Result<()>
317 317 /// Sum all version file sizes for a given item (for storage decrement on item delete).
318 318 #[tracing::instrument(skip_all)]
319 319 pub async fn sum_file_sizes_for_item(pool: &PgPool, item_id: super::ItemId) -> Result<i64> {
320 + // SUM over many bigints widens to NUMERIC in Postgres; cap at i64::MAX
321 + // before casting back to BIGINT so a pathological row count can't overflow
322 + // the i64 the rest of the codebase passes around.
320 323 let total: i64 = sqlx::query_scalar(
321 - "SELECT COALESCE(SUM(file_size_bytes)::BIGINT, 0) FROM versions WHERE item_id = $1 AND file_size_bytes IS NOT NULL",
324 + "SELECT COALESCE(LEAST(SUM(file_size_bytes), 9223372036854775807)::BIGINT, 0) FROM versions WHERE item_id = $1 AND file_size_bytes IS NOT NULL",
322 325 )
323 326 .bind(item_id)
324 327 .fetch_one(pool)
@@ -113,6 +113,7 @@ async fn main() {
113 113
114 114 let session_layer = SessionManagerLayer::new(session_store)
115 115 .with_secure(secure_cookies)
116 + .with_http_only(true)
116 117 .with_same_site(SameSite::Lax) // Lax allows session on top-level navigations (OAuth redirects)
117 118 .with_expiry(Expiry::OnInactivity(CookieDuration::days(
118 119 constants::SESSION_EXPIRY_DAYS,
@@ -70,9 +70,18 @@ pub async fn validate_project_slug(
70 70 auth: AuthUser,
71 71 axum::Form(form): axum::Form<SlugForm>,
72 72 ) -> impl IntoResponse {
73 - if form.slug.len() < 2 {
73 + if form.slug.is_empty() {
74 74 return Html(String::new());
75 75 }
76 + if form.slug.len() < 2 {
77 + return Html(
78 + SaveStatusTemplate {
79 + success: false,
80 + message: "Must be at least 2 characters".to_string(),
81 + }
82 + .render_string(),
83 + );
84 + }
76 85
77 86 let slug = match Slug::new(&form.slug) {
78 87 Ok(s) => s,
@@ -119,9 +128,18 @@ pub async fn validate_collection_slug(
119 128 auth: AuthUser,
120 129 axum::Form(form): axum::Form<SlugForm>,
121 130 ) -> impl IntoResponse {
122 - if form.slug.len() < 2 {
131 + if form.slug.is_empty() {
123 132 return Html(String::new());
124 133 }
134 + if form.slug.len() < 2 {
135 + return Html(
136 + SaveStatusTemplate {
137 + success: false,
138 + message: "Must be at least 2 characters".to_string(),
139 + }
140 + .render_string(),
141 + );
142 + }
125 143
126 144 let slug = match Slug::new(&form.slug) {
127 145 Ok(s) => s,
@@ -152,9 +170,18 @@ pub async fn validate_blog_slug(
152 170 auth: AuthUser,
153 171 axum::Form(form): axum::Form<BlogSlugForm>,
154 172 ) -> impl IntoResponse {
155 - if form.slug.len() < 2 {
173 + if form.slug.is_empty() {
156 174 return Html(String::new());
157 175 }
176 + if form.slug.len() < 2 {
177 + return Html(
178 + SaveStatusTemplate {
179 + success: false,
180 + message: "Must be at least 2 characters".to_string(),
181 + }
182 + .render_string(),
183 + );
184 + }
158 185
159 186 let slug = match Slug::new(&form.slug) {
160 187 Ok(s) => s,
@@ -344,10 +344,17 @@ pub(super) async fn handle_charge_refunded(
344 344 );
345 345 } else {
346 346 // No transaction found — check if this was a tip refund
347 - if db::tips::refund_tip_by_payment_intent(&state.db, payment_intent_id)
347 + let tip_refunded = db::tips::refund_tip_by_payment_intent(&state.db, payment_intent_id)
348 348 .await
349 - .context("refund tip")?
350 - {
349 + .inspect_err(|e| {
350 + tracing::error!(
351 + payment_intent_id = %payment_intent_id,
352 + error = ?e,
353 + "tip refund lookup failed"
354 + );
355 + })
356 + .context("refund tip")?;
357 + if tip_refunded {
351 358 tracing::info!(payment_intent_id = %payment_intent_id, "tip refund processed");
352 359 } else {
353 360 // No matching transaction or tip — the payment webhook likely hasn't