Skip to content

Commit a591c17

Browse files
authored
Merge pull request #4651 from WalterBright/stdio-trusted
std.stdio: fix unsafe use of .ptr
2 parents d60fde5 + 629b5ee commit a591c17

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

std/stdio.d

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -835,8 +835,7 @@ $(D rawRead) always reads in binary mode on Windows.
835835
scope(exit) __fhnd_info[fd] = info;
836836
}
837837
}
838-
immutable freadResult =
839-
fread(buffer.ptr, T.sizeof, buffer.length, _p.handle);
838+
immutable freadResult = trustedFread(_p.handle, buffer);
840839
assert (freadResult <= buffer.length); // fread return guarantee
841840
if (freadResult != buffer.length) // error or eof
842841
{
@@ -893,8 +892,7 @@ Throws: $(D ErrnoException) if the file is not opened or if the call to $(D fwri
893892
}
894893
scope(exit) flush(); // before restoring translation mode
895894
}
896-
auto result =
897-
.fwrite(buffer.ptr, T.sizeof, buffer.length, _p.handle);
895+
auto result = trustedFwrite(_p.handle, buffer);
898896
if (result == result.max) result = 0;
899897
errnoEnforce(result == buffer.length,
900898
text("Wrote ", result, " instead of ", buffer.length,
@@ -1892,7 +1890,7 @@ Allows to directly use range operations on lines of a file.
18921890
}
18931891
else
18941892
static assert(false);
1895-
line = line.ptr[0 .. line.length - tlen];
1893+
line = line[0 .. line.length - tlen];
18961894
}
18971895
}
18981896
}
@@ -2576,12 +2574,7 @@ $(D Range) that locks the file and allows fast writing to it.
25762574
{
25772575
//file.write(writeme); causes infinite recursion!!!
25782576
//file.rawWrite(writeme);
2579-
static auto trustedFwrite(in void* ptr, size_t size, size_t nmemb, FILE* stream) @trusted
2580-
{
2581-
return .fwrite(ptr, size, nmemb, stream);
2582-
}
2583-
auto result =
2584-
trustedFwrite(writeme.ptr, C.sizeof, writeme.length, fps_);
2577+
auto result = trustedFwrite(fps_, writeme);
25852578
if (result != writeme.length) errnoEnforce(0);
25862579
return;
25872580
}
@@ -2767,8 +2760,7 @@ See $(LREF byChunk) for an example.
27672760
import std.conv : text;
27682761
import std.exception : errnoEnforce;
27692762

2770-
auto result =
2771-
.fwrite(buffer.ptr, T.sizeof, buffer.length, fps);
2763+
auto result = trustedFwrite(fps, buffer);
27722764
if (result == result.max) result = 0;
27732765
errnoEnforce(result == buffer.length,
27742766
text("Wrote ", result, " instead of ", buffer.length,
@@ -3740,12 +3732,18 @@ version (Posix)
37403732

37413733
/*
37423734
* Convenience function that forwards to $(D core.stdc.stdio.fwrite)
3743-
* and throws an exception upon error
37443735
*/
3745-
private void binaryWrite(T)(FILE* f, T obj)
3736+
private auto trustedFwrite(T)(FILE* f, const T[] obj) @trusted
3737+
{
3738+
return fwrite(obj.ptr, T.sizeof, obj.length, f);
3739+
}
3740+
3741+
/*
3742+
* Convenience function that forwards to $(D core.stdc.stdio.fread)
3743+
*/
3744+
private auto trustedFread(T)(FILE* f, T[] obj) @trusted
37463745
{
3747-
immutable result = fwrite(obj.ptr, obj[0].sizeof, obj.length, f);
3748-
if (result != obj.length) StdioException();
3746+
return fread(obj.ptr, T.sizeof, obj.length, f);
37493747
}
37503748

37513749
/**
@@ -4075,7 +4073,7 @@ private struct ChunksImpl
40754073
size_t r = void;
40764074
int result = 1;
40774075
uint tally = 0;
4078-
while ((r = fread(buffer.ptr, buffer[0].sizeof, size, f._p.handle)) > 0)
4076+
while ((r = trustedFread(f._p.handle, buffer)) > 0)
40794077
{
40804078
assert(r <= size);
40814079
if (r != size)
@@ -4169,7 +4167,7 @@ class StdioException : Exception
41694167
/**
41704168
Initialize with a message and an error code.
41714169
*/
4172-
this(string message, uint e = core.stdc.errno.errno)
4170+
this(string message, uint e = core.stdc.errno.errno) @trusted
41734171
{
41744172
import std.conv : to;
41754173

@@ -4199,7 +4197,7 @@ Initialize with a message and an error code.
41994197
// If e is 0, we don't use the system error message. (The message
42004198
// is "Success", which is rather pointless for an exception.)
42014199
super(e == 0 ? message
4202-
: (message.ptr ? message ~ " (" ~ sysmsg ~ ")" : sysmsg));
4200+
: (message ? message ~ " (" ~ sysmsg ~ ")" : sysmsg));
42034201
}
42044202

42054203
/** Convenience functions that throw an $(D StdioException). */
@@ -4312,7 +4310,7 @@ private struct ReadlnAppender
43124310
buf = b;
43134311
pos = 0;
43144312
}
4315-
@property char[] data()
4313+
@property char[] data() @trusted
43164314
{
43174315
if (safeAppend)
43184316
assumeSafeAppend(buf.ptr[0..pos]);
@@ -4336,7 +4334,7 @@ private struct ReadlnAppender
43364334

43374335
return false;
43384336
}
4339-
void reserve(size_t n)
4337+
void reserve(size_t n) @trusted
43404338
{
43414339
import core.stdc.string : memcpy;
43424340
if (!reserveWithoutAllocating(n))
@@ -4349,12 +4347,12 @@ private struct ReadlnAppender
43494347
safeAppend = true;
43504348
}
43514349
}
4352-
void putchar(char c)
4350+
void putchar(char c) @trusted
43534351
{
43544352
reserve(1);
43554353
buf.ptr[pos++] = c;
43564354
}
4357-
void putdchar(dchar dc)
4355+
void putdchar(dchar dc) @trusted
43584356
{
43594357
import std.utf : toUTF8;
43604358

@@ -4364,7 +4362,7 @@ private struct ReadlnAppender
43644362
foreach (c; u)
43654363
buf.ptr[pos++] = c;
43664364
}
4367-
void putonly(char[] b)
4365+
void putonly(char[] b) @trusted
43684366
{
43694367
import core.stdc.string : memcpy;
43704368
assert(pos == 0); // assume this is the only put call
@@ -4475,7 +4473,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
44754473
}
44764474
}
44774475
app.putonly(p[0..i]);
4478-
app.buf.ptr[i - 1] = cast(char)terminator;
4476+
app.buf[i - 1] = cast(char)terminator;
44794477
if (terminator == '\n' && c == '\r')
44804478
i++;
44814479
}
@@ -4624,7 +4622,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
46244622

46254623
if (s <= buf.length)
46264624
{
4627-
buf = buf.ptr[0 .. s];
4625+
buf = buf[0 .. s];
46284626
buf[] = lineptr[0 .. s];
46294627
}
46304628
else
@@ -4710,7 +4708,7 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orie
47104708
buf.length = bufPos;
47114709
goto endGame;
47124710
}
4713-
buf.ptr[bufPos++] = cast(char) c;
4711+
buf[bufPos++] = cast(char) c;
47144712
if (c == terminator)
47154713
{
47164714
// No need to test for errors in file

0 commit comments

Comments
 (0)