override method_param/field name if it collides

This commit is contained in:
Janis 2023-06-26 10:51:36 +02:00
parent 9511f49163
commit 1ab11164d3
3 changed files with 72 additions and 8 deletions

View file

@ -411,13 +411,13 @@ pub mod rust {
struct_name: &str,
method: &ClassMethod,
) -> anyhow::Result<(TokenStream, TokenStream)> {
let method_name = canonicalize_name(&method.name);
let method_name = canonicalize_name(&method.unique_name());
let parameters = method
.parameters
.iter()
.map(|parameter| {
let name = canonicalize_name(&parameter.name);
let name = canonicalize_name(&parameter.unique_name());
let type_name = self.type_name(&parameter.ty)?;
anyhow::Ok((parameter, name, type_name))
@ -611,7 +611,7 @@ pub mod rust {
.fields
.iter()
.map(|field| {
let name = canonicalize_name(&field.name);
let name = canonicalize_name(&field.unique_name());
let ty = self.type_name(&field.ty)?;
anyhow::Ok((field, name, ty))

View file

@ -8,6 +8,7 @@ use ron::ser::PrettyConfig;
use crate::global_tables::objects::GOBJECTS;
use crate::sdk::repr::*;
use crate::util::DedupIter;
use crate::v2_types::{
any_type::{self, AnyField, AnyObject, AnyProperty, AnyStruct},
traits::{
@ -238,6 +239,28 @@ impl Class {
},
);
let fields = fields
.into_iter()
.dedup_with_by(
|n, field| ClassField {
override_name: Some(format!("{}{}", field.name, n)),
..field
},
|field: &ClassField| -> String { field.name.clone() },
)
.collect();
let methods = methods
.into_iter()
.dedup_with_by(
|n, field| ClassMethod {
override_name: Some(format!("{}{}", field.name, n)),
..field
},
|field: &ClassMethod| -> String { field.name.clone() },
)
.collect();
(fields, methods)
}
@ -257,14 +280,16 @@ impl Class {
impl ClassField {
pub fn from_uprop(prop: UProperty) -> anyhow::Result<Self> {
let name = prop
.name()
.get_name()
.context("failed to retrieve field name")?;
Ok(Self {
offset: *prop.offset() as u32,
size: *prop.element_size() as u32,
flags: *prop.property_flags(),
name: prop
.name()
.get_name()
.context("failed to retrieve field name")?,
override_name: None,
name,
ty: resolve_type(prop).context("failed to get field type")?,
})
}
@ -288,11 +313,21 @@ impl ClassMethod {
_ => None,
})
.map(|prop| ClassField::from_uprop(prop))
.collect::<anyhow::Result<Vec<_>>>()?;
.collect::<anyhow::Result<Vec<_>>>()?
.into_iter()
.dedup_with_by(
|n, field| ClassField {
override_name: Some(format!("{}{}", field.name, n)),
..field
},
|field: &ClassField| -> String { field.name.clone() },
)
.collect();
Ok(ClassMethod {
name,
full_name,
override_name: None,
flags: *func.function_flags(),
parameters: params,
})
@ -359,6 +394,14 @@ impl Package {
.context("not actually a package object")?,
types,
dependencies,
name: self
.package_object
.get_name()
.context("failed to get package object name.")?,
full_name: self
.package_object
.get_full_name()
.context("failed to get package object name.")?,
})
}
}

View file

@ -55,6 +55,8 @@ pub struct Package {
pub struct ProcessedPackage {
/// the package object ref.
pub package_object: PackageRef,
pub name: String,
pub full_name: String,
/// all types extracted from this package referenced by their `ObjectRef`.
pub types: BTreeMap<ObjectRef, UnrealType>,
/// All other packages that types in this package depend on directly.
@ -142,6 +144,7 @@ pub struct ClassField {
pub offset: u32,
pub size: u32,
pub name: String,
pub override_name: Option<String>,
pub flags: EPropertyFlags,
pub ty: Type,
}
@ -166,11 +169,19 @@ impl ClassField {
pub fn is_rep(&self) -> bool {
!self.flags.contains(EPropertyFlags::RepSkip)
}
pub fn unique_name(&self) -> &str {
self.override_name
.as_ref()
.map(|s| s.as_str())
.unwrap_or(self.name.as_str())
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ClassMethod {
pub name: String,
pub override_name: Option<String>,
pub full_name: String,
pub flags: EFunctionFlags,
pub parameters: Vec<ClassField>,
@ -180,13 +191,23 @@ impl ClassMethod {
pub fn is_static(&self) -> bool {
self.flags.contains(EFunctionFlags::Static)
}
pub fn is_native(&self) -> bool {
self.flags.contains(EFunctionFlags::Native)
}
/// this function is replicated to the server, might be exploitable.
pub fn is_net_server(&self) -> bool {
self.flags.contains(EFunctionFlags::NetServer)
}
pub fn unique_name(&self) -> &str {
self.override_name
.as_ref()
.map(|s| s.as_str())
.unwrap_or(self.name.as_str())
}
pub fn out_params(&self) -> Vec<&ClassField> {
self.parameters
.iter()