summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-07-26 09:42:30 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-07-27 20:38:06 -0400
commit51b468f688a3660c4842b9e634c5fe58a2196307 (patch)
tree1ecd53f2ee6985ec0e0e30d02b4773e953514084 /pp_sys.c
parentce5b0b849c4a3e4d77dc60096ae4170609a81644 (diff)
downloadperl-51b468f688a3660c4842b9e634c5fe58a2196307.tar.gz
readlink() result buffer is not zero-terminated.
Therefore, as an extra paranoia step, zero-terminate the readlink result buffer even before the result SV is created. Also, readlink returns SSize_t, not int.
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 501146e3c6..e01cf487a3 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3671,13 +3671,17 @@ PP(pp_readlink)
dTARGET;
const char *tmps;
char buf[MAXPATHLEN];
- int len;
+ SSize_t len;
TAINT;
tmps = POPpconstx;
+ /* NOTE: if the length returned by readlink() is sizeof(buf) - 1,
+ * it is impossible to know whether the result was truncated. */
len = readlink(tmps, buf, sizeof(buf) - 1);
if (len < 0)
RETPUSHUNDEF;
+ if (len != -1)
+ buf[len] = '\0';
PUSHp(buf, len);
RETURN;
#else