Skip to content

Commit

Permalink
Working towards #10: add some parameter validation to Scanf
Browse files Browse the repository at this point in the history
  • Loading branch information
derrell committed Oct 27, 2014
1 parent 8699f9e commit 8d536ce
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 2 deletions.
17 changes: 17 additions & 0 deletions desktop/compilers/ansic/canning/TESTS-EXPECTED-OUTPUT
Original file line number Diff line number Diff line change
Expand Up @@ -1319,3 +1319,20 @@ STDOUT:
>>> Running program
>>> Program exited with exit code 0

% echo '3' | ../dcc t084-scanf-one-format-marker-no-address.c --rootdir=../../../../backend-nodesqlite/deploy/stdio_files
3
ERROR: Error: Command failed:
STDOUT:
>>> Running program
Enter a number: Error near line 6: The format marker ("%d") requires an additional argument,
an address, where the value should be stored.
>>> Program had errors. It did not run to completion.

% ../dcc t085-scanf-invalid-format-string-addr.c --rootdir=../../../../backend-nodesqlite/deploy/stdio_files
ERROR: Error: Command failed:
STDOUT:
>>> Running program
Error near line 5: The format string argument appears to be invalid.
It is not the address of a string in memory
>>> Program had errors. It did not run to completion.

7 changes: 7 additions & 0 deletions desktop/compilers/ansic/canning/_dotests.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,13 @@ var tests =
},
{
name : "t083-array-initializer-negative-value.c"
},
{
name : "t084-scanf-one-format-marker-no-address.c",
stdin : "3"
},
{
name : "t085-scanf-invalid-format-string-addr.c"
}
];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <stdio.h>

int main(void)
{
printf("Enter a number: ");
scanf("%d, &input");
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdio.h>

int main(void)
{
scanf(23);
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ qx.Class.define("playground.c.lib.Declarator",
var thisType;
var otherType;

// normalize various pointer types for this specifier
// normalize various pointer types for this declarator
if ([ "pointer", "address", "array" ].indexOf(this.__type) != -1)
{
thisType = "pointer";
Expand All @@ -313,7 +313,7 @@ qx.Class.define("playground.c.lib.Declarator",
thisType = this.__type;
}

// Similarly, normalize the other specifier
// Similarly, normalize the other declarator
if ([ "pointer", "address", "array" ].indexOf(other.__type) != -1)
{
otherType = "pointer";
Expand Down
85 changes: 85 additions & 0 deletions desktop/playground/source/class/playground/c/stdio/Scanf.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ qx.Class.define("playground.c.stdio.Scanf",
var format = [];
var memBytes;
var i;
var info = playground.c.machine.Memory.info;

if (typeof formatAddr === "undefined")
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format string is missing.");
}

// Get memory as an array
this._mem = playground.c.machine.Memory.getInstance();
Expand All @@ -79,6 +87,20 @@ qx.Class.define("playground.c.stdio.Scanf",
// character at a time, into an array.
for (i = formatAddr; memBytes[i] != 0 && i < memBytes.length; i++)
{
// Ensure we are accessing a valid region of memory
if (! ((i >= info.gas.start &&
i < info.gas.start + info.gas.length) ||
(i >= info.heap.start &&
i < info.heap.start + info.heap.length) ||
(i >= info.rts.start &&
i < info.rts.start + info.rts.length)))
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format string argument appears to be invalid.\n" +
" It is not the address of a string in memory");
}

format.push(memBytes[i]);
}

Expand Down Expand Up @@ -859,6 +881,15 @@ qx.Class.define("playground.c.stdio.Scanf",
case 'n':
if (! (flags & this.Flags.NOASSIGN))
{ // silly, though
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%n\") requires an additional " +
"argument to scanf," +
"\n an address, where the value should be stored.");
}

if (flags & this.Flags.SHORT)
{
this._mem.set(this._args.shift(), "short", nrchars);
Expand Down Expand Up @@ -916,6 +947,15 @@ qx.Class.define("playground.c.stdio.Scanf",

if (! (flags & this.Flags.NOASSIGN))
{
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%" + kind + "\") requires " +
"an additional argument, " +
"\n an address, where the value should be stored.");
}

val = parseInt(this._inpBuf.join(""), base);

if (flags & this.Flags.LONG)
Expand Down Expand Up @@ -949,6 +989,15 @@ qx.Class.define("playground.c.stdio.Scanf",

if (! (flags & this.Flags.NOASSIGN))
{
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%c\") requies that " +
"more addresses (arguments) in which to store values " +
"must be provided.\n");
}

addr = this._args.shift();
}

Expand All @@ -966,6 +1015,15 @@ qx.Class.define("playground.c.stdio.Scanf",
{
if (! (flags & this.Flags.NOASSIGN))
{
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%c\") requires an additional " +
"argument to scanf, " +
"\n an address, where the value should be stored.");
}

this._mem.set(addr + i++, "char", ic.charCodeAt(0));
}

Expand Down Expand Up @@ -1067,6 +1125,15 @@ qx.Class.define("playground.c.stdio.Scanf",

if (! (flags & this.Flags.NOASSIGN))
{
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%s\") requires an additional " +
"argument to scanf, " +
"\n an address, where the string will be stored.");
}

addr = this._args.shift();
}

Expand Down Expand Up @@ -1151,6 +1218,15 @@ qx.Class.define("playground.c.stdio.Scanf",

if (! (flags & this.Flags.NOASSIGN))
{
if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%[\") requires an additional " +
"argument to scanf, " +
"\n an address, where the string will be stored.");
}

addr = this._args.shift();
}

Expand Down Expand Up @@ -1240,6 +1316,15 @@ qx.Class.define("playground.c.stdio.Scanf",
{
ld_val = parseFloat(this._inpBuf.join(""));

if (this._args.length < 1)
{
throw new playground.c.lib.RuntimeError(
playground.c.lib.Node._currentNode,
"The format marker (\"%" + kind + "\") requires " +
"an additional argument, " +
"\n an address, where the value should be stored.");
}

if (flags & this.Flags.LONG)
{
this._mem.set(this._args.shift(), "double", ld_val);
Expand Down

0 comments on commit 8d536ce

Please sign in to comment.