Divyank1607 commited on
Commit
74d99be
Β·
1 Parent(s): 5ce4119

Add Java rate limiter and C++ event dispatcher tasks; update requirements

Browse files
Files changed (1) hide show
  1. server/environment.py +142 -1
server/environment.py CHANGED
@@ -144,6 +144,147 @@ TASKS: Dict[str, dict] = {
144
  "severity_valid": ["critical"],
145
  },
146
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
 
@@ -303,4 +444,4 @@ class CodeReviewEnvironment:
303
  step_number=step_number,
304
  max_steps=MAX_STEPS,
305
  previous_feedback=previous_feedback,
306
- )
 
144
  "severity_valid": ["critical"],
145
  },
146
  },
147
+
148
+ # ── EXPERT ────────────────────────────────
149
+ "expert": {
150
+ "id": "task_expert_001",
151
+ "difficulty": "expert",
152
+ "language": "java",
153
+ "description": (
154
+ "This Java class implements a token bucket rate limiter. "
155
+ "Identify the logic bug that could allow users to bypass the rate limit."
156
+ ),
157
+ "code": (
158
+ "import java.util.concurrent.atomic.AtomicLong;\n\n"
159
+ "public class TokenBucketRateLimiter {\n"
160
+ " private final long maxTokens;\n"
161
+ " private final long refillRatePerSecond;\n"
162
+ " private AtomicLong currentTokens;\n"
163
+ " private AtomicLong lastRefillTimestamp;\n\n"
164
+ " public TokenBucketRateLimiter(long maxTokens, long refillRatePerSecond) {\n"
165
+ " this.maxTokens = maxTokens;\n"
166
+ " this.refillRatePerSecond = refillRatePerSecond;\n"
167
+ " this.currentTokens = new AtomicLong(maxTokens);\n"
168
+ " this.lastRefillTimestamp = new AtomicLong(System.currentTimeMillis());\n"
169
+ " }\n\n"
170
+ " /**\n"
171
+ " * Checks if the requested number of tokens is available.\n"
172
+ " * Decrements the bucket if allowed.\n"
173
+ " */\n"
174
+ " public synchronized boolean allowRequest(int tokensNeeded) {\n"
175
+ " refill();\n"
176
+ " if (currentTokens.get() >= tokensNeeded) {\n"
177
+ " currentTokens.addAndGet(-tokensNeeded);\n"
178
+ " return true;\n"
179
+ " }\n"
180
+ " return false;\n"
181
+ " }\n\n"
182
+ " private void refill() {\n"
183
+ " long now = System.currentTimeMillis();\n"
184
+ " long timeElapsedMs = now - lastRefillTimestamp.get();\n"
185
+ " \n"
186
+ " // Calculate how many tokens to add based on time elapsed\n"
187
+ " long tokensToAdd = (timeElapsedMs / 1000) * refillRatePerSecond;\n\n"
188
+ " if (tokensToAdd > 0) {\n"
189
+ " // Hint: Look closely at how the tokens are updated here.\n"
190
+ " // Consider what happens if a user stops making requests for a long time.\n"
191
+ " currentTokens.addAndGet(tokensToAdd);\n"
192
+ " lastRefillTimestamp.set(now);\n"
193
+ " }\n"
194
+ " }\n"
195
+ "}"
196
+ ),
197
+ "ground_truth": {
198
+ "bug_identified": True,
199
+ "bug_type_keywords": [
200
+ "logic", "limit", "overflow", "cap", "bound", "maximum", "exceed",
201
+ "logic error", "capacity",
202
+ ],
203
+ "location_keywords": [
204
+ "currentTokens.addAndGet", "refill()", "tokensToAdd",
205
+ "currentTokens.get()", "addAndGet(tokensToAdd)",
206
+ ],
207
+ "description_keywords": [
208
+ "exceed", "maxTokens", "cap", "limit", "bound",
209
+ "overflow", "infinite", "burst", "accumulate",
210
+ ],
211
+ "fix_keywords": [
212
+ "Math.min", "min(", "set(", "if (currentTokens.get() > maxTokens)",
213
+ "compareAndSet", "cap",
214
+ ],
215
+ "severity_valid": ["high", "medium"],
216
+ },
217
+ },
218
+
219
+ # ── EXPERT 2 (C++) ────────────────────────
220
+ "expert2": {
221
+ "id": "task_expert_002",
222
+ "difficulty": "expert2",
223
+ "language": "cpp",
224
+ "description": (
225
+ "This C++ class implements an event dispatcher. "
226
+ "Identify the concurrency bug that can occur when an event is dispatched."
227
+ ),
228
+ "code": (
229
+ "#include <iostream>\n"
230
+ "#include <vector>\n"
231
+ "#include <functional>\n"
232
+ "#include <mutex>\n"
233
+ "#include <algorithm>\n"
234
+ "#include <string>\n\n"
235
+ "class EventDispatcher {\n"
236
+ "public:\n"
237
+ " using Callback = std::function<void(const std::string&)>;\n\n"
238
+ " void subscribe(int listener_id, Callback cb) {\n"
239
+ " std::lock_guard<std::mutex> lock(mut_);\n"
240
+ " listeners_.push_back({listener_id, cb});\n"
241
+ " }\n\n"
242
+ " void unsubscribe(int listener_id) {\n"
243
+ " std::lock_guard<std::mutex> lock(mut_);\n"
244
+ " listeners_.erase(\n"
245
+ " std::remove_if(listeners_.begin(), listeners_.end(),\n"
246
+ " [listener_id](const Listener& l) { return l.id == listener_id; }),\n"
247
+ " listeners_.end()\n"
248
+ " );\n"
249
+ " }\n\n"
250
+ " void dispatch(const std::string& event_data) {\n"
251
+ " std::lock_guard<std::mutex> lock(mut_);\n"
252
+ " for (const auto& listener : listeners_) {\n"
253
+ " // Hint: What happens if a listener decides to call unsubscribe() \n"
254
+ " // from inside their own callback function when an event fires?\n"
255
+ " listener.cb(event_data);\n"
256
+ " }\n"
257
+ " }\n\n"
258
+ "private:\n"
259
+ " struct Listener {\n"
260
+ " int id;\n"
261
+ " Callback cb;\n"
262
+ " };\n \n"
263
+ " std::vector<Listener> listeners_;\n"
264
+ " std::mutex mut_;\n"
265
+ "};"
266
+ ),
267
+ "ground_truth": {
268
+ "bug_identified": True,
269
+ "bug_type_keywords": [
270
+ "deadlock", "concurrency", "lock", "recursive", "reentrant", "hang",
271
+ "iterator validation", "undefined behavior"
272
+ ],
273
+ "location_keywords": [
274
+ "listener.cb", "unsubscribe", "dispatch", "mut_", "std::lock_guard",
275
+ "lock(mut_)"
276
+ ],
277
+ "description_keywords": [
278
+ "deadlock", "already locked", "same thread", "recursive_mutex",
279
+ "reentrant", "hangs", "blocks", "invalidate", "iterator"
280
+ ],
281
+ "fix_keywords": [
282
+ "std::recursive_mutex", "copy", "local copy", "copy the vector",
283
+ "unlock before", "queue", "deferred"
284
+ ],
285
+ "severity_valid": ["high", "critical"],
286
+ },
287
+ },
288
  }
289
 
290
 
 
444
  step_number=step_number,
445
  max_steps=MAX_STEPS,
446
  previous_feedback=previous_feedback,
447
+ )