summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/Tcl.n2
-rw-r--r--generic/tclEncoding.c18
-rw-r--r--generic/tclZlib.c41
-rw-r--r--tests/zlib.test32
4 files changed, 81 insertions, 12 deletions
diff --git a/doc/Tcl.n b/doc/Tcl.n
index d13f3ea..99af4df 100644
--- a/doc/Tcl.n
+++ b/doc/Tcl.n
@@ -92,7 +92,7 @@ result of the script.
.IP "[8] \fBCommand substitution.\fR"
Each pair of brackets
.PQ [
-and
+and
.PQ ] ""
encloses a script and is replaced by the result of that script.
.IP "[9] \fBVariable substitution.\fR"
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index d0756c7..61e3236 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -1253,7 +1253,7 @@ Tcl_ExternalToUtf(
Tcl_Encoding encoding, /* The encoding for the source string, or NULL
* for the default system encoding. */
const char *src, /* Source string in specified encoding. */
- Tcl_Size srcLen, /* Source string length in bytes, or < 0 for
+ Tcl_Size srcLen, /* Source string length in bytes, or TCL_INDEX_NONE for
* encoding-specific string length. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -1298,6 +1298,13 @@ Tcl_ExternalToUtf(
flags |= TCL_ENCODING_START | TCL_ENCODING_END;
statePtr = &state;
}
+ if (srcLen > INT_MAX) {
+ srcLen = INT_MAX;
+ flags &= ~TCL_ENCODING_END;
+ }
+ if (dstLen > INT_MAX) {
+ dstLen = INT_MAX;
+ }
if (srcReadPtr == NULL) {
srcReadPtr = &srcRead;
}
@@ -1515,7 +1522,7 @@ Tcl_UtfToExternal(
Tcl_Encoding encoding, /* The encoding for the converted string, or
* NULL for the default system encoding. */
const char *src, /* Source string in UTF-8. */
- Tcl_Size srcLen, /* Source string length in bytes, or < 0 for
+ Tcl_Size srcLen, /* Source string length in bytes, or TCL_INDEX_NONE for
* strlen(). */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -1557,6 +1564,13 @@ Tcl_UtfToExternal(
flags |= TCL_ENCODING_START | TCL_ENCODING_END;
statePtr = &state;
}
+ if (srcLen > INT_MAX) {
+ srcLen = INT_MAX;
+ flags &= ~TCL_ENCODING_END;
+ }
+ if (dstLen > INT_MAX) {
+ dstLen = INT_MAX;
+ }
if (srcReadPtr == NULL) {
srcReadPtr = &srcRead;
}
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index 5a6dbc4..a0e79ac 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -443,10 +443,21 @@ GenerateHeader(
if (GetValue(interp, dictObj, "comment", &value) != TCL_OK) {
goto error;
} else if (value != NULL) {
- valueStr = Tcl_GetStringFromObj(value, &length);
- Tcl_UtfToExternal(NULL, latin1enc, valueStr, length, 0, NULL,
+ Tcl_EncodingState state;
+ valueStr = Tcl_GetStringFromObj(value, &len);
+ result = Tcl_UtfToExternal(NULL, latin1enc, valueStr, len,
+ TCL_ENCODING_START|TCL_ENCODING_END|TCL_ENCODING_STOPONERROR, &state,
headerPtr->nativeCommentBuf, MAX_COMMENT_LEN-1, NULL, &len,
NULL);
+ if (result != TCL_OK) {
+ if (result == TCL_CONVERT_UNKNOWN) {
+ Tcl_AppendResult(interp, "Comment contains characters > 0xFF", NULL);
+ } else {
+ Tcl_AppendResult(interp, "Comment too large for zip", NULL);
+ }
+ result = TCL_ERROR;
+ goto error;
+ }
headerPtr->nativeCommentBuf[len] = '\0';
headerPtr->header.comment = (Bytef *) headerPtr->nativeCommentBuf;
if (extraSizePtr != NULL) {
@@ -464,9 +475,21 @@ GenerateHeader(
if (GetValue(interp, dictObj, "filename", &value) != TCL_OK) {
goto error;
} else if (value != NULL) {
- valueStr = Tcl_GetStringFromObj(value, &length);
- Tcl_UtfToExternal(NULL, latin1enc, valueStr, length, 0, NULL,
- headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len, NULL);
+ Tcl_EncodingState state;
+ valueStr = Tcl_GetStringFromObj(value, &len);
+ result = Tcl_UtfToExternal(NULL, latin1enc, valueStr, len,
+ TCL_ENCODING_START|TCL_ENCODING_END|TCL_ENCODING_STOPONERROR, &state,
+ headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len,
+ NULL);
+ if (result != TCL_OK) {
+ if (result == TCL_CONVERT_UNKNOWN) {
+ Tcl_AppendResult(interp, "Filename contains characters > 0xFF", NULL);
+ } else {
+ Tcl_AppendResult(interp, "Filename too large for zip", NULL);
+ }
+ result = TCL_ERROR;
+ goto error;
+ }
headerPtr->nativeFilenameBuf[len] = '\0';
headerPtr->header.name = (Bytef *) headerPtr->nativeFilenameBuf;
if (extraSizePtr != NULL) {
@@ -547,8 +570,8 @@ ExtractHeader(
}
}
- Tcl_ExternalToUtfDStringEx(latin1enc, (char *) headerPtr->comment, -1,
- TCL_ENCODING_NOCOMPLAIN, &tmp);
+ Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->comment, -1,
+ &tmp);
SetValue(dictObj, "comment", Tcl_DStringToObj(&tmp));
}
SetValue(dictObj, "crc", Tcl_NewBooleanObj(headerPtr->hcrc));
@@ -564,8 +587,8 @@ ExtractHeader(
}
}
- Tcl_ExternalToUtfDStringEx(latin1enc, (char *) headerPtr->name, -1,
- TCL_ENCODING_NOCOMPLAIN, &tmp);
+ Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->name, -1,
+ &tmp);
SetValue(dictObj, "filename", Tcl_DStringToObj(&tmp));
}
if (headerPtr->os != 255) {
diff --git a/tests/zlib.test b/tests/zlib.test
index 1c9514d..9e6d563 100644
--- a/tests/zlib.test
+++ b/tests/zlib.test
@@ -486,6 +486,38 @@ test zlib-8.18 {Bug dd260aaf: fconfigure} -setup {
catch {close $inSide}
catch {close $outSide}
} -result {{one two} {one two}}
+test zlib-8.19 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header [list comment [string repeat A 500]]]
+} -cleanup {
+ catch {close $f}
+ removeFile $file
+} -returnCodes 1 -result {Comment too large for zip}
+test zlib-8.20 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header [list filename [string repeat A 5000]]]
+} -cleanup {
+ catch {close $f}
+ removeFile $file
+} -returnCodes 1 -result {Filename too large for zip}
+test zlib-8.21 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header [list comment \u100]]
+} -cleanup {
+ catch {close $f}
+ removeFile $file
+} -returnCodes 1 -result {Comment contains characters > 0xFF}
+test zlib-8.22 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header [list filename \u100]]
+} -cleanup {
+ catch {close $f}
+ removeFile $file
+} -returnCodes 1 -result {Filename contains characters > 0xFF}
test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
set sfile [makeFile {} testsrc.gz]