Program: 94136
Project: 94136
Buggy source:
public static void initPaint(XC_LoadPackage.LoadPackageParam lpparam,final XModuleResources modRes,final Context context){
  Class<?> legacyCanvasView=findClass("String_Node_Str",lpparam.classLoader);
  XposedHelpers.findAndHookConstructor("String_Node_Str",lpparam.classLoader,legacyCanvasView,int.class,float.class,new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      Logger.log("String_Node_Str" + param.args[1] + "String_Node_Str"+ param.args[2],true);
      param.args[1]=color;
      param.args[2]=width;
    }
    @Override protected void afterHookedMethod(    MethodHookParam param) throws Throwable {
      paint=(Paint)getObjectField(param.thisObject,"String_Node_Str");
      if (paint == null) {
        Logger.log("String_Node_Str",true);
      }
 else {
        if (shouldErase) {
          paint.setColor(0x00000000);
          paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
          paint.setAlpha(0x00);
        }
 else {
          paint.setXfermode(null);
          paint.setAlpha(alpha);
        }
        if (easterEgg) {
          int[] rainbow=getRainbowColors();
          Shader shader=new LinearGradient(0,0,0,720,rainbow,null,Shader.TileMode.MIRROR);
          Matrix matrix=new Matrix();
          matrix.setRotate(90);
          shader.setLocalMatrix(matrix);
          paint.setShader(shader);
        }
      }
    }
  }
);
  XposedHelpers.findAndHookConstructor("String_Node_Str",lpparam.classLoader,Context.class,AttributeSet.class,new XC_MethodHook(){
    @Override protected void afterHookedMethod(    final MethodHookParam param) throws Throwable {
      View colorpickerview=(View)getObjectField(param.thisObject,"String_Node_Str");
      if (colorpickerview == null) {
        Logger.log("String_Node_Str",true);
      }
 else {
        Logger.log("String_Node_Str",true);
      }
      eraserbutton=new ImageButton(context);
      eraserbutton.setBackgroundColor(0);
      eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
      eraserbutton.setScaleX((float)0.4);
      eraserbutton.setScaleY((float)0.4);
      eraserbutton.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          shouldErase=true;
          eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser_clicked));
        }
      }
);
      RelativeLayout.LayoutParams paramsErase=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsErase.topMargin=HookMethods.px(5.0f);
      paramsErase.rightMargin=HookMethods.px(5.0f);
      paramsErase.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton colorpicker=new ImageButton(context);
      colorpicker.setBackgroundColor(0);
      colorpicker.setImageDrawable(modRes.getDrawable(R.drawable.colorpicker));
      colorpicker.setScaleX((float)0.4);
      colorpicker.setScaleY((float)0.4);
      colorpicker.setOnLongClickListener(new View.OnLongClickListener(){
        @Override public boolean onLongClick(        View v){
          Toast.makeText(context,"String_Node_Str",Toast.LENGTH_SHORT).show();
          easterEgg=true;
          return true;
        }
      }
);
      colorpicker.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
          easterEgg=false;
          shouldErase=false;
          ColorPickerDialog colorPickerDialog=new ColorPickerDialog(context,color,new ColorPickerDialog.OnColorSelectedListener(){
            @Override public void onColorSelected(            int n){
              color=n;
            }
          }
);
          colorPickerDialog.setTitle("String_Node_Str");
          colorPickerDialog.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsPicker=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsPicker.topMargin=HookMethods.px(-40.0f);
      paramsPicker.rightMargin=HookMethods.px(5.0f);
      paramsPicker.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton widthpicker=new ImageButton(context);
      widthpicker.setBackgroundColor(0);
      widthpicker.setImageDrawable(modRes.getDrawable(R.drawable.width));
      widthpicker.setScaleX((float)0.4);
      widthpicker.setScaleY((float)0.4);
      widthpicker.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          AlertDialog.Builder builder=new AlertDialog.Builder(context);
          LinearLayout linearLayout=new LinearLayout(context);
          linearLayout.setOrientation(LinearLayout.VERTICAL);
          LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
          final TextView tv=new TextView(context);
          tv.setText("String_Node_Str" + width);
          final SeekBar seekBar2=new SeekBar(context);
          seekBar2.setMax(30);
          seekBar2.setProgress(width);
          seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            public void onProgressChanged(            SeekBar seekBar2,            int n,            boolean bl){
              if (n == 0) {
                n=n + 1;
              }
              tv.setText("String_Node_Str" + n);
            }
            @Override public void onStartTrackingTouch(            SeekBar arg0){
            }
            @Override public void onStopTrackingTouch(            SeekBar arg0){
            }
          }
);
          builder.setNeutralButton(Common.dialog_default,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              width=2;
            }
          }
);
          builder.setPositiveButton(Common.dialog_done,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              width=seekBar2.getProgress();
              if (width == 0) {
                width=width + 1;
              }
            }
          }
);
          linearLayout.addView(tv,params);
          linearLayout.addView(seekBar2,params);
          builder.setView((View)linearLayout);
          builder.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsWidth=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsWidth.topMargin=HookMethods.px(-40.0f);
      paramsWidth.rightMargin=HookMethods.px(55.0f);
      paramsWidth.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton alphabutton=new ImageButton(context);
      alphabutton.setBackgroundColor(0);
      alphabutton.setImageDrawable(modRes.getDrawable(R.drawable.alpha));
      alphabutton.getDrawable().setDither(true);
      alphabutton.setScaleX((float)0.4);
      alphabutton.setScaleY((float)0.4);
      alphabutton.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          AlertDialog.Builder builder=new AlertDialog.Builder(context);
          LinearLayout linearLayout=new LinearLayout(context);
          linearLayout.setOrientation(LinearLayout.VERTICAL);
          LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
          final TextView tv=new TextView(context);
          tv.setText("String_Node_Str" + alpha);
          final SeekBar seekBar2=new SeekBar(context);
          seekBar2.setMax(255);
          seekBar2.setProgress(alpha);
          seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            public void onProgressChanged(            SeekBar seekBar2,            int n,            boolean bl){
              int m=n + 1;
              tv.setText("String_Node_Str" + m);
            }
            @Override public void onStartTrackingTouch(            SeekBar arg0){
            }
            @Override public void onStopTrackingTouch(            SeekBar arg0){
            }
          }
);
          builder.setNeutralButton(Common.dialog_default,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              alpha=255;
            }
          }
);
          builder.setPositiveButton(Common.dialog_done,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              alpha=seekBar2.getProgress();
            }
          }
);
          linearLayout.addView(tv,params);
          linearLayout.addView(seekBar2,params);
          builder.setView((View)linearLayout);
          builder.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsAlpha=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsAlpha.topMargin=HookMethods.px(5.0f);
      paramsAlpha.rightMargin=HookMethods.px(55.0f);
      paramsAlpha.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(alphabutton,paramsAlpha);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(eraserbutton,paramsErase);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(colorpicker,paramsPicker);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(widthpicker,paramsWidth);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",int.class,new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      Logger.log("String_Node_Str" + param.args[0],true);
      color=(Integer)param.args[0];
      if (shouldErase == true) {
        eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
        shouldErase=false;
      }
    }
  }
);
}

Fixed version (ground truth):
public static void initPaint(XC_LoadPackage.LoadPackageParam lpparam,final XModuleResources modRes){
  XposedHelpers.findAndHookConstructor("String_Node_Str",lpparam.classLoader,Context.class,new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      if (param.args[0] != null) {
        context=(Context)param.args[0];
      }
 else {
        Logger.log("String_Node_Str",true);
      }
    }
  }
);
  Class<?> legacyCanvasView=findClass("String_Node_Str",lpparam.classLoader);
  XposedHelpers.findAndHookConstructor("String_Node_Str",lpparam.classLoader,legacyCanvasView,int.class,float.class,new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      Logger.log("String_Node_Str" + param.args[1] + "String_Node_Str"+ param.args[2],true);
      param.args[1]=color;
      param.args[2]=width;
    }
    @Override protected void afterHookedMethod(    MethodHookParam param) throws Throwable {
      paint=(Paint)getObjectField(param.thisObject,"String_Node_Str");
      if (paint == null) {
        Logger.log("String_Node_Str",true);
      }
 else {
        if (shouldErase) {
          paint.setColor(0x00000000);
          paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
          paint.setAlpha(0x00);
        }
 else {
          paint.setXfermode(null);
          paint.setAlpha(alpha);
        }
        if (easterEgg) {
          int[] rainbow=getRainbowColors();
          Shader shader=new LinearGradient(0,0,0,720,rainbow,null,Shader.TileMode.MIRROR);
          Matrix matrix=new Matrix();
          matrix.setRotate(90);
          shader.setLocalMatrix(matrix);
          paint.setShader(shader);
        }
      }
    }
  }
);
  XposedHelpers.findAndHookConstructor("String_Node_Str",lpparam.classLoader,Context.class,AttributeSet.class,new XC_MethodHook(){
    @Override protected void afterHookedMethod(    final MethodHookParam param) throws Throwable {
      View colorpickerview=(View)getObjectField(param.thisObject,"String_Node_Str");
      if (colorpickerview == null) {
        Logger.log("String_Node_Str",true);
      }
 else {
        Logger.log("String_Node_Str",true);
      }
      eraserbutton=new ImageButton(context);
      eraserbutton.setBackgroundColor(0);
      eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
      eraserbutton.setScaleX((float)0.4);
      eraserbutton.setScaleY((float)0.4);
      eraserbutton.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          shouldErase=true;
          eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser_clicked));
        }
      }
);
      RelativeLayout.LayoutParams paramsErase=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsErase.topMargin=HookMethods.px(5.0f);
      paramsErase.rightMargin=HookMethods.px(5.0f);
      paramsErase.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton colorpicker=new ImageButton(context);
      colorpicker.setBackgroundColor(0);
      colorpicker.setImageDrawable(modRes.getDrawable(R.drawable.colorpicker));
      colorpicker.setScaleX((float)0.4);
      colorpicker.setScaleY((float)0.4);
      colorpicker.setOnLongClickListener(new View.OnLongClickListener(){
        @Override public boolean onLongClick(        View v){
          Toast.makeText(context,"String_Node_Str",Toast.LENGTH_SHORT).show();
          easterEgg=true;
          return true;
        }
      }
);
      colorpicker.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
          easterEgg=false;
          shouldErase=false;
          ColorPickerDialog colorPickerDialog=new ColorPickerDialog(context,color,new ColorPickerDialog.OnColorSelectedListener(){
            @Override public void onColorSelected(            int n){
              color=n;
            }
          }
);
          colorPickerDialog.setTitle("String_Node_Str");
          colorPickerDialog.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsPicker=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsPicker.topMargin=HookMethods.px(-40.0f);
      paramsPicker.rightMargin=HookMethods.px(5.0f);
      paramsPicker.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton widthpicker=new ImageButton(context);
      widthpicker.setBackgroundColor(0);
      widthpicker.setImageDrawable(modRes.getDrawable(R.drawable.width));
      widthpicker.setScaleX((float)0.4);
      widthpicker.setScaleY((float)0.4);
      widthpicker.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          AlertDialog.Builder builder=new AlertDialog.Builder(context);
          LinearLayout linearLayout=new LinearLayout(context);
          linearLayout.setOrientation(LinearLayout.VERTICAL);
          LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
          final TextView tv=new TextView(context);
          tv.setText("String_Node_Str" + width);
          final SeekBar seekBar2=new SeekBar(context);
          seekBar2.setMax(30);
          seekBar2.setProgress(width);
          seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            public void onProgressChanged(            SeekBar seekBar2,            int n,            boolean bl){
              if (n == 0) {
                n=n + 1;
              }
              tv.setText("String_Node_Str" + n);
            }
            @Override public void onStartTrackingTouch(            SeekBar arg0){
            }
            @Override public void onStopTrackingTouch(            SeekBar arg0){
            }
          }
);
          builder.setNeutralButton(Common.dialog_default,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              width=2;
            }
          }
);
          builder.setPositiveButton(Common.dialog_done,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              width=seekBar2.getProgress();
              if (width == 0) {
                width=width + 1;
              }
            }
          }
);
          linearLayout.addView(tv,params);
          linearLayout.addView(seekBar2,params);
          builder.setView((View)linearLayout);
          builder.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsWidth=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsWidth.topMargin=HookMethods.px(-40.0f);
      paramsWidth.rightMargin=HookMethods.px(55.0f);
      paramsWidth.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ImageButton alphabutton=new ImageButton(context);
      alphabutton.setBackgroundColor(0);
      alphabutton.setImageDrawable(modRes.getDrawable(R.drawable.alpha));
      alphabutton.getDrawable().setDither(true);
      alphabutton.setScaleX((float)0.4);
      alphabutton.setScaleY((float)0.4);
      alphabutton.setOnClickListener(new View.OnClickListener(){
        @Override public void onClick(        View v){
          AlertDialog.Builder builder=new AlertDialog.Builder(context);
          LinearLayout linearLayout=new LinearLayout(context);
          linearLayout.setOrientation(LinearLayout.VERTICAL);
          LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
          final TextView tv=new TextView(context);
          tv.setText("String_Node_Str" + alpha);
          final SeekBar seekBar2=new SeekBar(context);
          seekBar2.setMax(255);
          seekBar2.setProgress(alpha);
          seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            public void onProgressChanged(            SeekBar seekBar2,            int n,            boolean bl){
              int m=n + 1;
              tv.setText("String_Node_Str" + m);
            }
            @Override public void onStartTrackingTouch(            SeekBar arg0){
            }
            @Override public void onStopTrackingTouch(            SeekBar arg0){
            }
          }
);
          builder.setNeutralButton(Common.dialog_default,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              alpha=255;
            }
          }
);
          builder.setPositiveButton(Common.dialog_done,new DialogInterface.OnClickListener(){
            @Override public void onClick(            DialogInterface dialog,            int which){
              alpha=seekBar2.getProgress();
            }
          }
);
          linearLayout.addView(tv,params);
          linearLayout.addView(seekBar2,params);
          builder.setView((View)linearLayout);
          builder.show();
        }
      }
);
      RelativeLayout.LayoutParams paramsAlpha=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
      paramsAlpha.topMargin=HookMethods.px(5.0f);
      paramsAlpha.rightMargin=HookMethods.px(55.0f);
      paramsAlpha.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(alphabutton,paramsAlpha);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(eraserbutton,paramsErase);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(colorpicker,paramsPicker);
      ((RelativeLayout)colorpickerview.getParent().getParent()).addView(widthpicker,paramsWidth);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",int.class,new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      Logger.log("String_Node_Str" + param.args[0],true);
      color=(Integer)param.args[0];
      if (shouldErase == true) {
        eraserbutton.setImageDrawable(modRes.getDrawable(R.drawable.eraser));
        shouldErase=false;
      }
    }
  }
);
}