Compare commits

...
56 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås aee40b044d subprojects: Prepare for release 2026-09-09 20:37:20 +02:00
Ole André Vadla Ravnås b8c22c18f1 subprojects: Bump outdated 2026-09-09 20:33:13 +02:00
Ole André Vadla Ravnås b0a080cd14 subprojects: Bump outdated 2026-09-09 20:16:39 +02:00
Ole André Vadla Ravnås e071ead36d subprojects: Bump outdated 2026-09-09 00:52:10 +02:00
Ole André Vadla Ravnås 2ff7776289 submodules: Bump releng 2026-09-09 00:52:10 +02:00
Ole André Vadla Ravnås df1b3af738 subprojects: Bump outdated 2026-09-09 00:47:02 +02:00
Ole André Vadla Ravnås 03d3b8ab0c subprojects: Bump outdated 2026-09-08 22:34:08 +02:00
Ole André Vadla Ravnås dd0639b6a0 submodules: Bump releng 2026-09-08 22:34:08 +02:00
Ole André Vadla Ravnås bfc6d48b72 bindgen: Fix typing imports on Python < 3.11
NotRequired, ParamSpec and TypedDict come from typing_extensions
there.
2026-09-08 14:14:07 +02:00
Ole André Vadla Ravnås 903143cfd2 subprojects: Bump outdated 2026-09-08 12:14:50 +02:00
Ole André Vadla Ravnås c91bd2d443 subprojects: Bump outdated 2026-09-08 11:39:29 +02:00
Ole André Vadla Ravnås c918c1e516 subprojects: Bump outdated 2026-09-07 17:39:36 +02:00
Ole André Vadla Ravnås ec645f2118 subprojects: Bump outdated 2026-09-07 11:47:57 +02:00
Ole André Vadla Ravnås 41a658af3f bindgen: Blacken model.py 2026-09-06 12:14:30 +02:00
Ole André Vadla Ravnås 9a86bd589b bindgen: Expose named constructors as factories
Emit them all rather than the first alone, and marshal a bytes
argument through GBytes. Keep new as the primary constructor.
2026-09-06 12:04:31 +02:00
Ole André Vadla Ravnås 82293f6c56 subprojects: Bump outdated 2026-09-06 12:02:40 +02:00
Ole André Vadla Ravnås b5c8757514 subprojects: Bump outdated 2026-09-04 17:27:46 +02:00
Ole André Vadla Ravnås 8c7b77cf52 subprojects: Bump outdated 2026-09-04 12:26:26 +02:00
Ole André Vadla Ravnås bbb129ac8d subprojects: Bump outdated 2026-09-03 22:40:11 +02:00
Ole André Vadla Ravnås 51c411d3f4 subprojects: Bump outdated 2026-09-03 18:19:36 +02:00
Ole André Vadla Ravnås a0dd2b7463 subprojects: Bump outdated 2026-09-03 14:43:19 +02:00
Ole André Vadla Ravnås fcc203f604 subprojects: Bump outdated 2026-09-02 18:42:33 +02:00
Ole André Vadla Ravnås a04b4a328e submodules: Bump releng 2026-09-02 18:42:33 +02:00
Ole André Vadla Ravnås f4109be14e subprojects: Bump outdated 2026-09-02 00:30:41 +02:00
Ole André Vadla Ravnås 786398a682 submodules: Bump releng 2026-09-02 00:30:41 +02:00
Ole André Vadla Ravnås 738060a8c5 subprojects: Bump outdated 2026-09-01 21:38:50 +02:00
Ole André Vadla Ravnås b5fb9987fc submodules: Bump releng 2026-09-01 21:38:50 +02:00
Ole André Vadla Ravnås b69d19f673 subprojects: Bump outdated 2026-09-01 15:16:05 +02:00
Ole André Vadla Ravnås 6622f997cd submodules: Bump releng 2026-09-01 15:16:05 +02:00
Ole André Vadla Ravnås 6eeeae51c8 subprojects: Bump outdated 2026-09-01 14:05:16 +02:00
Ole André Vadla Ravnås 679805bc8c submodules: Bump releng 2026-09-01 14:05:16 +02:00
Ole André Vadla Ravnås ec58231298 subprojects: Bump outdated 2026-08-27 18:26:09 +02:00
Ole André Vadla Ravnås 0caa5d4cf6 submodules: Bump releng 2026-08-27 18:26:09 +02:00
Ole André Vadla Ravnås 97d79c14a3 subprojects: Bump outdated 2026-08-18 15:32:21 +02:00
Ole André Vadla Ravnås e46178a118 submodules: Bump releng 2026-08-18 15:32:21 +02:00
Ole André Vadla Ravnås 1e631075e4 subprojects: Bump outdated 2026-08-18 12:50:57 +02:00
Ole André Vadla Ravnås 9cd85d0cfc subprojects: Bump outdated 2026-08-18 00:13:05 +02:00
Ole André Vadla Ravnås 4baee2713e subprojects: Bump outdated 2026-08-17 21:10:56 +02:00
Ole André Vadla Ravnås 4f33ee3945 submodules: Bump releng 2026-08-17 21:10:56 +02:00
Ole André Vadla Ravnås 6f890ee8d4 Take object args and settings kwargs
Sync methods dropped parameters of object type, so PeerOptions.add_relay
never reached the extension even though the facade referred to it.

Constructor kwargs were forwarded to an extension init that ignores them,
leaving them silently unapplied. Apply them to the impl instead, reusing
the options selectors so adders take a list, or a dict when they take a
name and a value.
2026-08-17 20:40:41 +02:00
Ole André Vadla Ravnås f27a8dcc73 subprojects: Bump outdated 2026-08-16 22:23:39 +02:00
Ole André Vadla Ravnås 7c81781550 submodules: Bump releng 2026-08-16 22:23:39 +02:00
Ole André Vadla Ravnås 317a796f7d subprojects: Bump outdated 2026-08-13 18:00:26 +02:00
Ole André Vadla Ravnås 01f691c075 subprojects: Bump outdated 2026-08-13 17:55:09 +02:00
Ole André Vadla Ravnås feb036961e submodules: Bump releng 2026-08-13 17:55:09 +02:00
Ole André Vadla Ravnås 62f066389e subprojects: Bump outdated 2026-08-13 16:21:25 +02:00
Ole André Vadla Ravnås 8deda449c3 submodules: Bump releng 2026-08-13 16:21:25 +02:00
Ole André Vadla Ravnås 5aa3fda547 subprojects: Bump outdated 2026-08-13 13:35:02 +02:00
Ole André Vadla Ravnås d7acc26d9d submodules: Bump releng 2026-08-13 13:35:02 +02:00
Ole André Vadla Ravnås 8cb6565adf subprojects: Bump outdated 2026-08-13 13:02:05 +02:00
Ole André Vadla Ravnås 5ba902508e submodules: Bump releng 2026-08-13 13:02:05 +02:00
Ole André Vadla Ravnås 4ee43bc18c subprojects: Bump outdated 2026-08-13 00:19:40 +02:00
Ole André Vadla Ravnås 4414c049f4 submodules: Bump releng 2026-08-13 00:19:40 +02:00
Ole André Vadla Ravnås 1649a5a4cf subprojects: Bump outdated 2026-08-12 13:00:22 +02:00
Ole André Vadla Ravnås b17f7704a3 submodules: Bump releng 2026-08-12 13:00:22 +02:00
Ole André Vadla Ravnås 4aca013c22 subprojects: Bump outdated 2026-08-11 11:41:53 +02:00
4 changed files with 188 additions and 35 deletions

No files matched your search

+185 -33
View File
@@ -34,10 +34,14 @@ def read_asset(name: str) -> str:
return (ASSETS_DIR / name).read_text(encoding="utf-8")
FACADE_TYPING_IMPORTS = (
"from typing import (Any, Callable, Dict, List, Literal, Mapping, NotRequired, Optional, Tuple, TypedDict, "
"Sequence, Union, ParamSpec, TypeVar, cast, overload)"
)
FACADE_TYPING_IMPORTS = """\
from typing import (Any, Callable, Dict, List, Literal, Mapping, Optional, Tuple, Sequence, Union, TypeVar, cast,
overload)
if sys.version_info >= (3, 11):
from typing import NotRequired, ParamSpec, TypedDict
else:
from typing_extensions import NotRequired, ParamSpec, TypedDict"""
def generate_facade_preludes(model: Model) -> List[str]:
@@ -88,17 +92,25 @@ def _to_envp(value):
def _make_options(cls, values, selectors):
options = cls()
_apply_settings(options, values, selectors)
return options
def _apply_settings(impl, values, selectors):
for name, value in values.items():
if value is None:
continue
select = selectors.get(name)
if select is None:
setattr(options, name, value)
setattr(impl, name, _unwrap(value))
elif isinstance(value, dict):
add = getattr(impl, select)
for key, element in value.items():
add(key, _unwrap(element))
else:
add = getattr(options, select)
add = getattr(impl, select)
for element in value:
add(element)
return options
add(_unwrap(element))
_current_cancellable = threading.local()
@@ -182,17 +194,25 @@ def _to_envp(value):
def _make_options(cls, values, selectors):
options = cls()
_apply_settings(options, values, selectors)
return options
def _apply_settings(impl, values, selectors):
for name, value in values.items():
if value is None:
continue
select = selectors.get(name)
if select is None:
setattr(options, name, value)
setattr(impl, name, _unwrap(value))
elif isinstance(value, dict):
add = getattr(impl, select)
for key, element in value.items():
add(key, _unwrap(element))
else:
add = getattr(options, select)
add = getattr(impl, select)
for element in value:
add(element)
return options
add(_unwrap(element))
_current_cancellable: contextvars.ContextVar = contextvars.ContextVar("frida_current_cancellable", default=None)
@@ -516,10 +536,8 @@ def generate_facade_init(otype: ObjectType) -> str:
{body}"""
return f""" def __init__(self, *args, **kwargs):
self._impl = _frida.{otype.py_name}(
*[_unwrap(a) for a in args],
**{{k: _unwrap(v) for k, v in kwargs.items()}},
)
self._impl = _frida.{otype.py_name}(*[_unwrap(a) for a in args])
_apply_settings(self._impl, kwargs, {build_option_selectors(otype)})
setup = getattr(self, "_setup", None)
if setup is not None:
setup()"""
@@ -643,7 +661,7 @@ def generate_py_sync_method(method: Method, model: Model) -> Optional[str]:
return None
params = [facade_param(param, model) for param in method.input_parameters]
names = ", ".join(param.name for param in method.input_parameters)
names = ", ".join(facade_argument(param, model) for param in method.input_parameters)
call = f"self._impl.{method.name}({names})"
if method.return_value is not None:
@@ -659,6 +677,12 @@ def facade_signature(method: Method, params: List[str]) -> str:
return ", ".join(["self"] + (method.custom_facade_params or params))
def facade_argument(param, model: Model) -> str:
if resolve_input_object_type(param.type, model) is not None:
return f"_unwrap({param.name})"
return param.name
def facade_param(param, model: Model) -> str:
annotation = pyi_type(param.type, model)
if param.nullable:
@@ -769,13 +793,22 @@ def generate_pyi_class(otype: ObjectType, model: Model) -> List[str]:
body = []
ctor = next(iter(otype.constructors), None)
if ctor is not None and not ctor.throws:
params = pyi_parameters(ctor.input_parameters, model)
primary = primary_constructor(otype)
if primary is not None and not primary.throws:
params = pyi_parameters(primary.input_parameters, model)
if params is not None:
signature = ", ".join(["self"] + params)
body.append(f" def __init__({signature}) -> None: ...")
for ctor in otype.constructors:
if ctor is primary:
continue
params = pyi_parameters(ctor.input_parameters, model)
if params is None:
continue
body.append(" @staticmethod")
body.append(f" def {ctor.name}({', '.join(params)}) -> {otype.py_name}: ...")
if otype.name == "Object":
body.append(" def on(self, signal: str, callback: Callable[..., Any]) -> None: ...")
body.append(" def off(self, signal: str, callback: Callable[..., Any]) -> None: ...")
@@ -924,6 +957,8 @@ def generate_extension_c(model: Model) -> str:
code += generate_interface_implementation(otype)
code += generate_object_type_constructor(otype)
for ctor in factory_constructors(otype):
code += generate_factory_function(otype, ctor, build_constructor_marshals(ctor))
return code
@@ -1198,6 +1233,10 @@ def generate_prototypes(model: Model) -> str:
"",
f"static int {otype_cprefix}_init ({otype_cprefix} * self, PyObject * args, PyObject * kw);",
]
for ctor in factory_constructors(otype):
prototypes.append(
f"static PyObject * {otype_cprefix}_{ctor.name} (PyObject * self, PyObject * args, PyObject * kw);"
)
if implementable_interface(otype):
prototypes += [
f"static int {otype_cprefix}_traverse (PyObject * self, visitproc visit, void * arg);",
@@ -1314,6 +1353,9 @@ def generate_object_type_methods(otype: ObjectType) -> str:
functions.append(function)
entries.append(entry)
for ctor in factory_constructors(otype):
entries.append(factory_method_entry(otype, ctor))
return f"""{"".join(functions)}
static PyMethodDef {otype.c_symbol_prefix}_methods[] =
{{
@@ -1839,6 +1881,16 @@ def build_sync_param(param: Parameter) -> Optional["SyncParam"]:
cleanup=f"g_clear_pointer (&{name}, g_variant_unref);",
)
if resolve_input_object_type(param.type, param.object_type.model) is not None:
return SyncParam(
decl=f"PyObject * {name}_obj;\n{param.type.c} {name} = NULL;",
fmt="O",
parse_args=[f"&{name}_obj"],
pre=f"""if ({name}_obj != Py_None)
{name} = ({param.type.c}) PY_GOBJECT_HANDLE ({name}_obj);""",
call_arg=name,
)
return None
@@ -2255,28 +2307,47 @@ def generate_object_type_constructor(otype: ObjectType) -> str:
if implementable_interface(otype):
return generate_interface_init(otype)
ctor = next(iter(otype.constructors), None)
ctor = primary_constructor(otype)
if ctor is None:
return generate_bare_init(otype)
marshals: Optional[List[ParamMarshal]] = None
if not ctor.throws:
marshals = []
for param in ctor.input_parameters:
marshal = build_param_marshal(param)
if marshal is None:
marshals = None
break
marshal.optional = param.optional
marshals.append(marshal)
if ctor.throws:
return generate_unconstructable_init(otype)
marshals = build_constructor_marshals(ctor)
if marshals is None:
return generate_unconstructable_init(otype)
return generate_constructor_init(otype, ctor, marshals)
def primary_constructor(otype: ObjectType) -> Optional[Procedure]:
if not otype.constructors:
return None
return next((c for c in otype.constructors if c.name == "new"), otype.constructors[0])
def factory_constructors(otype: ObjectType) -> List[Procedure]:
primary = primary_constructor(otype)
return [
ctor
for ctor in otype.constructors
if ctor is not primary and not ctor.is_async and build_constructor_marshals(ctor) is not None
]
def build_constructor_marshals(ctor: Procedure) -> Optional[List["ParamMarshal"]]:
marshals = []
for param in ctor.input_parameters:
marshal = build_param_marshal(param)
if marshal is None:
return None
marshal.optional = param.optional
marshals.append(marshal)
return marshals
def generate_interface_init(otype: ObjectType) -> str:
n = interface_impl_names(otype)
indent = constructor_indent(otype)
@@ -2377,7 +2448,88 @@ static int
{generate_constructor_tail(marshals)}"""
def generate_argument_parse(marshals: List["ParamMarshal"]) -> str:
def factory_method_entry(otype: ObjectType, ctor: Procedure) -> str:
return (
f' {{ "{ctor.name}", (PyCFunction) {otype.c_symbol_prefix}_{ctor.name}, '
"METH_VARARGS | METH_KEYWORDS | METH_STATIC, NULL },"
)
def generate_factory_function(otype: ObjectType, ctor: Procedure, marshals: List["ParamMarshal"]) -> str:
indent = " " * (len(otype.c_symbol_prefix) + len(ctor.name) + 3)
decls = [line for m in marshals for line in m.decls]
decls.append(f"{otype.c_type} * handle;")
if ctor.throws:
decls.append("GError * error = NULL;")
decls.append("PyObject * result = NULL;")
decls_block = indent_c_code("\n".join(decls), 1, prologue="\n")
keyword_decl = ""
parse_block = ""
if marshals:
keywords = ", ".join([f'"{m.keyword}"' for m in marshals] + ["NULL"])
keyword_decl = f"\n static char * keywords[] = {{ {keywords} }};"
parse_block = "\n" + generate_argument_parse(marshals, on_failure="return NULL;")
post_block = ""
for m in marshals:
if m.post is not None:
post_block += indent_c_code(m.post, 1, prologue="\n") + "\n"
call_args = [m.call_arg for m in marshals]
if ctor.throws:
call_args.append("&error")
call = f"handle = ({otype.c_type} *) {ctor.c_identifier} ({', '.join(call_args)});"
error_block = ""
if ctor.throws:
error_block = """
if (error != NULL)
{
result = PyFrida_raise (error);
goto beach;
}
"""
take_handle = f"result = PyGObject_new_take_handle (g_steal_pointer (&handle), PYFRIDA_TYPE ({otype.py_name}));"
return f"""
static PyObject *
{otype.c_symbol_prefix}_{ctor.name} (PyObject * self,
{indent}PyObject * args,
{indent}PyObject * kw)
{{{keyword_decl}{decls_block}
{parse_block}{post_block}
{call}
{error_block}
{take_handle}
{generate_factory_tail(marshals, ctor.throws)}"""
def generate_factory_tail(marshals: List["ParamMarshal"], throws: bool) -> str:
cleanups = [m.cleanup for m in marshals if m.cleanup is not None]
cleanup_block = indent_c_code("\n".join(reversed(cleanups)), 1) if cleanups else ""
if throws or constructor_needs_beach(marshals):
prologue = f"{cleanup_block}\n\n" if cleanup_block else ""
return f"""beach:
{prologue} return result;
}}
"""
if cleanup_block:
return f"""{cleanup_block}
return result;
}}
"""
return """ return result;
}
"""
def generate_argument_parse(marshals: List["ParamMarshal"], on_failure: str = "return -1;") -> str:
fmt = ""
optional_started = False
for m in marshals:
@@ -2391,7 +2543,7 @@ def generate_argument_parse(marshals: List["ParamMarshal"]) -> str:
indent = " " * len(" if (!PyArg_ParseTupleAndKeywords (")
parse_args_str = (",\n" + indent).join(parse_args)
return f""" if (!PyArg_ParseTupleAndKeywords ({parse_args_str}))
return -1;
{on_failure}
"""
+1
View File
@@ -144,6 +144,7 @@ class Method(core.Method):
custom = self.customizations
return custom.custom_logic if custom is not None else None
class Property(core.Property):
pass
+1 -1
Submodule releng updated: c9cc18138b...963fe3826f.
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/frida-core.git
revision = 17.17.0
revision = 17.18.0
depth = 1
[provide]