diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2010-09-17 21:43:24 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2010-09-17 21:43:24 (GMT) |
commit | 87b45bd0d18323898d5c09bb7cad7566e3267635 (patch) | |
tree | f5570d524399e3dab443dde9419af86c3874f416 /src/FbTk | |
parent | f3ad09c4ce70cc58871eeac49d640f213f3cd16f (diff) | |
download | fluxbox_paul-87b45bd0d18323898d5c09bb7cad7566e3267635.zip fluxbox_paul-87b45bd0d18323898d5c09bb7cad7566e3267635.tar.bz2 |
bugfix: avoid naive use of 'putenv' by providing 'FbTk::App::setenv()'
to quote from 'man putenv':
The string pointed to by string becomes part of the environment,
so altering the string changes the environment.
so, using putenv like
{
std::string foo("FOO=bar");
putenv(foo.c_str());
}
is wrong and leads to a potentially corrupted environment. valgrind
complaint correctly.
FbTk::App seems to be the appropriate place to hold '::seten()'
because it alters the environment of the application.
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/App.cc | 55 | ||||
-rw-r--r-- | src/FbTk/App.hh | 5 |
2 files changed, 60 insertions, 0 deletions
diff --git a/src/FbTk/App.cc b/src/FbTk/App.cc index 39cd36e..8157839 100644 --- a/src/FbTk/App.cc +++ b/src/FbTk/App.cc | |||
@@ -26,6 +26,21 @@ | |||
26 | 26 | ||
27 | #include "EventManager.hh" | 27 | #include "EventManager.hh" |
28 | 28 | ||
29 | #ifdef HAVE_CSTRING | ||
30 | #include <cstring> | ||
31 | #else | ||
32 | #include <string.h> | ||
33 | #endif | ||
34 | #ifdef HAVE_CSTDLIB | ||
35 | #include <cstdlib> | ||
36 | #else | ||
37 | #include <stdlib.h> | ||
38 | #endif | ||
39 | |||
40 | |||
41 | #include <set> | ||
42 | |||
43 | |||
29 | namespace FbTk { | 44 | namespace FbTk { |
30 | 45 | ||
31 | App *App::s_app = 0; | 46 | App *App::s_app = 0; |
@@ -79,4 +94,44 @@ void App::end() { | |||
79 | m_done = true; //end loop in App::eventLoop | 94 | m_done = true; //end loop in App::eventLoop |
80 | } | 95 | } |
81 | 96 | ||
97 | bool App::setenv(const char* key, const char* value) { | ||
98 | |||
99 | if (!key || !*key) | ||
100 | return false; | ||
101 | |||
102 | static std::set<char*> stored; | ||
103 | |||
104 | const size_t key_size = strlen(key); | ||
105 | const size_t value_size = value ? strlen(value) : 0; | ||
106 | |||
107 | char* newenv = new char[key_size + value_size + 2]; | ||
108 | if (newenv) { | ||
109 | |||
110 | char* oldenv = getenv(key); | ||
111 | |||
112 | // oldenv points to the value .. we have to go back a bit | ||
113 | if (oldenv && stored.find(oldenv - (key_size + 1)) != stored.end()) | ||
114 | oldenv -= (key_size + 1); | ||
115 | else | ||
116 | oldenv = NULL; | ||
117 | |||
118 | memset(newenv, 0, key_size + value_size + 2); | ||
119 | strcat(newenv, key); | ||
120 | strcat(newenv, "="); | ||
121 | if (value_size > 0) | ||
122 | strcat(newenv, value); | ||
123 | |||
124 | if (putenv(newenv) == 0) { | ||
125 | if (oldenv) { | ||
126 | stored.erase(oldenv); | ||
127 | delete[] oldenv; | ||
128 | } | ||
129 | stored.insert(newenv); | ||
130 | } | ||
131 | return true; | ||
132 | } | ||
133 | |||
134 | return false; | ||
135 | } | ||
136 | |||
82 | } // end namespace FbTk | 137 | } // end namespace FbTk |
diff --git a/src/FbTk/App.hh b/src/FbTk/App.hh index d878661..b83dd15 100644 --- a/src/FbTk/App.hh +++ b/src/FbTk/App.hh | |||
@@ -53,6 +53,11 @@ public: | |||
53 | /// forces an end to event loop | 53 | /// forces an end to event loop |
54 | void end(); | 54 | void end(); |
55 | bool done() const { return m_done; } | 55 | bool done() const { return m_done; } |
56 | |||
57 | // the setenv()-routine is not everywhere available and | ||
58 | // putenv() doesnt manage the strings in the environment | ||
59 | // and hence we have to do that on our own to avoid memleaking | ||
60 | static bool setenv(const char* key, const char* value); | ||
56 | private: | 61 | private: |
57 | static App *s_app; | 62 | static App *s_app; |
58 | bool m_done; | 63 | bool m_done; |