- Switch to pyproject macros.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-Js2Py?expand=0&rev=26
This commit is contained in:
2025-06-27 02:55:39 +00:00
committed by Git OBS Bridge
commit 56da916f63
10 changed files with 1548 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.osc

159
313-compatibility.patch Normal file
View File

@@ -0,0 +1,159 @@
From 0da30c83f149b15539ca3d246d5ebfb0afd7f140 Mon Sep 17 00:00:00 2001
From: a-j-albert <aalbert@cyberdude.com>
Date: Sun, 15 Dec 2024 22:03:31 -0800
Subject: [PATCH 1/2] My changes for 3.13
---
js2py/utils/injector.py | 78 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 7 deletions(-)
--- a/js2py/utils/injector.py
+++ b/js2py/utils/injector.py
@@ -15,6 +15,10 @@ LOAD_FAST = opcode.opmap['LOAD_FAST']
LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
LOAD_ATTR = opcode.opmap['LOAD_ATTR']
STORE_FAST = opcode.opmap['STORE_FAST']
+LOAD_FAST_LOAD_FAST = opcode.opmap.get('LOAD_FAST_LOAD_FAST')
+STORE_FAST_LOAD_FAST = opcode.opmap.get('STORE_FAST_LOAD_FAST')
+STORE_FAST_STORE_FAST = opcode.opmap.get('STORE_FAST_STORE_FAST')
+EXTENDED_ARG = opcode.opmap.get('EXTENDED_ARG')
_func_closure = "__closure__"
@@ -43,6 +47,40 @@ def fix_js_args(func):
closure=get_function_closure(func))
return result
+def get_list_of_var_indices_in_compound_opcodes(code_obj, non_arg_varnames, arg_count): #E.g. STORE_FAST_LOAD_FAST
+ indices = set()
+ for inst in instructions(code_obj):
+ extended = False
+ if inst.opcode == EXTENDED_ARG:
+ extended = True
+ continue
+ if not extended and inst.opcode in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
+ first_index = (inst.arg >> 4 & 0xF) - arg_count
+ second_index = (inst.arg & 0xF) - arg_count
+ if first_index >= 0:
+ indices.add(first_index)
+ if second_index >= 0:
+ indices.add(second_index)
+ extended = False
+ return indices
+
+def rearrange_by_indices(strings, indices):
+ """
+ Rearranges the strings in the list so that the elements corresponding
+ to the indices are at the beginning of the list.
+
+ Args:
+ strings (list): The list of strings.
+ indices (list): A list of indices into the strings list.
+
+ Returns:
+ list: A new list with rearranged elements.
+ """
+ # Extract elements based on indices
+ prioritized = [strings[i] for i in indices if 0 <= i < len(strings)]
+ # Include elements not in indices
+ remaining = [strings[i] for i in range(len(strings)) if i not in indices]
+ return prioritized + remaining
def append_arguments(code_obj, new_locals):
co_varnames = code_obj.co_varnames # Old locals
@@ -56,9 +94,9 @@ def append_arguments(code_obj, new_local
# left in code_obj.co_names.
not_removed = set(opcode.hasname) - set([LOAD_GLOBAL])
saved_names = set()
- for inst in instructions(code_obj):
- if inst[0] in not_removed:
- saved_names.add(co_names[inst[1]])
+ # for inst in instructions(code_obj):
+ # if inst.opcode in not_removed:
+ # saved_names.add(co_names[inst.oparg])
# Build co_names for the new code object. This should consist of
# globals that were only accessed via LOAD_GLOBAL
@@ -70,18 +108,21 @@ def append_arguments(code_obj, new_local
name_translations = dict(
(co_names.index(name), i) for i, name in enumerate(names))
+ non_arg_varnames = co_varnames[co_argcount:] # All varibles after the arguments
+ early_indices = get_list_of_var_indices_in_compound_opcodes(code_obj, non_arg_varnames, co_argcount)
+ rearranged_non_arg_varnames = rearrange_by_indices(non_arg_varnames, early_indices)
# Build co_varnames for the new code object. This should consist of
# the entirety of co_varnames with new_locals spliced in after the
# arguments
new_locals_len = len(new_locals)
varnames = (
- co_varnames[:co_argcount] + new_locals + co_varnames[co_argcount:])
+ co_varnames[:co_argcount] + new_locals + tuple(rearranged_non_arg_varnames))
# Build the dictionary that maps indices of entries in the old co_varnames
# to their indices in the new co_varnames
range1, range2 = xrange(co_argcount), xrange(co_argcount, len(co_varnames))
varname_translations = dict((i, i) for i in range1)
- varname_translations.update((i, i + new_locals_len) for i in range2)
+ varname_translations.update((i, varnames.index(co_varnames[i])) for i in range2)
# Build the dictionary that maps indices of deleted entries of co_names
# to their indices in the new co_varnames
@@ -94,6 +135,7 @@ def append_arguments(code_obj, new_local
modified = []
drop_future_cache = False
for inst in instructions(code_obj):
+ # print(inst.opname + ' - ' + str(inst.line_number))
if is_new_bytecode and inst.opname == "CACHE":
assert inst.arg == 0
if not drop_future_cache:
@@ -124,9 +166,18 @@ def append_arguments(code_obj, new_local
arg = tgt
else:
raise(ValueError("a name was lost in translation last instruction %s" % str(inst)))
+ elif inst.opcode in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
+ old_first_arg = inst.arg >> 4 & 0xF
+ old_second_arg = inst.arg & 0xF
+ new_first_arg = varname_translations[old_first_arg]
+ new_second_arg = varname_translations[old_second_arg]
+ arg = new_first_arg << 4 | new_second_arg
# If it accesses co_varnames or co_names then update its argument.
elif inst.opcode in opcode.haslocal:
- arg = varname_translations[inst.arg]
+ if arg < len(varname_translations): # Otherwise cellvar whose arg gets incremented by new_locals_len
+ arg = varname_translations[inst.arg]
+ else:
+ arg += new_locals_len
elif inst.opcode in opcode.hasname:
# for example STORE_GLOBAL
arg = name_translations[inst.arg]
@@ -135,6 +186,12 @@ def append_arguments(code_obj, new_local
if inst.argval not in code_obj.co_varnames[:code_obj.co_argcount]: # we do not need to remap existing arguments, they are not shifted by new ones.
arg = inst.arg + len(new_locals)
modified.extend(write_instruction(op, arg))
+ if hasattr(inst, 'end_offset'): # Assume otherwise instructions will have explicit CACHE entries
+ for inline_cache in range(int((inst.end_offset - inst.cache_offset) / 2)):
+ if not drop_future_cache:
+ modified.extend(write_instruction(0, 0))
+ else:
+ modified.extend(write_instruction(dis.opmap["NOP"], 0))
code = bytes(modified)
args = (co_argcount + new_locals_len, 0,
code_obj.co_nlocals + new_locals_len, code_obj.co_stacksize,
@@ -229,9 +286,16 @@ def check(code_obj):
pos_to_inst = {}
bytelist = []
+ offset = 0
+ instruction_bytes = None
for inst in insts:
pos_to_inst[len(bytelist)] = inst
- bytelist.extend(write_instruction(inst.opcode, inst.arg))
+ if instruction_bytes:
+ for gap_byte in range(inst.offset - offset - len(instruction_bytes)):
+ bytelist.append(0)
+ offset = inst.offset
+ instruction_bytes = write_instruction(inst.opcode, inst.arg)
+ bytelist.extend(instruction_bytes)
new_bytecode = bytes(bytelist)
if new_bytecode != old_bytecode:
print(new_bytecode)

13
CVE-2024-28397.patch Normal file
View File

@@ -0,0 +1,13 @@
Index: Js2Py-0.74/js2py/constructors/jsobject.py
===================================================================
--- Js2Py-0.74.orig/js2py/constructors/jsobject.py
+++ Js2Py-0.74/js2py/constructors/jsobject.py
@@ -48,7 +48,7 @@ class ObjectMethods:
raise MakeError(
'TypeError',
'Object.getOwnPropertyDescriptor called on non-object')
- return obj.own.keys()
+ return list(obj.own.keys())
def create(obj):
if not (obj.is_object() or obj.is_null()):

BIN
Js2Py-0.74.tar.gz LFS Normal file

Binary file not shown.

19
LICENSE.md Normal file
View File

@@ -0,0 +1,19 @@
The MIT License
Copyright © 2014, 2015 Piotr Dabkowski
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, subject
to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

85
python-Js2Py.changes Normal file
View File

@@ -0,0 +1,85 @@
-------------------------------------------------------------------
Fri Jun 27 02:47:33 UTC 2025 - Steve Kowalik <steven.kowalik@suse.com>
- Switch to pyproject macros.
-------------------------------------------------------------------
Wed Jan 1 23:38:45 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Add 313-compatibility.patch (gh#PiotrDabkowski/Js2Py#334)
-------------------------------------------------------------------
Mon Jul 1 08:39:07 UTC 2024 - Daniel Garcia <daniel.garcia@suse.com>
- Add CVE-2024-28397.patch upstream patch.
(bsc#1226660, gh#PiotrDabkowski/Js2Py#323)
-------------------------------------------------------------------
Mon Jul 1 08:19:03 UTC 2024 - Daniel Garcia <daniel.garcia@suse.com>
- Run tests
- Add patches:
* remove-python-six.patch, to remove python-six dependency
* python312.patch, to make it compatible with python312
-------------------------------------------------------------------
Fri Apr 21 12:20:47 UTC 2023 - Dirk Müller <dmueller@suse.com>
- add sle15_python_module_pythons (jsc#PED-68)
-------------------------------------------------------------------
Thu Apr 13 22:42:18 UTC 2023 - Matej Cepl <mcepl@suse.com>
- Make calling of %{sle15modernpython} optional.
-------------------------------------------------------------------
Thu Dec 1 17:54:56 UTC 2022 - Yogalakshmi Arunachalam <yarunachalam@suse.com>
- Update to version 0.74
* remove template and opname not supported in old python version
* support python 3.11 bytecode, fixes #282
-------------------------------------------------------------------
Tue May 24 08:04:00 UTC 2022 - Alberto Planas Dominguez <aplanas@suse.com>
- Update to version 0.71
* Some small fixes
-------------------------------------------------------------------
Fri Apr 17 09:27:55 UTC 2020 - Marketa Calabkova <mcalabkova@suse.com>
- update to version 0.70
* fix error messages
-------------------------------------------------------------------
Thu Mar 26 10:48:08 UTC 2020 - Marketa Calabkova <mcalabkova@suse.com>
- update to version 0.68
* fix error msg from python function
* Fix print functions and a python2 only import
-------------------------------------------------------------------
Mon Jan 13 16:31:02 UTC 2020 - Marketa Calabkova <mcalabkova@suse.com>
- update to version 0.67
* small bugfixes
-------------------------------------------------------------------
Fri Jul 26 07:44:48 UTC 2019 - Marketa Calabkova <mcalabkova@suse.com>
- update to version 0.66
* Convert exponential numbers to string
* Fix inconsistency between py2 and py3 jsdtoa
* fix object initialized too early case
* Try to add Python 3.7 and 3.8 (dev).
* Drop support for unsupported Python versions.
-------------------------------------------------------------------
Thu Mar 14 16:37:17 UTC 2019 - Jan Engelhardt <jengelh@inai.de>
- Remove wrong statements from description.
-------------------------------------------------------------------
Wed Mar 13 15:43:11 UTC 2019 - Ondřej Súkup <mimi.vx@gmail.com>
- initial commit

78
python-Js2Py.spec Normal file
View File

@@ -0,0 +1,78 @@
#
# spec file for package python-Js2Py
#
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%{?sle15_python_module_pythons}
Name: python-Js2Py
Version: 0.74
Release: 0
Summary: JavaScript to Python Translator & JavaScript interpreter
License: MIT
URL: https://github.com/PiotrDabkowski/Js2Py
Source: https://files.pythonhosted.org/packages/source/J/Js2Py/Js2Py-%{version}.tar.gz
Source1: https://raw.githubusercontent.com/PiotrDabkowski/Js2Py/master/LICENSE.md
# PATCH-FIX-OPENSUSE remove-python-six.patch
Patch0: remove-python-six.patch
# PATCH-FIX-UPSTREAM python312.patch gh#PiotrDabkowski/Js2Py#327
Patch1: python312.patch
# PATCH-FIX-UPSTREAM CVE-2024-28397.patch gh#PiotrDabkowski/Js2Py#323
Patch2: CVE-2024-28397.patch
# PATCH-FIX-UPSTREAM 313-compatibility.patch gh#PiotrDabkowski/Js2Py#334 mcepl@suse.com
# Compatibility with Python 3.13
Patch3: 313-compatibility.patch
BuildRequires: %{python_module pip}
BuildRequires: %{python_module pyjsparser}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-pyjsparser
Requires: python-tzlocal
BuildArch: noarch
%python_subpackages
%description
Translates JavaScript to Python code. Js2Py is able to translate and
execute virtually any JavaScript code. Js2Py, basically an
implementation of the JavaScript core, is written in pure Python.
%prep
%autosetup -p1 -n Js2Py-%{version}
cp %{SOURCE1} .
%build
%pyproject_wheel
%install
%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
pushd tests
touch node_failed.txt
%{python_expand #
PYTHONPATH=%{buildroot}%{$python_sitelib} $python run.py
}
popd
%files %{python_files}
%doc README.md
%license LICENSE.md
%{python_sitelib}/js2py
%{python_sitelib}/[Jj]s2[Pp]y-%{version}.dist-info
%changelog

57
python312.patch Normal file
View File

@@ -0,0 +1,57 @@
From fd7df4a91fb08060914c7b1d9e94583d18f3371b Mon Sep 17 00:00:00 2001
From: Felix Yan <felixonmars@archlinux.org>
Date: Wed, 17 Apr 2024 16:47:47 +0300
Subject: [PATCH] Fix bytecode for Python 3.12
`LOAD_ATTR` has been changed in Python 3.12 and it seems reusing the
`LOAD_GLOBAL` logic makes the simple tests passing.
I am not sure if this is correct since I'm pretty new to the code, but
maybe it's still helpful.
---
js2py/translators/translating_nodes.py | 2 +-
js2py/utils/injector.py | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
Index: Js2Py-0.74/js2py/translators/translating_nodes.py
===================================================================
--- Js2Py-0.74.orig/js2py/translators/translating_nodes.py
+++ Js2Py-0.74/js2py/translators/translating_nodes.py
@@ -538,7 +538,7 @@ def TryStatement(type, block, handler, h
if handler:
identifier = handler['param']['name']
holder = 'PyJsHolder_%s_%d' % (to_hex(identifier),
- random.randrange(1e8))
+ random.randrange(six.integer_types[-1](1e8)))
identifier = repr(identifier)
result += 'except PyJsException as PyJsTempException:\n'
# fill in except ( catch ) block and remember to recover holder variable to its previous state
Index: Js2Py-0.74/js2py/utils/injector.py
===================================================================
--- Js2Py-0.74.orig/js2py/utils/injector.py
+++ Js2Py-0.74/js2py/utils/injector.py
@@ -13,6 +13,7 @@ chr = lambda x: x
# Opcode constants used for comparison and replacecment
LOAD_FAST = opcode.opmap['LOAD_FAST']
LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
+LOAD_ATTR = opcode.opmap['LOAD_ATTR']
STORE_FAST = opcode.opmap['STORE_FAST']
@@ -88,6 +89,7 @@ def append_arguments(code_obj, new_local
(co_names.index(name), varnames.index(name)) for name in new_locals)
is_new_bytecode = sys.version_info >= (3, 11)
+ is_new_load_attr = sys.version_info >= (3, 12)
# Now we modify the actual bytecode
modified = []
drop_future_cache = False
@@ -106,7 +108,7 @@ def append_arguments(code_obj, new_local
# it's one of the globals that we are replacing. Either way,
# update its arg using the appropriate dict.
drop_future_cache = False
- if inst.opcode == LOAD_GLOBAL:
+ if inst.opcode == LOAD_GLOBAL or (is_new_load_attr and inst.opcode == LOAD_ATTR):
idx = inst.arg
if is_new_bytecode:
idx = idx // 2

1110
remove-python-six.patch Normal file

File diff suppressed because it is too large Load Diff