Compare commits

...
131 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås c686293400 subprojects: Prepare for release 2026-10-30 14:34:01 +01:00
Ole André Vadla Ravnås ee02bd8af2 subprojects: Bump outdated 2026-10-30 14:01:37 +01:00
Ole André Vadla Ravnås 5f224307bb bindgen: Narrow factory marshals for mypy 2026-10-30 13:03:31 +01:00
Ole André Vadla Ravnås 7357b0b5b4 Format with Black 26 2026-10-30 13:03:17 +01:00
Ole André Vadla Ravnås 2f2bb64f36 subprojects: Bump outdated 2026-10-30 07:08:42 +01:00
Ole André Vadla Ravnås 5a0894aaac subprojects: Bump outdated 2026-10-30 07:00:11 +01:00
Ole André Vadla Ravnås 0bcb9da6c5 submodules: Bump releng 2026-10-30 07:00:11 +01:00
Ole André Vadla Ravnås 2316a9f36d subprojects: Bump outdated 2026-10-29 23:02:21 +01:00
Ole André Vadla Ravnås 720d09bbbc subprojects: Bump outdated 2026-10-29 21:53:15 +01:00
Ole André Vadla Ravnås 1269168a06 subprojects: Bump outdated 2026-10-29 21:28:24 +01:00
Ole André Vadla Ravnås b6c8f04757 submodules: Bump releng 2026-10-29 21:28:24 +01:00
Ole André Vadla Ravnås a0213a48e4 subprojects: Bump outdated 2026-10-23 13:51:43 +02:00
Ole André Vadla Ravnås b978ae1cf0 submodules: Bump releng 2026-10-23 13:51:43 +02:00
Ole André Vadla Ravnås 8017678437 subprojects: Bump outdated 2026-10-20 21:57:18 +02:00
Ole André Vadla Ravnås caef01a609 subprojects: Bump outdated 2026-10-20 21:39:25 +02:00
Ole André Vadla Ravnås 688b5d5c4d submodules: Bump releng 2026-10-20 21:39:25 +02:00
Ole André Vadla Ravnås bd8ea3369b subprojects: Bump outdated 2026-10-20 21:33:27 +02:00
Ole André Vadla Ravnås 1ecf3cf2a6 subprojects: Bump outdated 2026-10-20 20:23:49 +02:00
Ole André Vadla Ravnås 58ca39d36d build: Sync wrappers with releng 2026-10-20 20:23:49 +02:00
Ole André Vadla Ravnås 79c0305e66 submodules: Bump releng 2026-10-20 20:23:49 +02:00
Ole André Vadla Ravnås c1464592c8 subprojects: Bump outdated 2026-10-20 14:26:04 +02:00
Ole André Vadla Ravnås 1b21ea127b submodules: Bump releng 2026-10-20 14:26:04 +02:00
Ole André Vadla Ravnås b43e681df3 subprojects: Prepare for release 2026-10-19 10:33:32 +02:00
Ole André Vadla Ravnås 15d2d930dc subprojects: Bump outdated 2026-10-19 10:30:59 +02:00
Ole André Vadla Ravnås 24bdbab9cb submodules: Bump releng 2026-10-19 10:30:59 +02:00
Ole André Vadla Ravnås d0267d9f38 subprojects: Prepare for release 2026-10-18 13:53:42 +02:00
Ole André Vadla Ravnås 922dbfad3e subprojects: Bump outdated 2026-10-18 13:52:22 +02:00
Ole André Vadla Ravnås 03cf741fe0 subprojects: Prepare for release 2026-10-17 12:54:33 +02:00
Ole André Vadla Ravnås fdcea1076a subprojects: Bump outdated 2026-10-17 12:53:48 +02:00
Ole André Vadla Ravnås 1e1bea3512 submodules: Bump releng 2026-10-17 12:53:48 +02:00
Ole André Vadla Ravnås 95cbbd197c subprojects: Prepare for release 2026-10-16 15:37:47 +02:00
Ole André Vadla Ravnås 9bc7087d74 subprojects: Bump outdated 2026-10-16 15:36:33 +02:00
Ole André Vadla Ravnås ffe970e655 subprojects: Bump outdated 2026-10-16 13:54:46 +02:00
Ole André Vadla Ravnås 7ce14f42fa subprojects: Bump outdated 2026-10-16 12:42:52 +02:00
Ole André Vadla Ravnås 14c8d33b37 submodules: Bump releng 2026-10-16 12:42:52 +02:00
Ole André Vadla Ravnås ff0f50f8a6 subprojects: Bump outdated 2026-10-15 18:18:18 +02:00
Ole André Vadla Ravnås 8b526bb25d subprojects: Bump outdated 2026-10-15 15:46:11 +02:00
Ole André Vadla Ravnås 7c422c233d submodules: Bump releng 2026-10-15 15:46:11 +02:00
Ole André Vadla Ravnås bd7e80c209 subprojects: Bump outdated 2026-10-15 15:14:38 +02:00
Ole André Vadla Ravnås f80a06d7ae submodules: Bump releng 2026-10-15 15:14:38 +02:00
Ole André Vadla Ravnås 82febc16ba subprojects: Prepare for release 2026-10-09 18:57:36 +02:00
Ole André Vadla Ravnås 76d3b504fe subprojects: Bump outdated 2026-10-09 18:56:41 +02:00
Ole André Vadla Ravnås 735d34d175 subprojects: Prepare for release 2026-10-09 14:19:26 +02:00
Ole André Vadla Ravnås a6feef0770 subprojects: Bump outdated 2026-10-09 14:16:52 +02:00
Ole André Vadla Ravnås 418c5e3f43 subprojects: Prepare for release 2026-10-08 14:49:02 +02:00
Ole André Vadla Ravnås a1929a4dc5 subprojects: Bump outdated 2026-10-08 14:32:45 +02:00
Ole André Vadla Ravnås aacd1913e0 subprojects: Prepare for release 2026-10-07 14:27:03 +02:00
Ole André Vadla Ravnås ea6c66da96 subprojects: Bump outdated 2026-10-07 14:24:00 +02:00
Ole André Vadla Ravnås 57b6cbae38 submodules: Bump releng 2026-10-07 14:24:00 +02:00
Ole André Vadla Ravnås 1b18f0174d subprojects: Prepare for release 2026-10-05 10:00:33 +02:00
Ole André Vadla Ravnås 7f04d40687 subprojects: Bump outdated 2026-10-05 09:57:11 +02:00
Ole André Vadla Ravnås c69db7eb40 submodules: Bump releng 2026-10-05 09:57:10 +02:00
Ole André Vadla Ravnås ce49a3102a subprojects: Prepare for release 2026-10-04 11:35:34 +02:00
Ole André Vadla Ravnås 288133374a subprojects: Bump outdated 2026-10-04 11:34:54 +02:00
Ole André Vadla Ravnås 56843bb3f8 subprojects: Prepare for release 2026-10-03 07:56:17 +02:00
Ole André Vadla Ravnås d90f991948 subprojects: Bump outdated 2026-10-03 07:55:28 +02:00
Ole André Vadla Ravnås c744c2a12a subprojects: Prepare for release 2026-10-02 20:28:27 +02:00
Ole André Vadla Ravnås 48631baafa subprojects: Bump outdated 2026-10-02 20:27:05 +02:00
Ole André Vadla Ravnås c711f8f040 subprojects: Prepare for release 2026-10-02 01:36:43 +02:00
Ole André Vadla Ravnås 049674da0a subprojects: Bump outdated 2026-10-02 01:32:18 +02:00
Ole André Vadla Ravnås e1c24e8187 bindgen: Marshal null variants as None 2026-10-01 18:24:45 +02:00
Ole André Vadla Ravnås 9947655e6a subprojects: Prepare for release 2026-09-25 13:15:47 +02:00
Ole André Vadla Ravnås e5b15dce63 subprojects: Bump outdated 2026-09-25 13:14:11 +02:00
Ole André Vadla Ravnås e846eb2815 subprojects: Bump outdated 2026-09-25 12:18:59 +02:00
Ole André Vadla Ravnås bc685fd8c1 subprojects: Bump outdated 2026-09-24 21:35:04 +02:00
Ole André Vadla Ravnås bcaa1a099e subprojects: Bump outdated 2026-09-23 00:02:59 +02:00
Ole André Vadla Ravnås 4e782ccbdf submodules: Bump releng 2026-09-23 00:02:58 +02:00
Ole André Vadla Ravnås 9823368745 subprojects: Bump outdated 2026-09-22 23:47:25 +02:00
Ole André Vadla Ravnås c6e5a8d4d9 submodules: Bump releng 2026-09-22 23:47:25 +02:00
Ole André Vadla Ravnås eb15035950 subprojects: Bump outdated 2026-09-22 21:04:23 +02:00
Ole André Vadla Ravnås ec509287e1 subprojects: Bump outdated 2026-09-22 15:57:26 +02:00
Ole André Vadla Ravnås 0c52c00bad submodules: Bump releng 2026-09-22 15:57:26 +02:00
Ole André Vadla Ravnås 8f31efacf2 Format with the current Black
Black has changed how it lays out a call whose argument is a
multiline string, and a `with` statement holding several contexts.
2026-09-17 19:01:25 +02:00
Ole André Vadla Ravnås 01fd680353 bindgen: Fix dropped constructors and out params
A static function that makes the class it sits on was not read at all,
so every named constructor in the API was missing. One that throws was
then missing twice over: skipped for __init__ because it throws, and
skipped as a factory for being the primary, leaving nothing to make
the class with.

An out parameter was dropped along with the value it carried, so a
`gboolean` method that answers through one now binds as Optional, and
any other out parameter is refused rather than bound as a result the
caller cannot read.
2026-09-17 18:54:58 +02:00
Ole André Vadla Ravnås 00e6231b89 subprojects: Bump outdated 2026-09-16 19:28:53 +02:00
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
8 changed files with 261 additions and 47 deletions

No files matched your search

+2 -2
View File
@@ -1,4 +1,4 @@
PYTHON ?= $(shell which python3 >/dev/null && echo python3 || echo python)
PYTHON ?= $(shell command -v python3 >/dev/null && echo python3 || echo python)
all $(MAKECMDGOALS):
@$(PYTHON) \
@@ -8,7 +8,7 @@ all $(MAKECMDGOALS):
$(MAKECMDGOALS)
git-submodules:
@if [ ! -f releng/meson/meson.py ] || [ ! -f frida-bindgen/frida_bindgen_core/model.py ]; then \
@if [ ! -f releng/meson/meson.py ] || git submodule status 2>/dev/null | grep -q '^-'; then \
git submodule update --init --recursive --depth 1; \
fi
-include git-submodules
Vendored
+2 -2
View File
@@ -1,12 +1,12 @@
#!/bin/sh
[ -z "$PYTHON" ] && PYTHON=$(which python3 >/dev/null && echo python3 || echo python)
[ -z "$PYTHON" ] && PYTHON=$(command -v python3 >/dev/null && echo python3 || echo python)
cd $(dirname $0)
srcroot=$(pwd)
if [ ! -f releng/meson/meson.py ]; then
if [ ! -f releng/meson/meson.py ] || git submodule status 2>/dev/null | grep -q '^-'; then
git submodule update --init --recursive --depth 1 || exit $?
fi
@@ -910,6 +910,9 @@ propagate_error:
static PyObject *
PyGObject_marshal_variant (GVariant * variant)
{
if (variant == NULL)
PyFrida_RETURN_NONE;
switch (g_variant_classify (variant))
{
case G_VARIANT_CLASS_STRING:
+242 -40
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)
@@ -416,7 +436,7 @@ def generate_aio_async_method(method: Method, model: Model) -> Optional[str]:
if method.return_value is not None:
call = wrap_result(call, method.return_value.type, model)
ret = "None" if method.return_value is None else pyi_type(method.return_value.type, model)
ret = facade_return_type(method, model)
return f""" async def {method.name}({signature}) -> {ret}:
return {call}"""
@@ -440,7 +460,7 @@ def generate_custom_facade_method(
body = textwrap.indent(logic.strip(), " " * 8)
keyword = "async def" if awaitable else "def"
ret = "None" if method.return_value is None else pyi_type(method.return_value.type, model)
ret = facade_return_type(method, model)
return f""" {keyword} {method.name}({signature}) -> {ret}:
{body}
@@ -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,13 +661,13 @@ 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:
call = wrap_result(call, method.return_value.type, model)
ret = "None" if method.return_value is None else pyi_type(method.return_value.type, model)
ret = facade_return_type(method, model)
return f""" def {method.name}({facade_signature(method, params)}) -> {ret}:
return {call}"""
@@ -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:
@@ -679,7 +703,7 @@ def generate_py_async_method(method: Method, model: Model) -> Optional[str]:
if method.return_value is not None:
call = wrap_result(call, method.return_value.type, model)
ret = "None" if method.return_value is None else pyi_type(method.return_value.type, model)
ret = facade_return_type(method, model)
return f""" def {method.name}({signature}) -> {ret}:
return {call}"""
@@ -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 = inline_constructor(otype)
if primary is not None:
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: ...")
@@ -836,7 +869,13 @@ def pyi_method(method: Method, model: Model) -> Optional[str]:
if params is None:
return None
signature = ", ".join(["self"] + params)
ret = "None" if method.return_value is None else pyi_type(method.return_value.type, model)
out = method.optional_out_parameter
if out is not None:
ret = f"Optional[{pyi_type(out.type, model)}]"
elif method.return_value is None:
ret = "None"
else:
ret = pyi_type(method.return_value.type, model)
return f" def {method.name}({signature}) -> {ret}: ..."
@@ -924,6 +963,10 @@ def generate_extension_c(model: Model) -> str:
code += generate_interface_implementation(otype)
code += generate_object_type_constructor(otype)
for ctor in factory_constructors(otype):
marshals = build_constructor_marshals(ctor)
assert marshals is not None
code += generate_factory_function(otype, ctor, marshals)
return code
@@ -1198,6 +1241,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 +1361,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[] =
{{
@@ -1329,6 +1379,11 @@ def generate_method(otype: ObjectType, method: Method) -> Optional[Tuple[str, st
marshal = synchronous_method_return_marshal(method)
if marshal is None:
return None
out = method.optional_out_parameter
if out is not None:
marshal = build_return_marshal(out.type, method.object_type.model)
if marshal is None:
return None
params = []
for param in method.input_parameters:
sync_param = build_sync_param(param)
@@ -1672,14 +1727,17 @@ def generate_synchronous_method(otype: ObjectType, method: Method, marshal: str,
indent = " " * (len(otype.c_symbol_prefix) + len(method.name) + 3)
handle = f"({otype.c_type} *) PY_GOBJECT_HANDLE (self)"
returns_strv = method.return_value is not None and method.return_value.type.name == "utf8[]"
out = method.optional_out_parameter
call_arg_list = [handle] + [p.call_arg for p in params]
if returns_strv:
call_arg_list.append("&retval_length")
if out is not None:
call_arg_list.append(f"&{out.name}")
if method.throws:
call_arg_list.append("&error")
call = f"{method.c_identifier} ({', '.join(call_arg_list)})"
if not params and not method.throws and not returns_strv:
if not params and not method.throws and not returns_strv and out is None:
if method.return_value is None:
body = f" {call};\n\n PyFrida_RETURN_NONE;"
else:
@@ -1698,6 +1756,8 @@ static PyObject *
decls.append(" GError * error = NULL;")
if returns_strv:
decls.append(" gint retval_length;")
if out is not None:
decls.append(f" {out_parameter_storage_type(out)} {out.name};")
for p in params:
decls += [f" {line}" for line in p.decl.splitlines()]
@@ -1712,7 +1772,15 @@ static PyObject *
pre = "".join(f"\n {p.pre}\n" for p in params if p.pre)
if method.return_value is None:
if out is not None:
invocation = f" gboolean found = {call};"
success = (
" if (found)\n"
f" result = {marshal.format(value=out.name)};\n"
" else\n"
" {\n Py_IncRef (Py_None);\n result = Py_None;\n }"
)
elif method.return_value is None:
invocation = f" {call};"
success = " Py_IncRef (Py_None);\n result = Py_None;"
elif returns_strv:
@@ -1757,6 +1825,22 @@ static PyObject *
"""
def facade_return_type(method: Method, model: Model) -> str:
out = method.optional_out_parameter
if out is not None:
return f"Optional[{pyi_type(out.type, model)}]"
if method.return_value is None:
return "None"
return pyi_type(method.return_value.type, model)
def out_parameter_storage_type(param: Parameter) -> str:
"""What the caller declares: the out parameter's own type, less the pointer."""
c = param.type.c
assert c.endswith("*"), c
return c[:-1].strip()
def synchronous_method_return_marshal(method: Method) -> Optional[str]:
if method.is_async or method.is_property_accessor:
return None
@@ -1839,6 +1923,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 +2349,55 @@ 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 inline_constructor(otype: ObjectType) -> Optional[Procedure]:
"""The constructor __init__ takes; one that throws is reached as a factory instead."""
ctor = primary_constructor(otype)
if ctor is None or ctor.throws:
return None
return ctor
def factory_constructors(otype: ObjectType) -> List[Procedure]:
primary = inline_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 +2498,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 +2593,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}
"""
+9
View File
@@ -17,6 +17,10 @@ class Model(core.Model):
class ObjectType(core.ObjectType):
@cached_property
def methods(self) -> List["Method"]:
return [m for m in super().methods if not m.out_parameters or m.optional_out_parameter is not None]
@cached_property
def py_name(self) -> str:
custom = self.customizations
@@ -144,6 +148,7 @@ class Method(core.Method):
custom = self.customizations
return custom.custom_logic if custom is not None else None
class Property(core.Property):
pass
@@ -276,6 +281,7 @@ def _make_class(
type_struct,
parent,
constructors,
functions,
methods,
properties,
signals,
@@ -290,6 +296,7 @@ def _make_class(
type_struct,
parent,
constructors,
functions,
methods,
properties,
signals,
@@ -306,6 +313,7 @@ def _make_interface(
type_struct,
parent,
constructors,
functions,
methods,
properties,
signals,
@@ -319,6 +327,7 @@ def _make_interface(
type_struct,
parent,
constructors,
functions,
methods,
properties,
signals,
+1 -1
Submodule releng updated: c9cc18138b...a3f1a54307.
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/frida-core.git
revision = 17.17.0
revision = 17.25.0
depth = 1
[provide]