3131
3232namespace shellanything
3333{
34+ static const int EXPANDING_MAX_ITERATIONS = 20 ;
3435
3536 PropertyManager::PropertyManager ()
3637 {
@@ -130,13 +131,18 @@ namespace shellanything
130131
131132 std::string PropertyManager::Expand (const std::string & value) const
132133 {
134+ int count = 1 ;
133135 std::string previous = value;
134136 std::string output = ExpandOnce (value);
135- while (output != previous)
137+
138+ // Prevent circular reference by expanding at most 20 times.
139+ while (output != previous && count <= EXPANDING_MAX_ITERATIONS)
136140 {
137141 previous = output;
138142 output = ExpandOnce (output);
143+ count++;
139144 }
145+
140146 return output;
141147 }
142148
@@ -150,11 +156,21 @@ namespace shellanything
150156 static const std::string token_open = " ${" ;
151157 static const std::string token_close = " }" ;
152158
159+ // Prevent circular reference by dfining a counter which counts how many time a character position was expanded.
160+ int count = 1 ;
161+ size_t previous_pos = std::string::npos;
162+
153163 for (size_t i=0 ; i<output.size (); i++)
154164 {
155- std::string name;
165+ // Count how many time we tried to expand this position
166+ if (i == previous_pos)
167+ count++; // same character as previous loop
168+ else
169+ count = 0 ; // that is a new character
170+ previous_pos = i;
156171
157172 // If we find a property reference token at this location...
173+ std::string name;
158174 if (strncmp (&output[i], token_open.c_str (), token_open.size ()) == 0 && IsPropertyReference (token_open, token_close, output, i, name))
159175 {
160176 // Found a property reference at output[i]
@@ -164,9 +180,19 @@ namespace shellanything
164180 size_t token_length = token_open.size () + name.size () + token_close.size ();
165181 output.replace (output.begin () + i, output.begin () + i + token_length, property_value);
166182
167- // Keep i at the same value for the next loop to process the same character position.
168- // This is required if the property value also contains property references.
169- i--; // -1 since the next for loop will increase i by 1.
183+ // Prevent circular reference by expanding 20 times maximum.
184+ if (count < EXPANDING_MAX_ITERATIONS)
185+ {
186+ // Keep i at the same value for the next loop to process the same character position.
187+ // This is required if the property value also contains property references.
188+ i--; // -1 since the next for loop will increase i by 1.
189+ }
190+ else
191+ {
192+ // Reached the maximum of 20 loops.
193+ // Stop looking for property reference at this position.
194+ int a = 0 ;
195+ }
170196 }
171197 }
172198
0 commit comments