<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>I don't have it completely nailed, but the corruption is
happening in here:<br>
</p>
<p><font face="Georgia">ZnUtils class>>readUpToEnd:
inputStream limit: limit<br>
| species bufferSize buffer totalRead outputStream answer ch
|<br>
bufferSize := limit ifNil: [ self streamingBufferSize ]
ifNotNil: [ self streamingBufferSize min: limit ].<br>
species := inputStream isBinary ifTrue: [ ByteArray ]
ifFalse: [ String ].<br>
buffer := species new: bufferSize.<br>
totalRead := 0.<br>
outputStream := nil. <br>
[ inputStream atEnd ] whileFalse: [ | readCount |<br>
readCount := inputStream readInto: buffer startingAt: 1
count: bufferSize.<br>
totalRead = 0 ifTrue: [<br>
ch := buffer first.<br>
<b>BOB note2: { 'readUpToEnd:'. species .
readCount. bufferSize. buffer copy. inputStream } this records
the fact that data put into the beginning of the buffer is
correct</b><br>
].<br>
totalRead := totalRead + readCount.<br>
(limit notNil and: [ totalRead > limit ])<br>
ifTrue: [ ZnEntityTooLarge signal ].<br>
outputStream ifNil: [ <br>
inputStream atEnd<br>
ifTrue: [ ^ buffer copyFrom: 1 to: readCount ] <br>
ifFalse: [ outputStream := (species new:
bufferSize) writeStream ] ].<br>
<b>BOB watchit: true. this enables noting when the
outputStream needs to grow a new collection</b><br>
outputStream next: readCount putAll: buffer startingAt:
1.<br>
<b>BOB watchit: false. this just turns it off</b><br>
<b>totalRead = readCount ifTrue: [BOB note2: {
'outcontents'. outputStream contents first: 100. outputStream
}]. this verifies that buffer made it to outputStream
correctly in the first pass</b><br>
<b>ch = outputStream contents first ifFalse: [ self halt ].
this tests every pass to see that the output is still good.
And eventually it is NOT</b><br>
self signalProgress: totalRead total: limit ].<br>
answer := outputStream ifNil: [ species new ] ifNotNil: [
outputStream contents ].<br>
<b>BOB note2: { 'answer'. answer first: 100. outputStream
}. this records what we are answering and it can be wrong.</b><br>
^answer</font><br>
</p>
So what happens?<br>
- data is added to the outputStream normally<br>
- the outputStream collection grows in an ordinary-looking fashion<br>
- then the check that <font face="Georgia"><b>ch = outputStream
contents first</b></font> fails -- the first 4 bytes in the
outputStream are now zero.<br>
- why here?<br>
--- we have just written data that pushed the outputStream to
18186240 bytes<br>
--- that write caused a grow from 18184052 to 22732263 in the
stream's collection<br>
--- after that grow/write, the initial bytes are changed --
something to do with the grow??<br>
--- another interesting but likely irrelevant fact is that the data
written just before the error is the last full 16384 from the file.
The next and final buffer to be written will only be 15845 bytes,
but that hasn't happened yet. so??<br>
<br>
I've been trying to recreate the error with a simple loop writing
data, but no success so far.<br>
<br>
<div class="moz-cite-prefix">On 1/10/18 4:42 AM, Cyrille Delaunay
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAMEdb_D9freOHuP8VR1gdOAS8vjZW7T28o+1BVN9urqg_OacYQ@mail.gmail.com">ZnDefaultServerDelegate
>> formTest3: request<br>
> | contents filename contentType page |<br>
> contents := filename := contentType := ''.<br>
> (request hasEntity and: [ request contentType matches:
ZnMimeType multiPartFormData ])<br>
> ifTrue: [<br>
> (request entity partNamed: #file
ifNone: [ nil ])<br>
> ifNotNil: [ :part |<br>
> filename := part
fileName.<br>
> contents := part
contents.<br>
> contentType := part
contentType.<br>
> contentType isBinary
ifTrue: [ contents := contents hex ] ] ].<br>
> page := ZnHtmlOutputStream streamContents: [ :html |<br>
> html page: 'Form Test 3' do: [<br>
> html<br>
> tag: #form<br>
> attributes: #(action
'form-test-3' 'accept-charset' 'utf-8'<br>
>
enctype 'multipart/form-data' method POST)<br>
> do: [<br>
> html<br>
> str: 'File';
space;<br>
> tag: #input
attributes: #(type file name file); space;<br>
> tag: #input
attributes: #(type submit) ];<br>
> tag: #p do: [ html str:
'filename = '; str: filename ];<br>
> tag: #p do: [ html str:
'content-type = '; str: contentType asString ];<br>
> tag: #p do: [ html str:
'contents = '; str: (contents copyFrom: 1 to: 20) asString ] ] ].<br>
> ^ ZnResponse ok: (ZnEntity html: page)</blockquote>
<br>
</body>
</html>