Re: [Question] Could the max code size check be optional?

"x4e_x4e" (via asm Mailing List) <[email protected]> Wed, 17 Mar 2021 14:28:41 +0000
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <rUjTjPk7uKbH8nTrQnZ_83SQ5WgoM-Z14GoSiq2yCcFPQAq4yMhJ2KduP6h81zCTtrSf3ggDHjQviNCjhrgKqulPB5E9tf6A0KN1bwTo_Y0=@protonmail.com>
This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
-----------------------6a8a633f240f5e0d9cc8b62cf251d1f5
Content-Type: multipart/mixed;boundary=---------------------a0e47617f6032d1dd3dd8bbceef998bf

-----------------------a0e47617f6032d1dd3dd8bbceef998bf
Content-Type: multipart/alternative;boundary=---------------------0ff0aabfa4007b3025daff0b5f4d8c53

-----------------------0ff0aabfa4007b3025daff0b5f4d8c53
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;charset=utf-8

> In the sense, that the frame computation and max local/stack is coupled =
to it. Currently, those features can't be used without a MethodWriter (ple=
ase correct me otherwise!).

I would say they are more a utility added onto the MethodWriter in case yo=
u don't update the maxLocals and maxStack yourself.

> Would it be better that those analyses/transformations are available and=
 required to be executed before actually calling the MethodWriter? In this=
 way, the MethodWriter just writes the legal and valid method structure of=
 the class file. In addition, in case you need to compute the max stack/lo=
cal and frames for a method node you can use that functionality without ca=
lling a MethodWriter.

I think it would certainly be useful to have it available before calling t=
he MethodWriter (though not a requirement, calculating it within the Metho=
dWriter would be faster than first passing it through a separate calculato=
r).

It would be duplicating the functionality of the MethodWriter, however I d=
on't think that is much of a problem, as the actual stack and local size c=
alculation performed in MethodWriter is a very small part of the large cod=
e existing for frame generation. Removing it from the MethodWriter would n=
ot have much purpose - the code that performs all the calculations for the=
 stack and local size calculations would still need to remain to support t=
he frame calculations.

> In the current design, is it possible to calculate these things without =
calling the MethodWriter? I'm assuming it is not possible.

It is possible, you would just have to write it yourself - or it could per=
haps be included in asm-commons. A similar thing already exists (AnalyzerA=
dapter) but I think it only works with bytecode that has updated stackfram=
es - I assume if you are not updating the maxLocals and maxStack you are a=
lso not updating frames.

x4e

=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Original M=
essage =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90
On Wednesday, March 17th, 2021 at 13:45, Manuel Carrasco <mgcarrasco2012@g=
mail.com> wrote:

> Thanks for your answer!
> =


> > In my opinion the MethodWriter should be designed to fit one purpose -=
 writing the (legal and valid) method structure of the classfile.
> =


> Yes, I do agree, but I think the MethodWriter is not actually doing that=
. In the sense, that the frame computation and max local/stack is coupled =
to it. Currently, those features can't be used without a MethodWriter (ple=
ase correct me otherwise!). Would it be better that those analyses/transfo=
rmations are available and required to be executed before actually calling=
 the MethodWriter? In this way, the MethodWriter just writes the legal and=
 valid method structure of the class file. In addition, in case you need t=
o compute the max stack/local and frames for a method node you can use tha=
t functionality without calling a MethodWriter.
> =


> > Perhaps a better way to do this would be to write a custom method visi=
tor that is able to calculate this for you?
> =


> That can work but the problem that I see is that we would duplicate the =
functionality that is already in the MethodWriter.
> =


> In the current design, is it possible to calculate these things without =
calling the MethodWriter? I'm assuming it is not possible.
> =


> Thanks again!
> =


> Cheers,
> Manuel.
> =


> El mi=C3=A9, 17 mar 2021 a las 12:25, x4e_x4e (<[email protected]>)=
 escribi=C3=B3:
> =


> > Hi Manuel,
> > =


> > In my opinion the MethodWriter should be designed to fit one purpose -=
 writing the (legal and valid) method structure of the classfile. It would=
 seem strange for it to also be used as a way of calculating the max stack=
/locals in a method for the user. Especially because the intended output o=
f the methodvisitor would be not just illegal but physically invalid, and =
no longer conform to the classfile=E2=80=99s structure from the specificat=
ion (not just the verifier/formatting rules).
> > =


> > Perhaps a better way to do this would be to write a custom method visi=
tor that is able to calculate this for you?
> > =


> > x4e
> > =


> > =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Origin=
al Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90
> > On Wednesday, March 17th, 2021 at 11:09, Manuel Carrasco <[email protected]>=
 wrote:
> > =


> > > Hi,
> > > =


> > > How are you?
> > > =


> > > I noticed that the MethodWriter currently (184aaa9f0ec4c233872087a3c=
4d2d96a3c204ac6) throws an exception when the method size exceeds the maxi=
mum allowed by the JVM. The intent is clear to me, the library wants to em=
it Java bytecode that is legal in terms of the specification. My question =
is, could we make this check optional and true by default?
> > > =


> > > In case that you want to perform an optimization to shrink your code=
, you may require to have the max stack and local as well as the stack map=
 frames available. So, you execute the ClassWriter to compute them, but it=
 will crash as soon the MethodWriter verifies the maximum code size.=C2=A0
> > > =


> > > The current implementation is limiting user optimizations on their c=
ode in case it has already exceeded the maximum limit. At least, it is not=
 allowing them to compute the max stack and local as well as the map stack=
 frames.
> > > =


> > > I tested commenting the check and emitting the code. It didn't crash=
, and I could optimize it, so it can be executed by the JVM.
> > > =


> > > Considering all this, I'd like to know if you consider reasonable to=
 make the max code size check optional. Perhaps, I'm missing some other te=
chnical reason that could make this impossible.
> > > =


> > > Thanks in advance!
> > > =


> > > Cheers,
> > > Manuel.
-----------------------0ff0aabfa4007b3025daff0b5f4d8c53
Content-Type: multipart/related;boundary=---------------------bf2dc6de2e5386d5d34337d89d7b9a6d

-----------------------bf2dc6de2e5386d5d34337d89d7b9a6d
Content-Type: text/html;charset=utf-8
Content-Transfer-Encoding: base64

PGRpdj4mZ3Q7IEluIHRoZSBzZW5zZSwgdGhhdCB0aGUgZnJhbWUgY29tcHV0YXRpb24gYW5kIG1h
eCBsb2NhbC9zdGFjayBpcyBjb3VwbGVkIHRvIGl0LiBDdXJyZW50bHksIHRob3NlIGZlYXR1cmVz
IGNhbid0IGJlIHVzZWQgd2l0aG91dCBhIE1ldGhvZFdyaXRlciAgKHBsZWFzZSBjb3JyZWN0IG1l
IG90aGVyd2lzZSEpLjxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2Pkkgd291bGQgc2F5IHRo
ZXkgYXJlIG1vcmUgYSB1dGlsaXR5IGFkZGVkIG9udG8gdGhlIE1ldGhvZFdyaXRlciBpbiBjYXNl
IHlvdSBkb24ndCB1cGRhdGUgdGhlIG1heExvY2FscyBhbmQgbWF4U3RhY2sgeW91cnNlbGYuPGJy
PjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jmd0OyBXb3VsZCBpdCBiZSBiZXR0ZXIgdGhhdCB0
aG9zZSBhbmFseXNlcy90cmFuc2Zvcm1hdGlvbnMgYXJlIGF2YWlsYWJsZSBhbmQgcmVxdWlyZWQg
dG8gYmUgZXhlY3V0ZWQgYmVmb3JlIGFjdHVhbGx5IGNhbGxpbmcgdGhlIE1ldGhvZFdyaXRlcj8g
SW4gdGhpcyB3YXksIHRoZSBNZXRob2RXcml0ZXIganVzdCB3cml0ZXMgdGhlIGxlZ2FsIGFuZCB2
YWxpZCBtZXRob2Qgc3RydWN0dXJlIG9mIHRoZSBjbGFzcyBmaWxlLiBJbiBhZGRpdGlvbiwgaW4g
Y2FzZSB5b3UgbmVlZCB0byBjb21wdXRlIHRoZSBtYXggc3RhY2svbG9jYWwgYW5kIGZyYW1lcyBm
b3IgYSBtZXRob2Qgbm9kZSB5b3UgY2FuIHVzZSB0aGF0IGZ1bmN0aW9uYWxpdHkgd2l0aG91dCBj
YWxsaW5nIGEgTWV0aG9kV3JpdGVyLjxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkkgdGhp
bmsgaXQgd291bGQgY2VydGFpbmx5IGJlIHVzZWZ1bCB0byBoYXZlIGl0IGF2YWlsYWJsZSBiZWZv
cmUgY2FsbGluZyB0aGUgTWV0aG9kV3JpdGVyICh0aG91Z2ggbm90IGEgcmVxdWlyZW1lbnQsIGNh
bGN1bGF0aW5nIGl0IHdpdGhpbiB0aGUgTWV0aG9kV3JpdGVyIHdvdWxkIGJlIGZhc3RlciB0aGFu
IGZpcnN0IHBhc3NpbmcgaXQgdGhyb3VnaCBhIHNlcGFyYXRlIGNhbGN1bGF0b3IpLjxicj48L2Rp
dj48ZGl2Pjxicj48L2Rpdj48ZGl2Pkl0IHdvdWxkIGJlIGR1cGxpY2F0aW5nIHRoZSBmdW5jdGlv
bmFsaXR5IG9mIHRoZSBNZXRob2RXcml0ZXIsIGhvd2V2ZXIgSSBkb24ndCB0aGluayB0aGF0IGlz
IG11Y2ggb2YgYSBwcm9ibGVtLCBhcyB0aGUgYWN0dWFsIHN0YWNrIGFuZCBsb2NhbCBzaXplIGNh
bGN1bGF0aW9uIHBlcmZvcm1lZCBpbiBNZXRob2RXcml0ZXIgaXMgYSB2ZXJ5IHNtYWxsIHBhcnQg
b2YgdGhlIGxhcmdlIGNvZGUgZXhpc3RpbmcgZm9yIGZyYW1lIGdlbmVyYXRpb24uIFJlbW92aW5n
IGl0IGZyb20gdGhlIE1ldGhvZFdyaXRlciB3b3VsZCBub3QgaGF2ZSBtdWNoIHB1cnBvc2UgLSB0
aGUgY29kZSB0aGF0IHBlcmZvcm1zIGFsbCB0aGUgY2FsY3VsYXRpb25zIGZvciB0aGUgc3RhY2sg
YW5kIGxvY2FsIHNpemUgY2FsY3VsYXRpb25zIHdvdWxkIHN0aWxsIG5lZWQgdG8gcmVtYWluIHRv
IHN1cHBvcnQgdGhlIGZyYW1lIGNhbGN1bGF0aW9ucy48YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+
PGRpdj4mZ3Q7IEluIHRoZSBjdXJyZW50IGRlc2lnbiwgaXMgaXQgcG9zc2libGUgdG8gY2FsY3Vs
YXRlIHRoZXNlIHRoaW5ncyB3aXRob3V0IGNhbGxpbmcgdGhlIE1ldGhvZFdyaXRlcj8gSSdtIGFz
c3VtaW5nIGl0IGlzIG5vdCBwb3NzaWJsZS48YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5J
dCBpcyBwb3NzaWJsZSwgeW91IHdvdWxkIGp1c3QgaGF2ZSB0byB3cml0ZSBpdCB5b3Vyc2VsZiAt
IG9yIGl0IGNvdWxkIHBlcmhhcHMgYmUgaW5jbHVkZWQgaW4gYXNtLWNvbW1vbnMuIEEgc2ltaWxh
ciB0aGluZyBhbHJlYWR5IGV4aXN0cyAoQW5hbHl6ZXJBZGFwdGVyKSBidXQgSSB0aGluayBpdCBv
bmx5IHdvcmtzIHdpdGggYnl0ZWNvZGUgdGhhdCBoYXMgdXBkYXRlZCBzdGFja2ZyYW1lcyAtIEkg
YXNzdW1lIGlmIHlvdSBhcmUgbm90IHVwZGF0aW5nIHRoZSBtYXhMb2NhbHMgYW5kIG1heFN0YWNr
IHlvdSBhcmUgYWxzbyBub3QgdXBkYXRpbmcgZnJhbWVzLiA8YnI+PC9kaXY+PGRpdj48YnI+PC9k
aXY+PGRpdj54NGU8YnI+PC9kaXY+PGRpdiBjbGFzcz0icHJvdG9ubWFpbF9zaWduYXR1cmVfYmxv
Y2sgcHJvdG9ubWFpbF9zaWduYXR1cmVfYmxvY2stZW1wdHkiPjxkaXYgY2xhc3M9InByb3Rvbm1h
aWxfc2lnbmF0dXJlX2Jsb2NrLXVzZXIgcHJvdG9ubWFpbF9zaWduYXR1cmVfYmxvY2stZW1wdHki
PjwvZGl2PjxkaXYgY2xhc3M9InByb3Rvbm1haWxfc2lnbmF0dXJlX2Jsb2NrLXByb3RvbiBwcm90
b25tYWlsX3NpZ25hdHVyZV9ibG9jay1lbXB0eSI+PC9kaXY+PC9kaXY+PGRpdj48YnI+PC9kaXY+
PGRpdiBjbGFzcz0icHJvdG9ubWFpbF9xdW90ZSI+PGRpdj7igJDigJDigJDigJDigJDigJDigJAg
T3JpZ2luYWwgTWVzc2FnZSDigJDigJDigJDigJDigJDigJDigJA8YnI+PC9kaXY+PGRpdj5PbiBX
ZWRuZXNkYXksIE1hcmNoIDE3dGgsIDIwMjEgYXQgMTM6NDUsIE1hbnVlbCBDYXJyYXNjbyAmbHQ7
bWdjYXJyYXNjbzIwMTJAZ21haWwuY29tJmd0OyB3cm90ZTo8YnI+PC9kaXY+PC9kaXY+PGJsb2Nr
cXVvdGUgdHlwZT0iY2l0ZSIgY2xhc3M9InByb3Rvbm1haWxfcXVvdGUiPjxkaXYgZGlyPSJsdHIi
PjxkaXY+VGhhbmtzIGZvciB5b3VyIGFuc3dlciE8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGJs
b2NrcXVvdGUgc3R5bGU9Im1hcmdpbjowcHggMHB4IDBweCAwLjhleDtib3JkZXItbGVmdDoxcHgg
c29saWQgcmdiKDIwNCwyMDQsMjA0KTtwYWRkaW5nLWxlZnQ6MWV4IiBjbGFzcz0iZ21haWxfcXVv
dGUiPjxkaXY+SW4gbXkgb3BpbmlvbiB0aGUgTWV0aG9kV3JpdGVyIHNob3VsZCBiZSBkZXNpZ25l
ZCB0byBmaXQgb25lIHB1cnBvc2UgLQp3cml0aW5nIHRoZSAobGVnYWwgYW5kIHZhbGlkKSBtZXRo
b2Qgc3RydWN0dXJlIG9mIHRoZSBjbGFzc2ZpbGUuPGJyPjwvZGl2PjwvYmxvY2txdW90ZT48ZGl2
Pjxicj48L2Rpdj48ZGl2PlllcywgSSBkbyBhZ3JlZSwgYnV0IEkgdGhpbmsgdGhlIE1ldGhvZFdy
aXRlciBpcyBub3QgYWN0dWFsbHkgZG9pbmcgdGhhdC4gSW4gdGhlIHNlbnNlLCB0aGF0IHRoZSBm
cmFtZSBjb21wdXRhdGlvbiBhbmQgbWF4IGxvY2FsL3N0YWNrIGlzIGNvdXBsZWQgdG8gaXQuIEN1
cnJlbnRseSwgdGhvc2UgZmVhdHVyZXMgY2FuJ3QgYmUgdXNlZCB3aXRob3V0IGEgTWV0aG9kV3Jp
dGVyICAocGxlYXNlIGNvcnJlY3QgbWUgb3RoZXJ3aXNlISkuIFdvdWxkIGl0IGJlIGJldHRlciB0
aGF0IHRob3NlIGFuYWx5c2VzL3RyYW5zZm9ybWF0aW9ucyBhcmUgYXZhaWxhYmxlIGFuZCByZXF1
aXJlZCB0byBiZSBleGVjdXRlZCBiZWZvcmUgYWN0dWFsbHkgY2FsbGluZyB0aGUgTWV0aG9kV3Jp
dGVyPyBJbiB0aGlzIHdheSwgdGhlIE1ldGhvZFdyaXRlciBqdXN0IHdyaXRlcyB0aGUgbGVnYWwg
YW5kIHZhbGlkIG1ldGhvZCBzdHJ1Y3R1cmUgb2YgdGhlIGNsYXNzIGZpbGUuIEluIGFkZGl0aW9u
LCBpbiBjYXNlIHlvdSBuZWVkIHRvIGNvbXB1dGUgdGhlIG1heCBzdGFjay9sb2NhbCBhbmQgZnJh
bWVzIGZvciBhIG1ldGhvZCBub2RlIHlvdSBjYW4gdXNlIHRoYXQgZnVuY3Rpb25hbGl0eSB3aXRo
b3V0IGNhbGxpbmcgYSBNZXRob2RXcml0ZXIuPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxibG9j
a3F1b3RlIHN0eWxlPSJtYXJnaW46MHB4IDBweCAwcHggMC44ZXg7Ym9yZGVyLWxlZnQ6MXB4IHNv
bGlkIHJnYigyMDQsMjA0LDIwNCk7cGFkZGluZy1sZWZ0OjFleCIgY2xhc3M9ImdtYWlsX3F1b3Rl
Ij48ZGl2PlBlcmhhcHMgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXMgd291bGQgYmUgdG8gd3JpdGUg
YSBjdXN0b20gbWV0aG9kIHZpc2l0b3IgdGhhdCBpcyBhYmxlIHRvIGNhbGN1bGF0ZSB0aGlzIGZv
ciB5b3U/PGJyPjwvZGl2PjwvYmxvY2txdW90ZT48ZGl2Pjxicj48L2Rpdj48ZGl2PlRoYXQgY2Fu
IHdvcmsgYnV0IHRoZSBwcm9ibGVtIHRoYXQgSSBzZWUgaXMgdGhhdCB3ZSB3b3VsZCBkdXBsaWNh
dGUgdGhlIGZ1bmN0aW9uYWxpdHkgdGhhdCBpcyBhbHJlYWR5IGluIHRoZSBNZXRob2RXcml0ZXIu
PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SW4gdGhlIGN1cnJlbnQgZGVzaWduLCBpcyBp
dCBwb3NzaWJsZSB0byBjYWxjdWxhdGUgdGhlc2UgdGhpbmdzIHdpdGhvdXQgY2FsbGluZyB0aGUg
TWV0aG9kV3JpdGVyPyBJJ20gYXNzdW1pbmcgaXQgaXMgbm90IHBvc3NpYmxlLiA8YnI+PC9kaXY+
PGRpdj48YnI+PC9kaXY+PGRpdj5UaGFua3MgYWdhaW4hPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2
PjxkaXY+Q2hlZXJzLDxicj48L2Rpdj48ZGl2Pk1hbnVlbC48YnI+PC9kaXY+PGRpdj48YnI+PC9k
aXY+PGRpdj48YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRp
diBjbGFzcz0iZ21haWxfcXVvdGUiPjxkaXYgZGlyPSJsdHIiPkVsIG1pw6ksIDE3IG1hciAyMDIx
IGEgbGFzIDEyOjI1LCB4NGVfeDRlICgmbHQ7PGEgcmVsPSJub3JlZmVycmVyIG5vZm9sbG93IG5v
b3BlbmVyIiBocmVmPSJtYWlsdG86eDRlX3g0ZUBwcm90b25tYWlsLmNvbSI+eDRlX3g0ZUBwcm90
b25tYWlsLmNvbTwvYT4mZ3Q7KSBlc2NyaWJpw7M6PGJyPjwvZGl2PjxibG9ja3F1b3RlIHN0eWxl
PSJtYXJnaW46MHB4IDBweCAwcHggMC44ZXg7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkIHJnYigyMDQs
MjA0LDIwNCk7cGFkZGluZy1sZWZ0OjFleCIgY2xhc3M9ImdtYWlsX3F1b3RlIj48ZGl2PjxkaXY+
SGkgTWFudWVsLDxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkluIG15IG9waW5pb24gdGhl
IE1ldGhvZFdyaXRlciBzaG91bGQgYmUgZGVzaWduZWQgdG8gZml0IG9uZSBwdXJwb3NlIC0gd3Jp
dGluZyB0aGUgKGxlZ2FsIGFuZCB2YWxpZCkgbWV0aG9kIHN0cnVjdHVyZSBvZiB0aGUgY2xhc3Nm
aWxlLiBJdCB3b3VsZCBzZWVtIHN0cmFuZ2UgZm9yIGl0IHRvIGFsc28gYmUgdXNlZCBhcyBhIHdh
eSBvZiBjYWxjdWxhdGluZyB0aGUgbWF4IHN0YWNrL2xvY2FscyBpbiBhIG1ldGhvZCBmb3IgdGhl
IHVzZXIuIEVzcGVjaWFsbHkgYmVjYXVzZSB0aGUgaW50ZW5kZWQgb3V0cHV0IG9mIHRoZSBtZXRo
b2R2aXNpdG9yIHdvdWxkIGJlIG5vdCBqdXN0IGlsbGVnYWwgYnV0IHBoeXNpY2FsbHkgaW52YWxp
ZCwgYW5kIG5vIGxvbmdlciBjb25mb3JtIHRvIHRoZSBjbGFzc2ZpbGXigJlzIHN0cnVjdHVyZSBm
cm9tIHRoZSBzcGVjaWZpY2F0aW9uIChub3QganVzdCB0aGUgdmVyaWZpZXIvZm9ybWF0dGluZyBy
dWxlcykuPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+UGVyaGFwcyBhIGJldHRlciB3YXkg
dG8gZG8gdGhpcyB3b3VsZCBiZSB0byB3cml0ZSBhIGN1c3RvbSBtZXRob2QgdmlzaXRvciB0aGF0
IGlzIGFibGUgdG8gY2FsY3VsYXRlIHRoaXMgZm9yIHlvdT88dT48L3U+PHU+PC91Pjxicj48L2Rp
dj48ZGl2Pjxicj48L2Rpdj48ZGl2PjxkaXY+eDRlPGJyPjwvZGl2PjxkaXY+PGRpdj48YnI+PC9k
aXY+PGRpdj48YnI+PC9kaXY+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj48ZGl2PuKAkOKAkOKA
kOKAkOKAkOKAkOKAkCBPcmlnaW5hbCBNZXNzYWdlIOKAkOKAkOKAkOKAkOKAkOKAkOKAkDxicj48
L2Rpdj48ZGl2Pk9uIFdlZG5lc2RheSwgTWFyY2ggMTd0aCwgMjAyMSBhdCAxMTowOSwgTWFudWVs
IENhcnJhc2NvICZsdDs8YSByZWw9Im5vcmVmZXJyZXIgbm9mb2xsb3cgbm9vcGVuZXIiIHRhcmdl
dD0iX2JsYW5rIiBocmVmPSJtYWlsdG86YXNtQG93Mi5vcmciPmFzbUBvdzIub3JnPC9hPiZndDsg
d3JvdGU6PGJyPjwvZGl2PjwvZGl2PjxibG9ja3F1b3RlIHR5cGU9ImNpdGUiPjxkaXYgZGlyPSJs
dHIiPjxkaXY+SGksPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SG93IGFyZSB5b3U/PGJy
PjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SSBub3RpY2VkIHRoYXQgdGhlIE1ldGhvZFdyaXRl
ciBjdXJyZW50bHkgKDE4NGFhYTlmMGVjNGMyMzM4NzIwODdhM2M0ZDJkOTZhM2MyMDRhYzYpIHRo
cm93cyBhbiBleGNlcHRpb24gd2hlbiA8YSB0YXJnZXQ9Il9ibGFuayIgaHJlZj0iaHR0cHM6Ly9n
aXRsYWIub3cyLm9yZy9hc20vYXNtLy0vYmxvYi9tYXN0ZXIvYXNtL3NyYy9tYWluL2phdmEvb3Jn
L29iamVjdHdlYi9hc20vTWV0aG9kV3JpdGVyLmphdmEjTDIwODYiIHJlbD0ibm9yZWZlcnJlciBu
b2ZvbGxvdyBub29wZW5lciI+dGhlIG1ldGhvZCBzaXplIGV4Y2VlZHMgdGhlIG1heGltdW0gYWxs
b3dlZCBieSB0aGUgSlZNPC9hPi4gVGhlIGludGVudCBpcyBjbGVhciB0byBtZSwgdGhlIGxpYnJh
cnkgd2FudHMgdG8gZW1pdCBKYXZhIGJ5dGVjb2RlIHRoYXQgaXMgbGVnYWwgaW4gdGVybXMgb2Yg
dGhlIHNwZWNpZmljYXRpb24uIE15IHF1ZXN0aW9uIGlzLCBjb3VsZCB3ZSBtYWtlIHRoaXMgY2hl
Y2sgb3B0aW9uYWwgYW5kIHRydWUgYnkgZGVmYXVsdD88YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+
PGRpdj5JbiBjYXNlIHRoYXQgeW91IHdhbnQgdG8gcGVyZm9ybSBhbiBvcHRpbWl6YXRpb24gdG8g
c2hyaW5rIHlvdXIgY29kZSwgeW91IG1heSByZXF1aXJlIHRvIGhhdmUgdGhlIG1heCBzdGFjayBh
bmQgbG9jYWwgYXMgd2VsbCBhcyB0aGUgc3RhY2sgbWFwIGZyYW1lcyBhdmFpbGFibGUuIFNvLCB5
b3UgZXhlY3V0ZSB0aGUgQ2xhc3NXcml0ZXIgdG8gY29tcHV0ZSB0aGVtLCBidXQgaXQgd2lsbCBj
cmFzaCBhcyBzb29uIHRoZSBNZXRob2RXcml0ZXIgdmVyaWZpZXMgdGhlIG1heGltdW0gY29kZSBz
aXplLiZuYnNwOyA8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5UaGUgY3VycmVudCBpbXBs
ZW1lbnRhdGlvbiBpcyBsaW1pdGluZyB1c2VyIG9wdGltaXphdGlvbnMgb24gdGhlaXIgY29kZSBp
biBjYXNlIGl0IGhhcyBhbHJlYWR5IGV4Y2VlZGVkIHRoZSBtYXhpbXVtIGxpbWl0LiBBdCBsZWFz
dCwgaXQgaXMgbm90IGFsbG93aW5nIHRoZW0gdG8gY29tcHV0ZSB0aGUgbWF4IHN0YWNrIGFuZCBs
b2NhbCBhcyB3ZWxsIGFzIHRoZSBtYXAgc3RhY2sgZnJhbWVzLjxicj48L2Rpdj48ZGl2Pjxicj48
L2Rpdj48ZGl2PkkgdGVzdGVkIGNvbW1lbnRpbmcgdGhlIGNoZWNrIGFuZCBlbWl0dGluZyB0aGUg
Y29kZS4gSXQgZGlkbid0IGNyYXNoLCBhbmQgSSBjb3VsZCBvcHRpbWl6ZSBpdCwgc28gaXQgY2Fu
IGJlIGV4ZWN1dGVkIGJ5IHRoZSBKVk0uPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Q29u
c2lkZXJpbmcgYWxsIHRoaXMsIEknZCBsaWtlIHRvIGtub3cgaWYgeW91IGNvbnNpZGVyIHJlYXNv
bmFibGUgdG8gbWFrZSB0aGUgbWF4IGNvZGUgc2l6ZSBjaGVjayBvcHRpb25hbC4gUGVyaGFwcywg
SSdtIG1pc3Npbmcgc29tZSBvdGhlciB0ZWNobmljYWwgcmVhc29uIHRoYXQgY291bGQgbWFrZSB0
aGlzIGltcG9zc2libGUuIDxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PlRoYW5rcyBpbiBh
ZHZhbmNlITxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkNoZWVycyw8YnI+PC9kaXY+PGRp
dj5NYW51ZWwuPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjwvZGl2PjwvYmxvY2txdW90ZT48ZGl2
Pjxicj48L2Rpdj48L2Rpdj48L2Rpdj48L2Jsb2NrcXVvdGU+PC9kaXY+PC9ibG9ja3F1b3RlPjxk
aXY+PGJyPjwvZGl2Pg==
-----------------------bf2dc6de2e5386d5d34337d89d7b9a6d--
-----------------------0ff0aabfa4007b3025daff0b5f4d8c53--
-----------------------a0e47617f6032d1dd3dd8bbceef998bf
Content-Type: application/pgp-keys; filename="publickey - [email protected] - 0x155E3958.asc"; name="publickey - [email protected] - 0x155E3958.asc"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="publickey - [email protected] - 0x155E3958.asc"; name="publickey - [email protected] - 0x155E3958.asc"

LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tDQpWZXJzaW9uOiBPcGVuUEdQLmpz
IHY0LjEwLjEwDQpDb21tZW50OiBodHRwczovL29wZW5wZ3Bqcy5vcmcNCg0KeHNGTkJHQVhFVFVC
RUFDM3pSNEVkM2wwVGp5clpMZW9rNGh1TGltUWJqY1Y4cDdlSGNjM1BRRDNLSnF4DQpSazJhSllN
RWhORmdmQ2RMcW00RVRCQ0xiNFZtbUtRZ3lZT3lCczduYUpjMm0zdnU5a1JXUGZjZDMwS2ENCnlC
ZnJaWmlXQmxqbEVnMXVtSjBhWlByaVZ1VUo4bVJjcTdOZ0FHQVpGNE1XUk9kTytlbnJKVVJkQURZ
WA0KQ2pPZk9nSHAxNDg3ekhjU3NxODY1b2pwdHdaSVNPelozdCtXRTJka3R6cDBkeDIrek1jTFE1
cWc5QkRzDQovV1pLZW1rYlRRdVFCSjdENU10M3RTVGVmMU00VWpuK24zZTNMVnBTTnhQV1FpcVhN
VVpoR2hacFhvdzkNCkZZclo0TFZIeTlHVXBTVGtZZWZJSnlqanU0eEdBdHkzc0lQQTBSbm1jSjR1
QkVkZHZqKy9CbW1hUVpFUQ0KMlFMRENuaVZ6NzhwcllMVzNJTXlGNy9md1V1TlhTcXZYM2pYZUZr
V09TM214cDlESUNLZXlrbXAyUmtCDQorSnVhTU9rZWEzNTM3ZXFKbit1VHFJSVVyOHhpVGVKaUQw
MVMvYm9Scjc2ejFGdWdlU1dEN3ZUY0ErU3gNClJ4SjFmUjJKODA5YlFaaG1mYytVZnQrWVZyMngz
MDY0SS9VdnFDMHhabHNpajJlWFZDUXRhN1BSbXJiQQ0KWmI0cFl4d1VDTldGMWNoNWg4ZndscGVy
NUg5VS9VTFdqZHhpZm9GcVNFZzllQzRxczJ5SWkyNmt5SXRmDQp3RHZDelJCeEtOMDV1N3pOcTZT
QktGSFgvakMyaDlwOFlpbStnaTZhVDBCcnlTWFRyZFVYSXA4UDBsTGUNCmJEb2d5ekdiOU9vbk5W
ektyelZkcjVMQWJRRFgwdWtxQUptcll3QVJBUUFCelM5NE5HVmZlRFJsUUhCeQ0KYjNSdmJtMWhh
V3d1WTI5dElEeDROR1ZmZURSbFFIQnliM1J2Ym0xaGFXd3VZMjl0UHNMQmpRUVFBUWdBDQpJQVVD
WUNLaHdBWUxDUWNJQXdJRUZRZ0tBZ1FXQWdFQUFoa0JBaHNEQWg0QkFDRUpFSWtqR2FJbzJ5WHUN
CkZpRUVGVjQ1V0lSZVV0Ly8wdWJIaVNNWm9pamJKZTVtZ2hBQW5ESC81NXF3c25CTTBKeENOT0d3
NExULw0KcG5yc1dvWm9yWi80aUc4VFhnUk1Wa0FpWjFDT2VCR05IbWNDb0ZXRzlVY0xDeUkrT05Q
eTBNandzOHlxDQpnSm01QXUrVE9GVUpMTFJwT3A3VmdRbWNrZmswUkYvRE5Hak9hT0tZQUtKQlFv
dDhJcjY3VjFnSmhGcHMNCnNyQ2hpVmRYa1hiWFRVWkVEcnI3K1dYaWttQlFDcDFPZnNoL2ZhSkZN
K1ZtQXRvUENkMlVZV0hGalI4Sw0KMjg0aTM4bENaOXg2N0R4ZkVTR3gwQTFtTDlJTnNQcW0ydG1x
UFc0R0Ixbk1WYjlBTHRHMTEyVDhaQ2VSDQpDRHZYUlpaWDQ2MXN4bG1CT2xma293cGdia3dzbEFO
eVFIYk1IbXdZS3hoODJmRkdsalM4Umtoek9xSjENCm42NDFQNjJrS1kxOThPREJ6c1pRUmI2d1B5
TmZCWEhtMWtpd1RoYTM1Z1phS25jRkVtNEV4OFNxTXZOZg0KV0xTVUZHRXNIQVFHUjM3cUxPeDZZ
M3V4VlNadlZoZSt3ZVZWd1JnNDlzeGJiNVlSMHl0VTV5bFJqaXphDQpOVE5ES3BkM2lnTXFtMTRn
NmRYSDM1NnFFVm1uSG5ndGk4Qi9FaFZCZ1dwaDJCbjhkc2xjZlRaOUM4bm4NCk5DT2kvOTZRbHNl
M216ZGU1cWNNdlRwRVp0cm9IV1QvNUxYK0Q2VDRXamZLQ2NlcDEzSnRMbHVsWGxpVw0KR3dYVHht
T0Uzb1VaS2dhQWtsbnArcWsvZndtZEtDblNySUVLK1ZjeDZVMEdvaWFHTnFXZGtnbjBiOERxDQpB
NUZaYitBWUZMVVZYVzNOdTdoWEFPdnJnSS9DZTZuZWFiR0UySTBVd3Z6bldWaFdEZjBjdDlxbDJR
Yk8NCndVMEVZQmNSTlFFUUFNdUdTQXdrcmRLVUVKQWlWZW9mV3FzQ0hEa1diT0luMVBiTytCWlk3
alRjdmFkVw0KVEhzU2kyTmJyd0lGRU1TSE1iaXVFelZkM0tBbVpMckduK1d3T0VLeHdNOXd2SG5T
Z2NkbmRIbmcyTHJxDQp0Y200cm9lZTRmYXNqUjVHczM4Q1FlMlhyaHVxVmFJbnl0UFlHTW1ub085
V3hGdGxERjNwQzBkajJZZUINCk5XTGdKclFhT3l3UlFvMXlMazJsRVJYaEFNWWI0eENSampPZHF4
c3IxOFl2MGJEWTRoUmoxRDNhTnpCRA0KK2kwdDZ2Z2QxSlhleG1TUXE5bnEvSEFNVjA4aHpROFh5
ZTN5bzN3NnMzSGFrNFAyUTZidHFCR2tRbjE1DQo3VnByVi9OUkpXdUcwem5VU2VQV09CNWpMdy9x
dXI2ekxvTXVVZWlZNXZBbmJSK1htQ0oxZUdNTFdSa0gNCi9NSTk1QTA0cTBpeU9DUGEveFZhQ2Nj
bUlLYXlhajlqcm5RRURKQjlZSDRxZStxWkI0TzRjcGdseWl0OA0KUFdoZ2R4b3BOc1p4ampTWE1G
aXRuR1Nka3hvQkdXRmxTdlFIQ054MGtJV2QwZkZsVWFqeEVCeHl1b1p5DQpJQzV3RHlOanpyOEhF
cm5vMlVSenhkS0dRMnhGNXlFd2djOGJsbFZ5a0FudGdjM3YvVnRMZFk0cCtRaUwNClYxd3NJZVJQ
YkFmdE4xRmxRQjI5bm9GaldvcllFRE0xRHpjbEVPVldiRjQzTGp4d29pKzFybjJISGlEVQ0KMUEr
MzRUTVpEdnBkSjZxYTVmVzZ2TWVPa2c3WFpySTRLU2VRL1JCaVdyamdyMEFCc1ZZWDZmcXo1ZVNO
DQpuaUhzL3VNQkRuRTh3ZnU5dWEwTHF3Q013MWNETVlSc0owcExBQkVCQUFIQ3dYWUVHQUVJQUFr
RkFtQWkNCm9jQUNHd3dBSVFrUWlTTVpvaWpiSmU0V0lRUVZYamxZaEY1UzMvL1M1c2VKSXhtaUtO
c2w3amRBRC9zRw0KMkNucnlwTmFGNnVydDI1OHo1UFNDNXR5bU5wUzVZOXJqVEZlYXJZWEZZNUJw
ak9zWEM1SzJlcDEwOWZUDQpQczd2STN5Tm4yL0JibllFbmV5ajRmRTZ3UDhSS09BdGhmVGZhdkhT
N2xGY1JFYlB1U2ZYelpSNi9EZU4NCk5aQzdQSmVsVXpuL3QybGdmeE0zVWRIOFRadmRaU0FZanVV
UmdLTE85Q04yK0xOWEM1WWk5UElkS0lHKw0KUzUwRWdoSWRkMndZVWgyeVVVenc5ZEs4ajVZU3hi
Wktyd1ZmdGxBYVJqbzZOOWc5bmU4STcyaGx0LzdWDQpoUll3VFBnV0pvczVFOG1lQW9rdlhTclpw
UnUvZDd0cmlYZUtNVUhhbDhvY1hSR2w2K0xRQ3pTR0ZrMmYNCm1ycE12OE9mMHVCRXdxZmxWQUZx
eUZJazFiNFFoaDNKUmZacDdiMmNXbjlhQ0FNbDBKcXc4dHVEa040dA0KbFZUUmFqUmx1cldIRWto
T3JEN3Q5dnRncVEyRVBBS0s3UUc1QkNoaHlUb2RsNWNWckxsbi9rOWdGNWp6DQp1QjFIaytMVFRk
YTFSU3BJcUpQRXEwZU1lK1dTRWp1ais5VkgxbzNQUEZ3RWI1UDdSS3NxemtpcDVBY1cNCjZ5Tjc2
czZvQmZWOXVhQ2YwM3pjdHZqUXpIMFZhRmVRTFRQWDNlT2FpMklkbldDMTdGMmdKbGVyTDNDNQ0K
T0dscjhDN2xQODUraEoxMVhsOXhBZWZ4QzRIYk11WmtuU2RnUzNyUWNmSVZFbzliak1RalQ5WmY1
WXVsDQpxcVV3NytKSTQwdWFmYVVpLzcxUDRVUTgreENCVUN3akFIK2hBVzdocTFyTjBJMmdNZlZ6
S2R5Z0FPTFcNCjNONkdBUHFGNUdROW8welJNTzExZWc9PQ0KPXZPdWoNCi0tLS0tRU5EIFBHUCBQ
VUJMSUMgS0VZIEJMT0NLLS0tLS0NCg==
-----------------------a0e47617f6032d1dd3dd8bbceef998bf--

-----------------------6a8a633f240f5e0d9cc8b62cf251d1f5
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: ProtonMail

wsFzBAEBCAAGBQJgUhIWACEJEIkjGaIo2yXuFiEEFV45WIReUt//0ubHiSMZ
oijbJe7GzRAAmdRFMy+O/AugnXSEVRh7EJ62mAmG77BztvtsXCishqEaMqUH
pK4PDpORKn+s+g4YtF21r076GKKkQRcPbPJZZdSN6bVXfBgy8oN0mlmfWUwC
2dUtHDkk+A/KHnCKQ3kvaIBf6M2tQQjKSvymEVsg4DphEG7j3cQ8vi3EawJy
nLZL76caQGl9j8IooSJyvqFlwn6tjt/zn11AWPeZ2s9rIp8tqQ1FGVl5aeJn
tQKZWM6bEm4NhNP3MwtuZX/3pBIIXro6SzEi7kagffRNGK4/BIEEUsbzYtID
biqlJo8ItiSGJBcIT7EJaxmIukoKgiUsAD2UDTk8NOPO//XJ2TIJwtY+1D5h
SVH0O5c/jIxMgTZWxGylZKG9bUpodDwvF//FVo/7GVJjZIwp59wiz5xYA7tZ
oXYuVTDuaOVNjxIu99J5/mc1YI9XEhbbkL/QeTVawGh0XNOcHHNb2NaT0weP
LSJ0krA7tOgBI/IANg++mQQwdxL8ZlISoHjTwEn238EocnhhMda6H42+177P
6Zik9JbRdiqp2pybB+u03AmzVoRzQCiZZwxVTYASi8fyt47sti064v6stEtV
b6eGOpsM0pbRSStLpJ9lo8zE55rKgnfKuVRhXAeI5mJ9oiEsFEM/68REcEps
kl/efgFJfYSPRmX4rsag9EPj1WS8W8kpus0=
=tP95
-----END PGP SIGNATURE-----


-----------------------6a8a633f240f5e0d9cc8b62cf251d1f5--