authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-02 21:32:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-02 16:44:30-05:00
loge9536ca10fe53d829551624b9d5753b163577eb2
tree08b32fd9e799f87504af63f3e9991343b97c7344
parentafd029091854358e6e88cfc4cbb524022f4ec136

Fix edge case in C tokenizer

Closes #4042

1 files changed, 40 insertions(+), 16 deletions(-)

src-self-hosted/c_tokenizer.zig+40-16
...@@ -207,23 +207,30 @@ fn zigifyEscapeSequences(ctx: *Context, loc: ZigClangSourceLocation, name: []con...@@ -207,23 +207,30 @@ fn zigifyEscapeSequences(ctx: *Context, loc: ZigClangSourceLocation, name: []con
207 }207 }
208 },208 },
209 .Octal => {209 .Octal => {
210 switch (c) {210 const accept_digit = switch (c) {
211 '0'...'7' => {211 // The maximum length of a octal literal is 3 digits
212 count += 1;212 '0'...'7' => count < 3,
213 num = std.math.mul(u8, num, 8) catch {213 else => false,
214 try failDecl(ctx, loc, name, "macro tokenizing failed: octal literal overflowed", .{});214 };
215 return error.TokenizingFailed;215
216 };216 if (accept_digit) {
217 num += c - '0';217 count += 1;
218 if (count < 3)218 num = std.math.mul(u8, num, 8) catch {
219 continue;219 try failDecl(ctx, loc, name, "macro tokenizing failed: octal literal overflowed", .{});
220 },220 return error.TokenizingFailed;
221 else => {},221 };
222 num += c - '0';
223 } else {
224 i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
225 num = 0;
226 count = 0;
227 if (c == '\\')
228 state = .Escape
229 else
230 state = .Start;
231 bytes[i] = c;
232 i += 1;
222 }233 }
223 i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
224 state = .Start;
225 count = 0;
226 num = 0;
227 },234 },
228 }235 }
229 }236 }
...@@ -940,4 +947,21 @@ test "escape sequences" {...@@ -940,4 +947,21 @@ test "escape sequences" {
940 .id = .StrLit,947 .id = .StrLit,
941 .bytes = "\\045abc",948 .bytes = "\\045abc",
942 })).bytes, "\\x25abc"));949 })).bytes, "\\x25abc"));
950
951 expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
952 .id = .CharLit,
953 .bytes = "\\0",
954 })).bytes, "\\x00"));
955 expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
956 .id = .CharLit,
957 .bytes = "\\00",
958 })).bytes, "\\x00"));
959 expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
960 .id = .CharLit,
961 .bytes = "\\000\\001",
962 })).bytes, "\\x00\\x01"));
963 expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
964 .id = .CharLit,
965 .bytes = "\\000abc",
966 })).bytes, "\\x00abc"));
943}967}