Skip to content

Commit 33e8b11

Browse files
committed
add krate-name validation to rustdoc parameter extraction
1 parent 1c4d0d0 commit 33e8b11

21 files changed

+452
-414
lines changed

.sqlx/query-1be3826465e3cd76738b3bfc9d46df14795d1f18830783080bf3a58b909ab16a.json

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-543694448dbb43af41dc18c29017c5b211f45f7722811fdcabea26f796d4514b.json

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-af663241b6e7d77402847d57ef9a1d69412ea5af6d0b6562644fe913bac2e1df.json

Lines changed: 0 additions & 64 deletions
This file was deleted.

.sqlx/query-bdddad099e891bb45ba3703d7144160056d6cb620c55be459ead0f95c3523035.json

Lines changed: 0 additions & 34 deletions
This file was deleted.

.sqlx/query-db8654a53a9914ebfaa15a9bcc0af66fc2f46a8b5caa5473278123403ebbd613.json

Lines changed: 0 additions & 26 deletions
This file was deleted.

.sqlx/query-e1a95bfd43982d86a56cf542fde99a6e5a42e56aedf068a3acf39f923eb32ade.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ edition = "2024"
1010

1111
[workspace]
1212
members = ["crates/*"]
13+
exclude = [
14+
"ignored",
15+
"tests",
16+
".workspace",
17+
".rustwide-docker",
18+
]
1319

1420
[dependencies]
1521
sentry = { version = "0.46.0", features = ["panic", "tracing", "tower-http", "anyhow", "backtrace"] }

src/db/types/krate_name.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use sqlx::{
66
Decode, Encode, Postgres,
77
encode::IsNull,
88
error::BoxDynError,
9-
postgres::{PgArgumentBuffer, PgTypeInfo, PgValueRef},
9+
postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef},
1010
prelude::*,
1111
};
12-
use std::{io::Write, str::FromStr};
12+
use std::{borrow::Cow, io::Write, str::FromStr};
1313

1414
/// validated crate name
1515
///
@@ -31,7 +31,14 @@ use std::{io::Write, str::FromStr};
3131
SerializeDisplay,
3232
bincode::Encode,
3333
)]
34-
pub struct KrateName(String);
34+
pub struct KrateName(Cow<'static, str>);
35+
36+
impl KrateName {
37+
#[cfg(test)]
38+
pub(crate) const fn from_static(s: &'static str) -> Self {
39+
KrateName(Cow::Borrowed(s))
40+
}
41+
}
3542

3643
impl From<&KrateName> for KrateName {
3744
fn from(krate_name: &KrateName) -> Self {
@@ -44,7 +51,7 @@ impl FromStr for KrateName {
4451

4552
fn from_str(s: &str) -> Result<Self, Self::Err> {
4653
validate_crate_name("crate", s)?;
47-
Ok(KrateName(s.to_string()))
54+
Ok(KrateName(Cow::Owned(s.to_string())))
4855
}
4956
}
5057

@@ -67,8 +74,21 @@ impl<'q> Encode<'q, Postgres> for KrateName {
6774

6875
impl<'r> Decode<'r, Postgres> for KrateName {
6976
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
77+
// future improvement: we could also avoid the allocation here
78+
// and return a Cow::Borrowed while reading from the DB.
79+
// But this would mean the lifetime leaks into the whole codebase.
7080
let s: &str = Decode::<Postgres>::decode(value)?;
71-
Ok(Self(s.parse()?))
81+
Ok(Self(Cow::Owned(s.parse()?)))
82+
}
83+
}
84+
85+
impl PgHasArrayType for KrateName {
86+
fn array_type_info() -> PgTypeInfo {
87+
<&str as PgHasArrayType>::array_type_info()
88+
}
89+
90+
fn array_compatible(ty: &PgTypeInfo) -> bool {
91+
<&str as PgHasArrayType>::array_compatible(ty)
7292
}
7393
}
7494

src/utils/cargo_metadata.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::{db::types::version::Version, error::Result};
1+
use crate::db::types::krate_name::KrateName;
2+
use crate::web::ReqVersion;
3+
use crate::{db::types::version::Version, error::Result, web::extractors::rustdoc::RustdocParams};
24
use anyhow::{Context, bail};
35
use rustwide::{Toolchain, Workspace, cmd::Command};
46
use semver::VersionReq;
@@ -135,6 +137,19 @@ pub(crate) struct Dependency {
135137
pub(crate) optional: bool,
136138
}
137139

140+
impl Dependency {
141+
pub(crate) fn rustdoc_params(&self) -> RustdocParams {
142+
RustdocParams::new(
143+
// I validated in the database, which makes me assume that renames are
144+
// handled before storing the deps into the column.
145+
self.name
146+
.parse::<KrateName>()
147+
.expect("we validated that the dep name is always a valid KrateName"),
148+
)
149+
.with_req_version(ReqVersion::Semver(self.req.clone()))
150+
}
151+
}
152+
138153
impl bincode::Encode for Dependency {
139154
fn encode<E: bincode::enc::Encoder>(
140155
&self,

src/web/build_details.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub(crate) async fn build_details_handler(
7676
.into_canonical_req_version_or_else(|confirmed_name, version| {
7777
let params = params
7878
.clone()
79-
.with_confirmed_name(Some(confirmed_name))
79+
.with_name(confirmed_name)
8080
.with_req_version(version);
8181
AxumNope::Redirect(
8282
params.build_details_url(id, build_params.filename.as_deref()),

0 commit comments

Comments
 (0)