File size: 6,552 Bytes
d25ab77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
[
  {
    "snippet_id": "medium_001",
    "filename": "cart.py",
    "code": "def collect_names(items):\n    names = []\n    for i in range(len(items) - 1):\n        names.append(items[i].name)\n    return names",
    "gold_issues": [
      {
        "issue_id": "medium_001_off_by_one",
        "line": 3,
        "issue_type": "LOGIC",
        "severity": "MEDIUM",
        "description": "Loop skips the last item because of an off-by-one range.",
        "required": true,
        "explanation_keywords": ["off-by-one", "last item", "range", "skip", "len"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_002",
    "filename": "lists.py",
    "code": "def add_item(item, bucket=[]):\n    bucket.append(item)\n    return bucket",
    "gold_issues": [
      {
        "issue_id": "medium_002_mutable_default",
        "line": 1,
        "issue_type": "LOGIC",
        "severity": "HIGH",
        "description": "Mutable default argument is shared between calls.",
        "required": true,
        "explanation_keywords": ["mutable", "default", "shared", "calls", "list"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_003",
    "filename": "loader.py",
    "code": "def load_payload(reader):\n    try:\n        return reader.read()\n    except Exception:\n        pass\n    return None",
    "gold_issues": [
      {
        "issue_id": "medium_003_swallow",
        "line": 4,
        "issue_type": "LOGIC",
        "severity": "HIGH",
        "description": "Broad exception is swallowed, hiding errors from callers.",
        "required": true,
        "explanation_keywords": ["exception", "swallow", "pass", "hide", "error"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_004",
    "filename": "billing.py",
    "code": "def total_price(prices):\n    total = 0\n    for price in prices:\n        total = total + str(price)\n    return total",
    "gold_issues": [
      {
        "issue_id": "medium_004_type_bug",
        "line": 4,
        "issue_type": "LOGIC",
        "severity": "MEDIUM",
        "description": "Converts price to string and concatenates instead of adding numerically.",
        "required": true,
        "explanation_keywords": ["string", "concatenate", "numeric", "add", "type"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_005",
    "filename": "flags.py",
    "code": "def should_run(user_input):\n    if user_input == True:\n        return True\n    return False",
    "gold_issues": [
      {
        "issue_id": "medium_005_bool_compare",
        "line": 2,
        "issue_type": "LOGIC",
        "severity": "LOW",
        "description": "Explicit comparison to True is brittle and can mis-handle truthy values.",
        "required": true,
        "explanation_keywords": ["true", "truthy", "boolean", "comparison", "if"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_006",
    "filename": "ranges.py",
    "code": "def between(value, start, end):\n    if value >= start or value <= end:\n        return True\n    return False",
    "gold_issues": [
      {
        "issue_id": "medium_006_boolean_logic",
        "line": 2,
        "issue_type": "LOGIC",
        "severity": "HIGH",
        "description": "Uses `or` instead of `and`, so the range check almost always passes.",
        "required": true,
        "explanation_keywords": ["or", "and", "range", "always", "boolean"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_007",
    "filename": "cleanup.py",
    "code": "def remove_empty(values):\n    for value in values:\n        if not value:\n            values.remove(value)\n    return values",
    "gold_issues": [
      {
        "issue_id": "medium_007_mutation_during_iteration",
        "line": 4,
        "issue_type": "LOGIC",
        "severity": "HIGH",
        "description": "Mutates the list while iterating, causing elements to be skipped.",
        "required": true,
        "explanation_keywords": ["mutate", "iteration", "remove", "skip", "list"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_008",
    "filename": "averages.py",
    "code": "def average(numbers):\n    if not numbers:\n        return 0\n    return sum(numbers) / (len(numbers) - 1)",
    "gold_issues": [
      {
        "issue_id": "medium_008_divisor",
        "line": 4,
        "issue_type": "LOGIC",
        "severity": "HIGH",
        "description": "Divides by len(numbers) - 1, producing the wrong average and crashing for one item.",
        "required": true,
        "explanation_keywords": ["average", "divide", "len", "minus 1", "wrong"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_009",
    "filename": "retry.py",
    "code": "def fetch_name(client):\n    try:\n        return client.name()\n    except ValueError:\n        return \"\"\n    return None",
    "gold_issues": [
      {
        "issue_id": "medium_009_unreachable_fallback",
        "line": 6,
        "issue_type": "LOGIC",
        "severity": "LOW",
        "description": "The final return is unreachable and suggests the error path was designed incorrectly.",
        "required": false,
        "explanation_keywords": ["unreachable", "return", "fallback", "dead code"]
      },
      {
        "issue_id": "medium_009_swallow",
        "line": 5,
        "issue_type": "LOGIC",
        "severity": "MEDIUM",
        "description": "Returns an empty string on ValueError, masking the failure as a valid result.",
        "required": true,
        "explanation_keywords": ["empty string", "mask", "failure", "valid result", "error"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  },
  {
    "snippet_id": "medium_010",
    "filename": "tokens.py",
    "code": "def normalize_token(token):\n    if token is \"\":\n        return None\n    return token.strip()",
    "gold_issues": [
      {
        "issue_id": "medium_010_is_compare",
        "line": 2,
        "issue_type": "LOGIC",
        "severity": "MEDIUM",
        "description": "Uses `is` for string comparison instead of equality.",
        "required": true,
        "explanation_keywords": ["is", "string", "comparison", "equality", "identity"]
      }
    ],
    "must_approve": false,
    "must_reject": true
  }
]