Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify interior of a looping function at runtime

This one's a doozy, but bear with me.

I'm calling in to a library that has a function that waits indefinitely for a certain kind of input. Unfortunately, this function is bugged in such a way that it allows the pipeline it reads from to fill with irrelevant input, causing the program to lock up as it waits for input that it has blinded itself to. The library is entirely critical, exceptionally difficult to replicate, and the maintainer is not accepting pull requests or bug reports.

I need to inject a "flush the pipe" function call into the body of this function. Previously I've solved this problem by taking advantage of similar functions having callback parameters, but this specific function has no such parameter.

What can I do?

like image 629
Schilcote Avatar asked Oct 19 '22 11:10

Schilcote


1 Answers

It seems like you can view the source code so what you can do is to go through the source code and locate a method that is called inside the bugged method and monkey patch it:

class OtherGuysClass:

    def buggedMethod(self, items):
        for item in items:
            a = self.convert(item)
            print(a * 5)

    def convert(self, str):
        return int(str)

if __name__ == "__main__":
    try:
        OtherGuysClass().buggedMethod([1, 2, None, 5])
    except Exception as e:
        print("Bugged method crashed: " + str(e))

    # Replace convert with our own method that returns 0 for None and ""
    o = OtherGuysClass()
    original_convert = o.convert
    def float_convert(str):
        if str:
            return original_convert(str)
        return 0
    o.convert = float_convert
    o.buggedMethod(["1", "2", None, "5"])

5
10
Bugged method crashed: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
5
10
0
25

like image 84
Raniz Avatar answered Nov 02 '22 13:11

Raniz