1 /*
 2 Copyright 2012 Canonical
 3 
 4 This program is free software: you can redistribute it and/or modify it
 5 under the terms of the GNU General Public License version 3, as published
 6 by the Free Software Foundation.
 7 */
 8 
 9 #include "qttestability.h"
10 
11 #include <link.h>
12 #include <string>
13 #include <iostream>
14 
15 typedef enum
16 {
17     QT_VERSION_4,
18     QT_VERSION_5,
19     QT_VERSION_UNKNOWN
20 } QtVersion;
21 
22 static int
23 callback(struct dl_phdr_info *info, size_t size, void *data)
24 {
25     (void) size;
26     QtVersion *v = (QtVersion*) data;
27 
28     if (*v == QT_VERSION_UNKNOWN)
29     {
30         std::string lib_path(info->dlpi_name);
31         if (lib_path.rfind("libQtCore.so.4") != std::string::npos)
32         {
33             *v = QT_VERSION_4;
34         }
35         else if (lib_path.rfind("libQtCore.so.5") != std::string::npos || lib_path.rfind("libQt5Core.so.5") != std::string::npos)
36         {
37             *v = QT_VERSION_5;
38         }
39     }
40 
41     return 0;
42 }
43 
44 void qt_testability_init(void)
45 {
46     QtVersion version = QT_VERSION_UNKNOWN;
47     dl_iterate_phdr(callback, &version);
48 
49     std::string driver_name;
Condition "version == QT_VERSION_4", taking true branch
50     if (version == QT_VERSION_4)
51     {
52         driver_name = "libautopilot_driver_qt4.so.1";
Falling through to end of if statement
53     }
54     else if (version == QT_VERSION_5)
55     {
56         driver_name = "libautopilot_driver_qt5.so.1";
57     }
58     else
59     {
60         std::cerr << "We don't seem to link to version 4 or 5 of QtCore." << std::endl
61             << "Unable to determine which autopilot driver to load." << std::endl
62             << "Autopilot introspection will not be available for this process." << std::endl;
63             return;
64     }
65 
CID 13682 - RESOURCE_LEAK
Storage is returned from allocation function "dlopen(char const *, int)".
Assigning: "driver" = storage returned from "dlopen(driver_name.c_str(), 1)".
66     void* driver = dlopen(driver_name.c_str(), RTLD_LAZY);
Condition "!driver", taking false branch
67     if (!driver)
68     {
69         std::cerr << "Cannot load library: " << dlerror() << std::endl
70             << "Autopilot introspection will not be available for this process." << std::endl;
71             return;
End of if statement
72     }
73 
74     // load the entry point function for the actual driver:
75     typedef void (*entry_t)();
76     // clear errors:
77     dlerror();
CID 13682 - RESOURCE_LEAK
Resource "driver" is not freed or pointed-to in function "dlsym(void *, char const *)".
78     entry_t entry_point = (entry_t) dlsym(driver, "qt_testability_init");
79     const char* err = dlerror();
Condition "err", taking true branch
80     if (err)
81     {
82         std::cerr << "Cannot load library entry point symbol: " << err << std::endl
83         << "Autopilot introspection will not be available for this process." << std::endl;
CID 13682 - RESOURCE_LEAK
Variable "driver" going out of scope leaks the storage it points to.
84             return;
85     }
86     entry_point();
87 }