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: Don't use public items via paths that include private modules #316

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#[doc(inline)]
pub use api::engine;
#[doc(inline)]
pub use api::Surreal;

mod api {
pub struct Surreal<T>(T);

pub mod engine {
pub struct Any;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//! Do NOT edit this code.
//! It was automatically generated by Pavex.
//! All manual edits will be lost next time the code is generated.
extern crate alloc;
struct ServerState {
router: pavex_matchit::Router<u32>,
application_state: ApplicationState,
}
pub struct ApplicationState {
s0: dep::Surreal<dep::engine::Any>,
}
pub async fn build_application_state() -> crate::ApplicationState {
let v0 = app::constructor();
crate::ApplicationState { s0: v0 }
}
pub fn run(
server_builder: pavex::server::Server,
application_state: ApplicationState,
) -> pavex::server::ServerHandle {
let server_state = std::sync::Arc::new(ServerState {
router: build_router(),
application_state,
});
server_builder.serve(route_request, server_state)
}
fn build_router() -> pavex_matchit::Router<u32> {
let mut router = pavex_matchit::Router::new();
router.insert("/", 0u32).unwrap();
router
}
async fn route_request(
request: http::Request<hyper::body::Incoming>,
_connection_info: Option<pavex::connection::ConnectionInfo>,
server_state: std::sync::Arc<ServerState>,
) -> pavex::response::Response {
let (request_head, request_body) = request.into_parts();
#[allow(unused)]
let request_body = pavex::request::body::RawIncomingBody::from(request_body);
let request_head: pavex::request::RequestHead = request_head.into();
let matched_route = match server_state.router.at(&request_head.target.path()) {
Ok(m) => m,
Err(_) => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter(
vec![],
)
.into();
return route_1::entrypoint(&allowed_methods).await;
}
};
let route_id = matched_route.value;
#[allow(unused)]
let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route
.params
.into();
match route_id {
0u32 => {
match &request_head.method {
&pavex::http::Method::GET => {
route_0::entrypoint(&server_state.application_state.s0).await
}
_ => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([
pavex::http::Method::GET,
])
.into();
route_1::entrypoint(&allowed_methods).await
}
}
}
i => unreachable!("Unknown route id: {}", i),
}
}
pub mod route_0 {
pub async fn entrypoint<'a>(
s_0: &'a dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let response = wrapping_0(s_0).await;
response
}
async fn stage_1<'a>(
s_0: &'a dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let response = handler(s_0).await;
response
}
async fn wrapping_0(
v0: &dep::Surreal<dep::engine::Any>,
) -> pavex::response::Response {
let v1 = crate::route_0::Next0 {
s_0: v0,
next: stage_1,
};
let v2 = pavex::middleware::Next::new(v1);
let v3 = pavex::middleware::wrap_noop(v2).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v3)
}
async fn handler(v0: &dep::Surreal<dep::engine::Any>) -> pavex::response::Response {
let v1 = app::handler(v0);
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
}
struct Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
s_0: &'a dep::Surreal<dep::engine::Any>,
next: fn(&'a dep::Surreal<dep::engine::Any>) -> T,
}
impl<'a, T> std::future::IntoFuture for Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
type Output = pavex::response::Response;
type IntoFuture = T;
fn into_future(self) -> Self::IntoFuture {
(self.next)(self.s_0)
}
}
}
pub mod route_1 {
pub async fn entrypoint<'a>(
s_0: &'a pavex::router::AllowedMethods,
) -> pavex::response::Response {
let response = wrapping_0(s_0).await;
response
}
async fn stage_1<'a>(
s_0: &'a pavex::router::AllowedMethods,
) -> pavex::response::Response {
let response = handler(s_0).await;
response
}
async fn wrapping_0(
v0: &pavex::router::AllowedMethods,
) -> pavex::response::Response {
let v1 = crate::route_1::Next0 {
s_0: v0,
next: stage_1,
};
let v2 = pavex::middleware::Next::new(v1);
let v3 = pavex::middleware::wrap_noop(v2).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v3)
}
async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::response::Response {
let v1 = pavex::router::default_fallback(v0).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
}
struct Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
s_0: &'a pavex::router::AllowedMethods,
next: fn(&'a pavex::router::AllowedMethods) -> T,
}
impl<'a, T> std::future::IntoFuture for Next0<'a, T>
where
T: std::future::Future<Output = pavex::response::Response>,
{
type Output = pavex::response::Response;
type IntoFuture = T;
fn into_future(self) -> Self::IntoFuture {
(self.next)(self.s_0)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
digraph "GET / - 0" {
0 [ label = "pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_0::Next0<'a>>) -> pavex::response::Response"]
1 [ label = "pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next<crate::route_0::Next0<'a>>"]
2 [ label = "crate::route_0::Next0(&'a dep::Surreal<dep::engine::Any>) -> crate::route_0::Next0<'a>"]
4 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
5 [ label = "&dep::Surreal<dep::engine::Any>"]
1 -> 0 [ ]
2 -> 1 [ ]
0 -> 4 [ ]
5 -> 2 [ ]
}

digraph "GET / - 1" {
0 [ label = "app::handler(&dep::Surreal<dep::engine::Any>) -> pavex::response::Response"]
2 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
3 [ label = "&dep::Surreal<dep::engine::Any>"]
0 -> 2 [ ]
3 -> 0 [ ]
}

digraph "* / - 0" {
0 [ label = "pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_1::Next0<'a>>) -> pavex::response::Response"]
1 [ label = "pavex::middleware::Next::new(crate::route_1::Next0<'a>) -> pavex::middleware::Next<crate::route_1::Next0<'a>>"]
2 [ label = "crate::route_1::Next0(&'a pavex::router::AllowedMethods) -> crate::route_1::Next0<'a>"]
4 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
5 [ label = "&pavex::router::AllowedMethods"]
1 -> 0 [ ]
2 -> 1 [ ]
0 -> 4 [ ]
5 -> 2 [ ]
}

digraph "* / - 1" {
0 [ label = "pavex::router::default_fallback(&pavex::router::AllowedMethods) -> pavex::response::Response"]
2 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
3 [ label = "&pavex::router::AllowedMethods"]
0 -> 2 [ ]
3 -> 0 [ ]
}

digraph app_state {
0 [ label = "crate::ApplicationState(dep::Surreal<dep::engine::Any>) -> crate::ApplicationState"]
1 [ label = "app::constructor() -> dep::Surreal<dep::engine::Any>"]
1 -> 0 [ ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use pavex::blueprint::{router::GET, Blueprint};
use pavex::f;
use pavex::response::Response;

pub type RemoteAlias = dep::Surreal<dep::engine::Any>;

pub fn constructor() -> RemoteAlias {
todo!()
}

pub fn handler(_a: &RemoteAlias) -> Response {
todo!()
}

pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.singleton(f!(crate::constructor));
bp.route(GET, "/", f!(crate::handler));
bp
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description = "Reproduction of a reported bug"

[expectations]
codegen = "pass"

[ephemeral_dependencies]
dep = { path = "dep.rs" }
1 change: 1 addition & 0 deletions libs/pavexc/src/compiler/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl App {
) else {
return Err(diagnostics);
};

let framework_item_db = FrameworkItemDb::new(&package_graph, &krate_collection);
let mut component_db = ComponentDb::build(
user_component_db,
Expand Down
9 changes: 8 additions & 1 deletion libs/pavexc/src/rustdoc/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ impl Crate {
&mut id2private_import_paths,
&mut re_exports,
&krate.root,
true,
)?;

import_path2id.reserve(id2public_import_paths.len());
Expand Down Expand Up @@ -870,6 +871,7 @@ fn index_local_types<'a>(
private_path_index: &mut HashMap<rustdoc_types::Id, BTreeSet<Vec<String>>>,
re_exports: &mut HashMap<Vec<String>, (Vec<String>, u32)>,
current_item_id: &rustdoc_types::Id,
is_public: bool,
) -> Result<(), anyhow::Error> {
// TODO: the way we handle `current_path` is extremely wasteful,
// we can likely reuse the same buffer throughout.
Expand All @@ -890,6 +892,8 @@ fn index_local_types<'a>(
Some(i) => i,
};

let is_public = is_public && current_item.visibility == Visibility::Public;

match &current_item.inner {
ItemEnum::Module(m) => {
let current_path_segment = current_item
Expand All @@ -906,6 +910,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
item_id,
is_public,
)?;
}
}
Expand Down Expand Up @@ -949,6 +954,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
re_exported_item_id,
is_public,
)?;
}
} else {
Expand All @@ -960,6 +966,7 @@ fn index_local_types<'a>(
private_path_index,
re_exports,
imported_id,
is_public,
)?;
}
}
Expand All @@ -977,7 +984,7 @@ fn index_local_types<'a>(
current_path.push(name);
let path = current_path.into_iter().map(|s| s.to_string()).collect();

let index = if current_item.visibility == Visibility::Public {
let index = if is_public {
public_path_index
} else {
private_path_index
Expand Down