In StringTemplate - which I've used in some projects to emit C code - whitespace prefixes are automatically added in the output lines:
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
When this template is rendered in StringTemplate, the whitespace
prefixing the multilined linesGlobal and linesLocal strings,
is copied for all the lines emitted. The generated C code is
e.g.:
void foo() {
if (someRuntimeFlag) {
int i;
i=1; // <=== whitespace prefix copied in 2nd
i++; // <=== and 3rd line
if (anotherRuntimeFlag) {
int j=i;
j++; // <=== ditto
}
}
}
I am new to Jinja2 - and tried to replicate this, to see if I can use Python/Jinja2 to do the same thing:
#!/usr/bin/env python
from jinja2 import Template
linesGlobal='\n'.join(['int i;', 'i=1;'])
linesLocal='\n'.join(['int j=i;', 'j++;'])
tmpl = Template(u'''\
void foo() {
if (someRuntimeFlag) {
{{linesGlobal}}
if (anotherRuntimeFlag) {
{{linesLocal}}
}
}
}
''')
print tmpl.render(
linesGlobal=linesGlobal,
linesLocal=linesLocal)
...but saw it produce this:
void foo() {
if (someRuntimeFlag) {
int i;
i=1;
if (anotherRuntimeFlag) {
int j=i;
j++;
}
}
}
...which is not what I want.
I managed to make the output emit proper whitespace prefixes with this:
...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...but this is arguably bad, since I need to manually count whitespace
for every string I emit...
Surely Jinja2 offers a better way that I am missing?
There's no answer (yet), because quite simply, Jinja2 doesn't support this functionality.
There is, however, an open ticket for this feature - if you care about it, join the discussion there.
Related
I want to ensure that my code does not exceed 5 levels of indentation, like so:
class Foo { // 0
void bar() { // 1
if () { // 2
if () { // 3
if () { // 4
if () { // 5
if () { // 6 - error
}
}
}
}
}
}
}
Looking through the Checkstyle documentation, I couldn't find a rule that specifically implements this. Does such a rule exist, or do I have to look into custom rules?
There is an issue still in "Open" state about this feature: https://github.com/checkstyle/checkstyle/issues/5487
Not exactly what you need, but you can achieve something similar using the NestedForDepth, NestedIfDepth and NestedTryDepth checks.
I wanted to hook some functions from instagram apk using frida, decompiled the apk with
jadx/JEB, one of the functions I wanted to hook was in this:
public static void A00(HGf arg8, I1Y arg9) {
arg8.A0P();
Boolean v0 = arg9.A0v;
if(v0 != null) {
arg8.A0l("about_your_account_bloks_entrypoint_enabled", v0.booleanValue());
}
//some other code here
}
Tried to hook the function with this frida script:
try {
//
let I1X = Java.use("X.I1X")
console.log("this is instance: ", I1X)
console.log(
"these are the methods:: ",
Java.use("X.I1X").class.getDeclaredMethods()
)
I1X.A00.overload().implemention = function (HGf, I1Y) {
console.log("A0l is called")
let ret = this.A0l(str, z)
console.log("A0l ret value is " + ret)
}
} catch (e) {
console.log("failed!" + e)
}
})
this script outputs:
this is instance: <class: X.I1X>
these are the methods::
failed!TypeError: not a function
apparently the A00 here is not a function, so back to jadx in the compiled code there is another class with the same name within same package but consisting of some other code, here it is:
/* renamed from: X.I1x reason: case insensitive filesystem */
/* loaded from: classes7.dex */
public final class C39227I1x {
public C39229I1z A00 = null;
}
apparently Frida is hooking this variable instance A00 In my opinion that is why
it is returning not a function here.
So my question, how can I hook like this situation?
Edit:
the two classes are somewhat different in jadx.
Consider a simple for of:
for (const elem of document.getElementsByTagName('*') {
// do something with elem
}
does getElementsByTagName evaluated only once or on each iteration ?
thx!
In this case, it's evaluated once to obtain an iterable, which it then uses to obtain an iterator. It reuses that iterator to grab all the values and pass them to your for block. It's very similar to doing the following with a generator function:
function* getIntegers(max) {
for (let i = 0; i <= max; i++) {
yield i;
}
}
const iterator = getIntegers(15);
while (true) {
const { done, value } = iterator.next();
if (done) {
break;
}
console.log(value);
}
As noted by loganfsmyth, generator functions return an iterator directly. Note: generator functions can also be used with the for..of construct.
See this article on MDN for more info.
I have an example.scss file. When it is imported (parsed), I would like to push a value to a map.
// Declare selectors
register(example);
Prior to its import, the following has already been imported:
$example-map: (
);
#function register($key){
$pointless: map-set($example-map, $key, true); // Have to assign to a variable
#return true; // Have to return something
}
This is invalid as it appears that functions cannot be called outside of selectors. Why is this?
Codepen here
You can use a mixin instead. Sure it's a little more to type but it should work.
Here's my quick test:
$register: ();
#mixin register ($key) {
#if not index($register, $key) {
$register: append($register, $key);
}
}
#include register(foo);
#include register(bar);
#include register(bar);
#include register(baz);
body {
content: $register;
}
Then you can test if it's registed just using index.
#if index($register, foo) {
.foo {
color: red;
}
}
Here's a small demo:
Sassmeister: http://sassmeister.com/gist/6069ebaba50d29052eeb
For instance, I have a library and I would like to protect the source code to being viewed. The first method that comes to mind is to create public wrappers for private functions like the following
function executeMyCoolFunction(param1, param2, param3) {
return executeMyCoolFunction_(param1, param2, param3);
}
Only public part of the code will be visible in this way. It is fine, but all Google Service functions look like function abs() {/* */}. I am curious, is there an approach to hide library source code like Google does?
Edit 00: Do not "hide" a library code by using another library, i.e. the LibA with known project key uses the LibB with unknown project key. The public functions code of LibB is possible to get and even execute them. The code is
function exploreLib_(lib, libName) {
if (libName == null) {
for (var name in this) {
if (this[name] == lib) {
libName = name;
}
}
}
var res = [];
for (var entity in lib) {
var obj = lib[entity];
var code;
if (obj["toSource"] != null) {
code = obj.toSource();
}
else if (obj["toString"] != null) {
code = obj.toString();
}
else {
var nextLibCode = exploreLib_(obj, libName + "." + entity);
res = res.concat(nextLibCode);
}
if (code != null) {
res.push({ libraryName: libName, functionCode: code });
}
}
return res;
}
function explorerLibPublicFunctionsCode() {
var lstPublicFunctions = exploreLib_(LibA);
var password = LibA.LibB.getPassword();
}
I don't know what google does, but you could do something like this (not tested! just an idea):
function declarations:
var myApp = {
foo: function { /**/ },
bar: function { /**/ }
};
and then, in another place, an anonymous function writes foo() and bar():
(function(a) {
a['\u0066\u006F\u006F'] = function(){
// here code for foo
};
a['\u0062\u0061\u0072'] = function(){
// here code for bar
};
})(myApp);
You can pack or minify to obfuscate even more.
Edit: changed my answer to reflect the fact that an exception's stacktrace will contain the library project key.
In this example, MyLibraryB is a library included by MyLibraryA. Both are shared publicly to view (access controls) but only MyLibraryA's project key is made known. It appears it would be very difficult for an attacker to see the code in MyLibraryB:
//this function is in your MyLibraryA, and you share its project key
function executeMyCoolFunction(param1, param2, param3) {
for (var i = 0; i < 1000000; i++) {
debugger; //forces a breakpoint that the IDE cannot? step over
}
//... your code goes here
//don't share MyLibraryB project key
MyLibraryB.doSomething(args...);
}
but as per the #megabyte1024's comments, if you were to cause an exception in MyLibraryB.doSomething(), the stacktrace would contain the project key to MyLibraryB.