diff --git a/src/attrib.d b/src/attrib.d index 3a83809d0a15..f5e649ce5eb7 100644 --- a/src/attrib.d +++ b/src/attrib.d @@ -413,7 +413,7 @@ public: char* depmsg = null; StringExp se = msg.toStringExp(); if (se) - depmsg = cast(char*)se.string; + depmsg = se.toStringz(); else msg.error("string expected, not '%s'", msg.toChars()); Scope* scx = sc.push(); @@ -1266,7 +1266,8 @@ public: { se = se.toUTF8(sc); uint errors = global.errors; - scope Parser p = new Parser(loc, sc._module, cast(char*)se.string, se.len, 0); + auto cstr = se.toStringz(); + scope Parser p = new Parser(loc, sc._module, cstr, se.len, 0); p.nextToken(); decl = p.parseDeclDefs(0); if (p.token.value != TOKeof) diff --git a/src/backend/dt.c b/src/backend/dt.c index b952916f81a1..e46ca9b989f3 100644 --- a/src/backend/dt.c +++ b/src/backend/dt.c @@ -175,23 +175,25 @@ dt_t ** dtnbytes(dt_t **pdtend,unsigned size,const char *ptr) * Construct a DTabytes record, and return it. */ -dt_t **dtabytes(dt_t **pdtend, unsigned offset, unsigned size, const char *ptr) +dt_t **dtabytes(dt_t **pdtend, unsigned offset, unsigned size, const char *ptr, unsigned nbytes) { - return dtabytes(pdtend, TYnptr, offset, size, ptr); + return dtabytes(pdtend, TYnptr, offset, size, ptr, nbytes); } -dt_t **dtabytes(dt_t **pdtend,tym_t ty, unsigned offset, unsigned size, const char *ptr) +dt_t **dtabytes(dt_t **pdtend,tym_t ty, unsigned offset, unsigned size, const char *ptr, unsigned nbytes) { dt_t *dt; while (*pdtend) pdtend = &((*pdtend)->DTnext); dt = dt_calloc(DT_abytes); - dt->DTnbytes = size; - dt->DTpbytes = (char *) MEM_PH_MALLOC(size); + dt->DTnbytes = size + nbytes; + dt->DTpbytes = (char *) MEM_PH_MALLOC(size + nbytes); dt->Dty = ty; dt->DTabytes = offset; memcpy(dt->DTpbytes,ptr,size); + if (size) + memset(dt->DTpbytes + size, 0, nbytes); *pdtend = dt; pdtend = &dt->DTnext; diff --git a/src/backend/dt.h b/src/backend/dt.h index a5da922a30ad..b74484d240b0 100644 --- a/src/backend/dt.h +++ b/src/backend/dt.h @@ -11,8 +11,8 @@ void dt_free(dt_t *); void dt_term(); dt_t **dtnbytes(dt_t **,unsigned,const char *); -dt_t **dtabytes(dt_t **pdtend,tym_t ty, unsigned offset, unsigned size, const char *ptr); -dt_t **dtabytes(dt_t **pdtend, unsigned offset, unsigned size, const char *ptr); +dt_t **dtabytes(dt_t **pdtend,tym_t ty, unsigned offset, unsigned size, const char *ptr, unsigned nzeros); +dt_t **dtabytes(dt_t **pdtend, unsigned offset, unsigned size, const char *ptr, unsigned nzeros); dt_t **dtdword(dt_t **, int value); dt_t **dtsize_t(dt_t **, unsigned long long value); dt_t **dtnzeros(dt_t **pdtend,unsigned size); diff --git a/src/e2ir.c b/src/e2ir.c index eb5995476c7e..4c394afe059e 100644 --- a/src/e2ir.c +++ b/src/e2ir.c @@ -1391,9 +1391,11 @@ elem *toElem(Expression *e, IRState *irs) e = el_calloc(); e->Eoper = OPstring; // freed in el_free - e->EV.ss.Vstring = (char *)mem_malloc((se->len + 1) * se->sz); - memcpy(e->EV.ss.Vstring, se->string, (se->len + 1) * se->sz); - e->EV.ss.Vstrlen = (se->len + 1) * se->sz; + unsigned len = se->len * se->sz; + e->EV.ss.Vstring = (char *)mem_malloc(len + se->sz); + memcpy(e->EV.ss.Vstring, se->string, len); + memset(e->EV.ss.Vstring + len, 0, se->sz); + e->EV.ss.Vstrlen = len + se->sz; e->Ety = TYnptr; } else @@ -5593,7 +5595,8 @@ Symbol *toStringSymbol(const char *str, size_t len, size_t sz) Symbol *si = symbol_generate(SCstatic,type_static_array(len * sz, tschar)); si->Salignment = 1; si->Sdt = NULL; - dtnbytes(&si->Sdt, (len + 1) * sz, str); + dt_t **pdt = dtnbytes(&si->Sdt, len * sz, str); + dtnzeros(pdt, sz); si->Sfl = FLdata; out_readonly(si); outdata(si); diff --git a/src/expression.d b/src/expression.d index 976441167b8c..3c49b80f8c90 100644 --- a/src/expression.d +++ b/src/expression.d @@ -4428,6 +4428,19 @@ public: return value; } + /******************************** + * Convert string contents to a 0 terminated string, + * allocated by mem.xmalloc(). + */ + final char* toStringz() + { + auto nbytes = len * sz; + char* s = cast(char*)mem.xmalloc(nbytes + sz); + memcpy(s, string, nbytes); + memset(s + nbytes, 0, sz); + return s; + } + override void accept(Visitor v) { v.visit(this); @@ -7602,12 +7615,14 @@ public: override Expression semantic(Scope* sc) { - const(char)* name; - StringExp se; static if (LOGSEMANTIC) { printf("FileExp::semantic('%s')\n", toChars()); } + const(char)* name; + char* namez; + StringExp se; + sc = sc.startCTFE(); e1 = e1.semantic(sc); e1 = resolveProperties(sc, e1); @@ -7620,24 +7635,24 @@ public: } se = cast(StringExp)e1; se = se.toUTF8(sc); - name = cast(char*)se.string; + namez = se.toStringz(); if (!global.params.fileImppath) { - error("need -Jpath switch to import text file %s", name); + error("need -Jpath switch to import text file %s", namez); goto Lerror; } /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory * ('Path Traversal') attacks. * http://cwe.mitre.org/data/definitions/22.html */ - name = FileName.safeSearchPath(global.filePath, name); + name = FileName.safeSearchPath(global.filePath, namez); if (!name) { error("file %s cannot be found or not in a path specified with -J", se.toChars()); goto Lerror; } if (global.params.verbose) - fprintf(global.stdmsg, "file %s\t(%s)\n", cast(char*)se.string, name); + fprintf(global.stdmsg, "file %.*s\t(%s)\n", cast(int)se.len, se.string, name); if (global.params.moduleDeps !is null) { OutBuffer* ob = global.params.moduleDeps; @@ -7650,7 +7665,7 @@ public: ob.writestring(") : "); if (global.params.moduleDepsFile) ob.writestring("string : "); - ob.writestring(cast(char*)se.string); + ob.write(se.string, se.len); ob.writestring(" ("); escapePath(ob, name); ob.writestring(")"); diff --git a/src/expression.h b/src/expression.h index 1eca529c29f0..297991ea48ef 100644 --- a/src/expression.h +++ b/src/expression.h @@ -380,6 +380,7 @@ class StringExp : public Expression Expression *modifiableLvalue(Scope *sc, Expression *e); unsigned charAt(uinteger_t i); void accept(Visitor *v) { v->visit(this); } + char *toStringz(); }; // Tuple diff --git a/src/todt.c b/src/todt.c index 0789bf2f2c0b..230e28da2e75 100644 --- a/src/todt.c +++ b/src/todt.c @@ -381,7 +381,8 @@ dt_t **Expression_toDt(Expression *e, dt_t **pdt) { case Tarray: pdt = dtsize_t(pdt, e->len); - pdt = dtabytes(pdt, 0, (e->len + 1) * e->sz, (char *)e->string); + case Tpointer: + pdt = dtabytes(pdt, 0, e->len * e->sz, (const char *)e->string, (unsigned)e->sz); break; case Tsarray: @@ -400,9 +401,6 @@ dt_t **Expression_toDt(Expression *e, dt_t **pdt) } break; } - case Tpointer: - pdt = dtabytes(pdt, 0, (e->len + 1) * e->sz, (char *)e->string); - break; default: printf("StringExp::toDt(type = %s)\n", e->type->toChars());