Check for number of field overflow.

This commit is contained in:
Bob Nystrom
2014-01-15 07:59:10 -08:00
parent eb1c0284dd
commit e493ac7cf4
7 changed files with 1126 additions and 6 deletions

View File

@ -63,6 +63,13 @@
// extra spaces added to handle arity, and another byte to terminate the string.
#define MAX_METHOD_SIGNATURE (MAX_METHOD_NAME + MAX_PARAMETERS + 1)
// The maximum number of fields a class can have, including inherited fields.
// This is explicit in the bytecode since `CODE_CLASS` and `CODE_SUBCLASS` take
// a single byte for the number of fields. Note that it's 255 and not 256
// because creating a class takes the *number* of fields, not the *highest
// field index*.
#define MAX_FIELDS (255)
// Assertions are used to validate program invariants. They indicate things the
// program expects to be true about its internal state during execution. If an
// assertion fails, there is a bug in Wren.

View File

@ -1504,6 +1504,11 @@ static void field(Compiler* compiler, bool allowAssignment)
field = wrenSymbolTableEnsure(compiler->parser->vm, compiler->fields,
compiler->parser->previous.start,
compiler->parser->previous.length);
if (field >= MAX_FIELDS)
{
error(compiler, "A class can only have %d fields.", MAX_FIELDS);
}
}
else
{
@ -1513,8 +1518,6 @@ static void field(Compiler* compiler, bool allowAssignment)
field = 255;
}
// TODO: Make sure field number fits in byte.
// If there's an "=" after a field name, it's an assignment.
if (match(compiler, TOKEN_EQ))
{
@ -2350,7 +2353,6 @@ void statement(Compiler* compiler)
static void classDefinition(Compiler* compiler)
{
// Create a variable to store the class in.
// TODO: Allow anonymous classes?
int symbol = declareVariable(compiler);
// Load the superclass (if there is one).
@ -2522,10 +2524,10 @@ void wrenBindMethodCode(ObjClass* classObj, ObjFn* fn)
case CODE_STORE_FIELD:
case CODE_LOAD_FIELD_THIS:
case CODE_STORE_FIELD_THIS:
// Shift this class's fields down past the inherited ones.
// Shift this class's fields down past the inherited ones. We don't
// check for overflow here because we'll see if the number of fields
// overflows when the subclass is created.
fn->bytecode[ip++] += classObj->superclass->numFields;
// TODO: Make sure field number still fits in byte.
break;
case CODE_CLOSURE:

View File

@ -530,6 +530,22 @@ static void methodNotFound(WrenVM* vm, ObjFiber* fiber, Value* receiver,
wrenDebugPrintStackTrace(vm, fiber, *receiver);
}
static void tooManyInheritedFields(WrenVM* vm, ObjFiber* fiber, Value* slot)
{
// TODO: Tune size.
char message[200];
// TODO: Include class name in message. Mention inheritance.
snprintf(message, 200,
"A class may not have more than %d fields, including inherited ones.",
MAX_FIELDS);
// Store the error message in the receiver slot so that it's on the fiber's
// stack and doesn't get garbage collected.
*slot = wrenNewString(vm, message, strlen(message));
wrenDebugPrintStackTrace(vm, fiber, *slot);
}
// Pushes [function] onto [fiber]'s callstack and invokes it. Expects [numArgs]
// arguments (including the receiver) to be on the top of the stack already.
// [function] can be an `ObjFn` or `ObjClosure`.
@ -1181,6 +1197,16 @@ static bool runInterpreter(WrenVM* vm)
ObjClass* classObj = wrenNewClass(vm, superclass, numFields);
// Now that we know the total number of fields, make sure we don't
// overflow.
// TODO: Same check for static fields.
if (superclass->numFields + numFields > MAX_FIELDS)
{
STORE_FRAME();
tooManyInheritedFields(vm, fiber, &fiber->stack[fiber->stackSize - 1]);
return false;
}
// Don't pop the superclass off the stack until the subclass is done
// being created, to make sure it doesn't get collected.
if (isSubclass) POP();

262
test/limit/many_fields.wren Normal file
View File

@ -0,0 +1,262 @@
class Foo {
new {
_field1 = 1
_field2 = 2
_field3 = 3
_field4 = 4
_field5 = 5
_field6 = 6
_field7 = 7
_field8 = 8
_field9 = 9
_field10 = 10
_field11 = 11
_field12 = 12
_field13 = 13
_field14 = 14
_field15 = 15
_field16 = 16
_field17 = 17
_field18 = 18
_field19 = 19
_field20 = 20
_field21 = 21
_field22 = 22
_field23 = 23
_field24 = 24
_field25 = 25
_field26 = 26
_field27 = 27
_field28 = 28
_field29 = 29
_field30 = 30
_field31 = 31
_field32 = 32
_field33 = 33
_field34 = 34
_field35 = 35
_field36 = 36
_field37 = 37
_field38 = 38
_field39 = 39
_field40 = 40
_field41 = 41
_field42 = 42
_field43 = 43
_field44 = 44
_field45 = 45
_field46 = 46
_field47 = 47
_field48 = 48
_field49 = 49
_field50 = 50
_field51 = 51
_field52 = 52
_field53 = 53
_field54 = 54
_field55 = 55
_field56 = 56
_field57 = 57
_field58 = 58
_field59 = 59
_field60 = 60
_field61 = 61
_field62 = 62
_field63 = 63
_field64 = 64
_field65 = 65
_field66 = 66
_field67 = 67
_field68 = 68
_field69 = 69
_field70 = 70
_field71 = 71
_field72 = 72
_field73 = 73
_field74 = 74
_field75 = 75
_field76 = 76
_field77 = 77
_field78 = 78
_field79 = 79
_field80 = 80
_field81 = 81
_field82 = 82
_field83 = 83
_field84 = 84
_field85 = 85
_field86 = 86
_field87 = 87
_field88 = 88
_field89 = 89
_field90 = 90
_field91 = 91
_field92 = 92
_field93 = 93
_field94 = 94
_field95 = 95
_field96 = 96
_field97 = 97
_field98 = 98
_field99 = 99
_field100 = 100
_field101 = 101
_field102 = 102
_field103 = 103
_field104 = 104
_field105 = 105
_field106 = 106
_field107 = 107
_field108 = 108
_field109 = 109
_field110 = 110
_field111 = 111
_field112 = 112
_field113 = 113
_field114 = 114
_field115 = 115
_field116 = 116
_field117 = 117
_field118 = 118
_field119 = 119
_field120 = 120
_field121 = 121
_field122 = 122
_field123 = 123
_field124 = 124
_field125 = 125
_field126 = 126
_field127 = 127
_field128 = 128
_field129 = 129
_field130 = 130
_field131 = 131
_field132 = 132
_field133 = 133
_field134 = 134
_field135 = 135
_field136 = 136
_field137 = 137
_field138 = 138
_field139 = 139
_field140 = 140
_field141 = 141
_field142 = 142
_field143 = 143
_field144 = 144
_field145 = 145
_field146 = 146
_field147 = 147
_field148 = 148
_field149 = 149
_field150 = 150
_field151 = 151
_field152 = 152
_field153 = 153
_field154 = 154
_field155 = 155
_field156 = 156
_field157 = 157
_field158 = 158
_field159 = 159
_field160 = 160
_field161 = 161
_field162 = 162
_field163 = 163
_field164 = 164
_field165 = 165
_field166 = 166
_field167 = 167
_field168 = 168
_field169 = 169
_field170 = 170
_field171 = 171
_field172 = 172
_field173 = 173
_field174 = 174
_field175 = 175
_field176 = 176
_field177 = 177
_field178 = 178
_field179 = 179
_field180 = 180
_field181 = 181
_field182 = 182
_field183 = 183
_field184 = 184
_field185 = 185
_field186 = 186
_field187 = 187
_field188 = 188
_field189 = 189
_field190 = 190
_field191 = 191
_field192 = 192
_field193 = 193
_field194 = 194
_field195 = 195
_field196 = 196
_field197 = 197
_field198 = 198
_field199 = 199
_field200 = 200
_field201 = 201
_field202 = 202
_field203 = 203
_field204 = 204
_field205 = 205
_field206 = 206
_field207 = 207
_field208 = 208
_field209 = 209
_field210 = 210
_field211 = 211
_field212 = 212
_field213 = 213
_field214 = 214
_field215 = 215
_field216 = 216
_field217 = 217
_field218 = 218
_field219 = 219
_field220 = 220
_field221 = 221
_field222 = 222
_field223 = 223
_field224 = 224
_field225 = 225
_field226 = 226
_field227 = 227
_field228 = 228
_field229 = 229
_field230 = 230
_field231 = 231
_field232 = 232
_field233 = 233
_field234 = 234
_field235 = 235
_field236 = 236
_field237 = 237
_field238 = 238
_field239 = 239
_field240 = 240
_field241 = 241
_field242 = 242
_field243 = 243
_field244 = 244
_field245 = 245
_field246 = 246
_field247 = 247
_field248 = 248
_field249 = 249
_field250 = 250
_field251 = 251
_field252 = 252
_field253 = 253
_field254 = 254
_field255 = 255
IO.print(_field255)
}
}
var foo = new Foo // expect: 255

View File

@ -0,0 +1,280 @@
class Foo {
new {
_field1 = 1
_field2 = 2
_field3 = 3
_field4 = 4
_field5 = 5
_field6 = 6
_field7 = 7
_field8 = 8
_field9 = 9
_field10 = 10
_field11 = 11
_field12 = 12
_field13 = 13
_field14 = 14
_field15 = 15
_field16 = 16
_field17 = 17
_field18 = 18
_field19 = 19
_field20 = 20
_field21 = 21
_field22 = 22
_field23 = 23
_field24 = 24
_field25 = 25
_field26 = 26
_field27 = 27
_field28 = 28
_field29 = 29
_field30 = 30
_field31 = 31
_field32 = 32
_field33 = 33
_field34 = 34
_field35 = 35
_field36 = 36
_field37 = 37
_field38 = 38
_field39 = 39
_field40 = 40
_field41 = 41
_field42 = 42
_field43 = 43
_field44 = 44
_field45 = 45
_field46 = 46
_field47 = 47
_field48 = 48
_field49 = 49
_field50 = 50
_field51 = 51
_field52 = 52
_field53 = 53
_field54 = 54
_field55 = 55
_field56 = 56
_field57 = 57
_field58 = 58
_field59 = 59
_field60 = 60
_field61 = 61
_field62 = 62
_field63 = 63
_field64 = 64
_field65 = 65
_field66 = 66
_field67 = 67
_field68 = 68
_field69 = 69
_field70 = 70
_field71 = 71
_field72 = 72
_field73 = 73
_field74 = 74
_field75 = 75
_field76 = 76
_field77 = 77
_field78 = 78
_field79 = 79
_field80 = 80
_field81 = 81
_field82 = 82
_field83 = 83
_field84 = 84
_field85 = 85
_field86 = 86
_field87 = 87
_field88 = 88
_field89 = 89
_field90 = 90
_field91 = 91
_field92 = 92
_field93 = 93
_field94 = 94
_field95 = 95
_field96 = 96
_field97 = 97
_field98 = 98
_field99 = 99
_field100 = 100
_field101 = 101
_field102 = 102
_field103 = 103
_field104 = 104
_field105 = 105
_field106 = 106
_field107 = 107
_field108 = 108
_field109 = 109
_field110 = 110
_field111 = 111
_field112 = 112
_field113 = 113
_field114 = 114
_field115 = 115
_field116 = 116
_field117 = 117
_field118 = 118
_field119 = 119
_field120 = 120
_field121 = 121
_field122 = 122
_field123 = 123
_field124 = 124
_field125 = 125
_field126 = 126
_field127 = 127
_field128 = 128
}
foo {
IO.print(_field1)
IO.print(_field128)
}
}
class Bar is Foo { // expect runtime error: A class may not have more than 255 fields, including inherited ones.
new {
super
_field129 = 129
_field130 = 130
_field131 = 131
_field132 = 132
_field133 = 133
_field134 = 134
_field135 = 135
_field136 = 136
_field137 = 137
_field138 = 138
_field139 = 139
_field140 = 140
_field141 = 141
_field142 = 142
_field143 = 143
_field144 = 144
_field145 = 145
_field146 = 146
_field147 = 147
_field148 = 148
_field149 = 149
_field150 = 150
_field151 = 151
_field152 = 152
_field153 = 153
_field154 = 154
_field155 = 155
_field156 = 156
_field157 = 157
_field158 = 158
_field159 = 159
_field160 = 160
_field161 = 161
_field162 = 162
_field163 = 163
_field164 = 164
_field165 = 165
_field166 = 166
_field167 = 167
_field168 = 168
_field169 = 169
_field170 = 170
_field171 = 171
_field172 = 172
_field173 = 173
_field174 = 174
_field175 = 175
_field176 = 176
_field177 = 177
_field178 = 178
_field179 = 179
_field180 = 180
_field181 = 181
_field182 = 182
_field183 = 183
_field184 = 184
_field185 = 185
_field186 = 186
_field187 = 187
_field188 = 188
_field189 = 189
_field190 = 190
_field191 = 191
_field192 = 192
_field193 = 193
_field194 = 194
_field195 = 195
_field196 = 196
_field197 = 197
_field198 = 198
_field199 = 199
_field200 = 200
_field201 = 201
_field202 = 202
_field203 = 203
_field204 = 204
_field205 = 205
_field206 = 206
_field207 = 207
_field208 = 208
_field209 = 209
_field210 = 210
_field211 = 211
_field212 = 212
_field213 = 213
_field214 = 214
_field215 = 215
_field216 = 216
_field217 = 217
_field218 = 218
_field219 = 219
_field220 = 220
_field221 = 221
_field222 = 222
_field223 = 223
_field224 = 224
_field225 = 225
_field226 = 226
_field227 = 227
_field228 = 228
_field229 = 229
_field230 = 230
_field231 = 231
_field232 = 232
_field233 = 233
_field234 = 234
_field235 = 235
_field236 = 236
_field237 = 237
_field238 = 238
_field239 = 239
_field240 = 240
_field241 = 241
_field242 = 242
_field243 = 243
_field244 = 244
_field245 = 245
_field246 = 246
_field247 = 247
_field248 = 248
_field249 = 249
_field250 = 250
_field251 = 251
_field252 = 252
_field253 = 253
_field254 = 254
_field255 = 255
_field256 = 256
}
bar {
IO.print(_field129)
IO.print(_field256)
}
}
var bar = new Bar
bar.foo
bar.bar

View File

@ -0,0 +1,262 @@
class Foo {
new {
_field1 = 1
_field2 = 2
_field3 = 3
_field4 = 4
_field5 = 5
_field6 = 6
_field7 = 7
_field8 = 8
_field9 = 9
_field10 = 10
_field11 = 11
_field12 = 12
_field13 = 13
_field14 = 14
_field15 = 15
_field16 = 16
_field17 = 17
_field18 = 18
_field19 = 19
_field20 = 20
_field21 = 21
_field22 = 22
_field23 = 23
_field24 = 24
_field25 = 25
_field26 = 26
_field27 = 27
_field28 = 28
_field29 = 29
_field30 = 30
_field31 = 31
_field32 = 32
_field33 = 33
_field34 = 34
_field35 = 35
_field36 = 36
_field37 = 37
_field38 = 38
_field39 = 39
_field40 = 40
_field41 = 41
_field42 = 42
_field43 = 43
_field44 = 44
_field45 = 45
_field46 = 46
_field47 = 47
_field48 = 48
_field49 = 49
_field50 = 50
_field51 = 51
_field52 = 52
_field53 = 53
_field54 = 54
_field55 = 55
_field56 = 56
_field57 = 57
_field58 = 58
_field59 = 59
_field60 = 60
_field61 = 61
_field62 = 62
_field63 = 63
_field64 = 64
_field65 = 65
_field66 = 66
_field67 = 67
_field68 = 68
_field69 = 69
_field70 = 70
_field71 = 71
_field72 = 72
_field73 = 73
_field74 = 74
_field75 = 75
_field76 = 76
_field77 = 77
_field78 = 78
_field79 = 79
_field80 = 80
_field81 = 81
_field82 = 82
_field83 = 83
_field84 = 84
_field85 = 85
_field86 = 86
_field87 = 87
_field88 = 88
_field89 = 89
_field90 = 90
_field91 = 91
_field92 = 92
_field93 = 93
_field94 = 94
_field95 = 95
_field96 = 96
_field97 = 97
_field98 = 98
_field99 = 99
_field100 = 100
_field101 = 101
_field102 = 102
_field103 = 103
_field104 = 104
_field105 = 105
_field106 = 106
_field107 = 107
_field108 = 108
_field109 = 109
_field110 = 110
_field111 = 111
_field112 = 112
_field113 = 113
_field114 = 114
_field115 = 115
_field116 = 116
_field117 = 117
_field118 = 118
_field119 = 119
_field120 = 120
_field121 = 121
_field122 = 122
_field123 = 123
_field124 = 124
_field125 = 125
_field126 = 126
_field127 = 127
_field128 = 128
_field129 = 129
_field130 = 130
_field131 = 131
_field132 = 132
_field133 = 133
_field134 = 134
_field135 = 135
_field136 = 136
_field137 = 137
_field138 = 138
_field139 = 139
_field140 = 140
_field141 = 141
_field142 = 142
_field143 = 143
_field144 = 144
_field145 = 145
_field146 = 146
_field147 = 147
_field148 = 148
_field149 = 149
_field150 = 150
_field151 = 151
_field152 = 152
_field153 = 153
_field154 = 154
_field155 = 155
_field156 = 156
_field157 = 157
_field158 = 158
_field159 = 159
_field160 = 160
_field161 = 161
_field162 = 162
_field163 = 163
_field164 = 164
_field165 = 165
_field166 = 166
_field167 = 167
_field168 = 168
_field169 = 169
_field170 = 170
_field171 = 171
_field172 = 172
_field173 = 173
_field174 = 174
_field175 = 175
_field176 = 176
_field177 = 177
_field178 = 178
_field179 = 179
_field180 = 180
_field181 = 181
_field182 = 182
_field183 = 183
_field184 = 184
_field185 = 185
_field186 = 186
_field187 = 187
_field188 = 188
_field189 = 189
_field190 = 190
_field191 = 191
_field192 = 192
_field193 = 193
_field194 = 194
_field195 = 195
_field196 = 196
_field197 = 197
_field198 = 198
_field199 = 199
_field200 = 200
_field201 = 201
_field202 = 202
_field203 = 203
_field204 = 204
_field205 = 205
_field206 = 206
_field207 = 207
_field208 = 208
_field209 = 209
_field210 = 210
_field211 = 211
_field212 = 212
_field213 = 213
_field214 = 214
_field215 = 215
_field216 = 216
_field217 = 217
_field218 = 218
_field219 = 219
_field220 = 220
_field221 = 221
_field222 = 222
_field223 = 223
_field224 = 224
_field225 = 225
_field226 = 226
_field227 = 227
_field228 = 228
_field229 = 229
_field230 = 230
_field231 = 231
_field232 = 232
_field233 = 233
_field234 = 234
_field235 = 235
_field236 = 236
_field237 = 237
_field238 = 238
_field239 = 239
_field240 = 240
_field241 = 241
_field242 = 242
_field243 = 243
_field244 = 244
_field245 = 245
_field246 = 246
_field247 = 247
_field248 = 248
_field249 = 249
_field250 = 250
_field251 = 251
_field252 = 252
_field253 = 253
_field254 = 254
_field255 = 255
_field256 = 256 // expect error
}
}
var foo = new Foo

View File

@ -0,0 +1,281 @@
class Foo {
new {
_field1 = 1
_field2 = 2
_field3 = 3
_field4 = 4
_field5 = 5
_field6 = 6
_field7 = 7
_field8 = 8
_field9 = 9
_field10 = 10
_field11 = 11
_field12 = 12
_field13 = 13
_field14 = 14
_field15 = 15
_field16 = 16
_field17 = 17
_field18 = 18
_field19 = 19
_field20 = 20
_field21 = 21
_field22 = 22
_field23 = 23
_field24 = 24
_field25 = 25
_field26 = 26
_field27 = 27
_field28 = 28
_field29 = 29
_field30 = 30
_field31 = 31
_field32 = 32
_field33 = 33
_field34 = 34
_field35 = 35
_field36 = 36
_field37 = 37
_field38 = 38
_field39 = 39
_field40 = 40
_field41 = 41
_field42 = 42
_field43 = 43
_field44 = 44
_field45 = 45
_field46 = 46
_field47 = 47
_field48 = 48
_field49 = 49
_field50 = 50
_field51 = 51
_field52 = 52
_field53 = 53
_field54 = 54
_field55 = 55
_field56 = 56
_field57 = 57
_field58 = 58
_field59 = 59
_field60 = 60
_field61 = 61
_field62 = 62
_field63 = 63
_field64 = 64
_field65 = 65
_field66 = 66
_field67 = 67
_field68 = 68
_field69 = 69
_field70 = 70
_field71 = 71
_field72 = 72
_field73 = 73
_field74 = 74
_field75 = 75
_field76 = 76
_field77 = 77
_field78 = 78
_field79 = 79
_field80 = 80
_field81 = 81
_field82 = 82
_field83 = 83
_field84 = 84
_field85 = 85
_field86 = 86
_field87 = 87
_field88 = 88
_field89 = 89
_field90 = 90
_field91 = 91
_field92 = 92
_field93 = 93
_field94 = 94
_field95 = 95
_field96 = 96
_field97 = 97
_field98 = 98
_field99 = 99
_field100 = 100
_field101 = 101
_field102 = 102
_field103 = 103
_field104 = 104
_field105 = 105
_field106 = 106
_field107 = 107
_field108 = 108
_field109 = 109
_field110 = 110
_field111 = 111
_field112 = 112
_field113 = 113
_field114 = 114
_field115 = 115
_field116 = 116
_field117 = 117
_field118 = 118
_field119 = 119
_field120 = 120
_field121 = 121
_field122 = 122
_field123 = 123
_field124 = 124
_field125 = 125
_field126 = 126
_field127 = 127
_field128 = 128
}
foo {
IO.print(_field1)
IO.print(_field128)
}
}
class Bar is Foo {
new {
super
_field129 = 129
_field130 = 130
_field131 = 131
_field132 = 132
_field133 = 133
_field134 = 134
_field135 = 135
_field136 = 136
_field137 = 137
_field138 = 138
_field139 = 139
_field140 = 140
_field141 = 141
_field142 = 142
_field143 = 143
_field144 = 144
_field145 = 145
_field146 = 146
_field147 = 147
_field148 = 148
_field149 = 149
_field150 = 150
_field151 = 151
_field152 = 152
_field153 = 153
_field154 = 154
_field155 = 155
_field156 = 156
_field157 = 157
_field158 = 158
_field159 = 159
_field160 = 160
_field161 = 161
_field162 = 162
_field163 = 163
_field164 = 164
_field165 = 165
_field166 = 166
_field167 = 167
_field168 = 168
_field169 = 169
_field170 = 170
_field171 = 171
_field172 = 172
_field173 = 173
_field174 = 174
_field175 = 175
_field176 = 176
_field177 = 177
_field178 = 178
_field179 = 179
_field180 = 180
_field181 = 181
_field182 = 182
_field183 = 183
_field184 = 184
_field185 = 185
_field186 = 186
_field187 = 187
_field188 = 188
_field189 = 189
_field190 = 190
_field191 = 191
_field192 = 192
_field193 = 193
_field194 = 194
_field195 = 195
_field196 = 196
_field197 = 197
_field198 = 198
_field199 = 199
_field200 = 200
_field201 = 201
_field202 = 202
_field203 = 203
_field204 = 204
_field205 = 205
_field206 = 206
_field207 = 207
_field208 = 208
_field209 = 209
_field210 = 210
_field211 = 211
_field212 = 212
_field213 = 213
_field214 = 214
_field215 = 215
_field216 = 216
_field217 = 217
_field218 = 218
_field219 = 219
_field220 = 220
_field221 = 221
_field222 = 222
_field223 = 223
_field224 = 224
_field225 = 225
_field226 = 226
_field227 = 227
_field228 = 228
_field229 = 229
_field230 = 230
_field231 = 231
_field232 = 232
_field233 = 233
_field234 = 234
_field235 = 235
_field236 = 236
_field237 = 237
_field238 = 238
_field239 = 239
_field240 = 240
_field241 = 241
_field242 = 242
_field243 = 243
_field244 = 244
_field245 = 245
_field246 = 246
_field247 = 247
_field248 = 248
_field249 = 249
_field250 = 250
_field251 = 251
_field252 = 252
_field253 = 253
_field254 = 254
_field255 = 255
}
bar {
IO.print(_field129)
IO.print(_field255)
}
}
var bar = new Bar
bar.foo // expect: 1
// expect: 128
bar.bar // expect: 129
// expect: 255