[Seaside] WAUrl class>>#decodePercent:
jtuchel at objektfabrik.de
jtuchel at objektfabrik.de
Thu Aug 29 05:46:07 UTC 2013
Hi Philippe,
please find the stacktrace attached. As I mentioned, I am on VA ST, so
don't be surprised if the trace looks a bit different.
What is happening is that Seaside receives an Ajax request with one of
its parameters containing the String 'test%'.
The String has not been URI encoded or anything in the Javascript code,
it was just retrieved from a text input field using its .val() method.
Removing $% from the string before sending an Ajax request solves the
problem.
encodeURI() would solve it as well, but that brings up a new problem,
because the String received at the server side then is encoded and has
to be decoded before it can be processed. AFAIK, VAST cannot do that yet
- which is another story...
You may argue that it is never a good idea to not encode Ajax
parameters, and I have a hard time finding counter arguments. But I
think the way the error shows up in the end (reading beyond the end of
the input stream) is misleading.
So as Johan already said, maybe the only way to improve things here is
to throw a better exception.
I hope I could clarify the point with this message. Please feel free to
ask if you need more information
Joachim
Am 27.08.13 18:34, schrieb Philippe Marschall:
> On Thu, Aug 22, 2013 at 7:26 AM, jtuchel at objektfabrik.de
> <jtuchel at objektfabrik.de> wrote:
>> Hi,
>>
>> I just stumbled across a problem when processing an Ajax callback for a
>> specialized autocompleter. I get a server side "Index out of range" if I
>> enter a String ending with $% into the textInput (which I have to supress
>> anyways, but that is another story).
>>
>> The problem is in WAUrl class>>#decodePercent: . the method doesn't check if
>> the percent character is the last in the url string.
>>
>> You can recreate the problem by evaluating
>>
>> WAUrl decodePercent: 'abc%'
>>
>> Please note that in Pharo 2.0 I get another exception (receiver of
>> asUpppercase is nil), but still this doesn't work. So I guess my code ( I am
>> using VA Smalltalk and its older version of Seaside) would also fail on the
>> current stable Seaside version.
> Sorry I somehow missed this thread. Who is sending #decodePercent: to
> WAUrl message? Can you provide a stack trace?
>
> Cheers
> Philippe
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
--
--
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel mailto:jtuchel at objektfabrik.de
Fliederweg 1 http://www.objektfabrik.de
D-71640 Ludwigsburg http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
-------------- next part --------------
Debugger Stack Trace Report:
Error String: '(ExCLDTIndexOutOfRange) Index out of range.'
Resumable: false
Process
Name: Dispatch worker: 195525
Process State: suspended
Priority: 3
Executing in: WAUrl>>#parseQuery:
System Configuration Dump
Copyright:
VA Smalltalk V8.5.2; Image: 8.5.2 [232]
VM Timestamp: 4.0,(NC) 8/7/2012 (84)
(C) Copyright Instantiations 1994, 2012. All rights reserved.
(C) Copyright International Business Machines Corp. 1994, 2006. All rights reserved.
Time: 07:33:35
Date: 29.08.2013
Platform:
Virtual machine: ES
Bytecode version: 4.0
Manager version: 4.00
'OS' subsystem: 'WIN32s'
'CLIM' subsystem: 'ES'
'CP' subsystem: 'WIN32s'
'CLDT' subsystem: 'ES'
'CFS' subsystem: 'WIN32s'
'SCI' subsystem: 'WIN'
'CW' subsystem: 'WIN32s'
'CPM' subsystem: 'ES'
'CG' subsystem: 'WIN32s'
'CPIC' subsystem: 'WIN32s'
Current user: Joachim Tuchel
Connected Library:
Pathname:
Library version: 6
Size of library: 266785184 bytes
Has consistent EOF: true
Acquire read locks: false
Single user mode: false
Server address: '192.168.xx.xx'
Library Access:
Host system name: None
Use release lock mode: true
Native primitives library:
Emsrv primitives library:
Memory:
Total allocation: 78278020 bytes
Available: 1063868 bytes
Fixed Space: 35360 bytes
New Space: 144784 bytes
Old Space: 918472 bytes
=============<STACK TRACE BEGINS>============
[] in <optimized block>(ExceptionalEvent class)>>#initializeSystemExceptions
signal=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
Signal>>#evaluate:
self=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
aBlock=[] in ExceptionalEvent class>>#initializeSystemExceptions
Signal>>#evaluateDefaultHandler:
self=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
aBlock=[] in ExceptionalEvent class>>#initializeSystemExceptions
ExceptionalEvent>>#applyDefaultHandler:
self=Exception: (ExCLDTIndexOutOfRange) Index out of range.
aSignal=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
exception=Exception: (ExCLDTIndexOutOfRange) Index out of range.
Signal>>#handlesByDefault
self=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
[] in BlockContextTemplate(Block)>>#when:do:exitWith:retryReturn:
self=[] in SstHttpInvokerServlet>>#service:
exception=Exception: (ExSstHttpRequestError) A servlet request error has occurred.
handlerBlock=[] in SstHttpInvokerServlet>>#service:
exitBlock=[] in Block>>#when:do:
knownResult=an Object
retryBlock=[] in Block>>#when:do:exitWith:retryReturn:
handler=[] in Block>>#when:do:exitWith:retryReturn:
oldHandler=nil
signal=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
ExceptionalEvent>>#signalFor:
self=Exception: (ExCLDTIndexOutOfRange) Index out of range.
aSignalOrExceptionSelector=Signal on Exception: (ExCLDTIndexOutOfRange) Index out of range.
handler=[] in Block>>#when:do:exitWith:retryReturn:
ExceptionalEvent>>#signalWithArguments:
self=Exception: (ExCLDTIndexOutOfRange) Index out of range.
arguments=()
ExceptionalEvent>>#signal
self=Exception: (ExCLDTIndexOutOfRange) Index out of range.
ReadStream>>#next
self=a ReadStream
WAUrl class>>#decodePercent:
self=WAUrl
aString='test%'
input=a ReadStream
output=a WriteStream
char=$%
value -> 37 (16r25)
isLowercase -> false
isUppercase -> false
isDigit -> false
isLetter -> false
isPunctuation -> true
isSeparator -> false
WAUrl>>#decode:
self=/?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-
aString='test%'
WAUrl>>#parseQuery:
self=/?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-
aString='_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-&19=test%'
input=a ReadStream
string='19=test%'
index=3
WAUrl>>#initializeFromString:
self=/?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-
aString='/kontolino?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-&19=test%'
string='/kontolino?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-&19=test%'
index=13
WAUrl class>>#absolute:
self=WAUrl
aString='/kontolino?_s=t0JuC1crW9NO2Bw5&_k=8qoE8Ph8YOUaO2a-&19=test%'
WASstServerAdaptor(WASstRequestConverter)>>#requestUrlFor:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
WASstServerAdaptor(WAServerAdaptor)>>#requestFor:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
WASstServerAdaptor(WAServerAdaptor)>>#contextFor:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
WASstServerAdaptor(WAServerAdaptor)>>#process:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
context=nil
[] in WASstServerAdaptor>>#process:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
response=nil
WASstServerAdaptor>>#process:
self=a WASstServerAdaptor
aNativeRequest=a SstHttpServletRequest
response=nil
WASstHttpServlet>>#doGet:
self=a WASstHttpServlet
message=a SstHttpServletRequest
response=nil
[] in WASstHttpServlet(SstHttpServlet)>>#service:
self=a WASstHttpServlet
message=a SstHttpServletRequest
selector=#doGet:
LookupTable>>#at:ifPresent:
self=LookupTable(#doOptions: #doHead: #doDelete: #doGet: #doPost: #doPut: #doTrace: )
aKey='GET'
aBlock=[] in SstHttpServlet>>#service:
hashIndex=14
element='GET'
elementsSize=22
index=14
WASstHttpServlet(SstHttpServlet)>>#service:
self=a WASstHttpServlet
message=a SstHttpServletRequest
SstHttpInvokerServlet>>#basicService:
self=a SstHttpInvokerServlet
request=a SstHttpServletRequest
servlet=a WASstHttpServlet
[] in SstHttpInvokerServlet>>#service:
self=a SstHttpInvokerServlet
request=a SstHttpServletRequest
BlockContextTemplate(Block)>>#valueWithErrorHandler:oldHandler:onReturnDo:
self=[] in SstHttpInvokerServlet>>#service:
handler=[] in Block>>#when:do:exitWith:retryReturn:
oldHandler=nil
completionBlock=[]
BlockContextTemplate(Block)>>#when:do:exitWith:retryReturn:
self=[] in SstHttpInvokerServlet>>#service:
exception=Exception: (ExSstHttpRequestError) A servlet request error has occurred.
handlerBlock=[] in SstHttpInvokerServlet>>#service:
exitBlock=[] in Block>>#when:do:
knownResult=an Object
retryBlock=[] in Block>>#when:do:exitWith:retryReturn:
handler=[] in Block>>#when:do:exitWith:retryReturn:
oldHandler=nil
BlockContextTemplate(Block)>>#when:do:
self=[] in SstHttpInvokerServlet>>#service:
exception=Exception: (ExSstHttpRequestError) A servlet request error has occurred.
handlerBlock=[] in SstHttpInvokerServlet>>#service:
knownResult=an Object
result=nil
SstHttpInvokerServlet>>#service:
self=a SstHttpInvokerServlet
request=a SstHttpServletRequest
WASstHttpServletEngine(SstHttpServletEngine)>>#basicProcessRequest:
self=a WASstHttpServletEngine
servletRequest=a SstHttpServletRequest
responseContent=nil
responseMessage=false
WASstHttpServletEngine(SstBasicServer)>>#processClientRequest:
self=a WASstHttpServletEngine
request=a SstHttpServletRequest
context=a SstServletContext
sessionManager=a SstHttpSessionManager
result=nil
WASstHttpServletEngine(SstHttpServer)>>#processClientRequest:
self=a WASstHttpServletEngine
request=a SstHttpServletRequest
response=nil
WASstHttpServletEngine(SstHttpServletEngine)>>#processClientRequest:
self=a WASstHttpServletEngine
request=a SstByteMessage
WASstHttpServletEngine(SstBasicServer)>>#processRequest:
self=a WASstHttpServletEngine
request=a SstByteMessage
SstRequest(DirectedMessage)>>#send
self=SstRequest (a WASstHttpServletEngine, #processRequest:, (a SstByteMessage))
[] in SstPooledDispatcher(SstDispatcher)>>#basicExecuteRequest:
self=a SstPooledDispatcher
request=SstRequest (a WASstHttpServletEngine, #processRequest:, (a SstByteMessage))
sstTag=#SstTag:Execute
savedRequest=nil
oldErrorHandler=nil
SstPooledDispatcher(SstDispatcher)>>#basicExecuteRequest:
self=a SstPooledDispatcher
request=SstRequest (a WASstHttpServletEngine, #processRequest:, (a SstByteMessage))
sstTag=#SstTag:Execute
savedRequest=nil
oldErrorHandler=nil
SstPooledDispatcher(SstDispatcher)>>#dispatchRequest:
self=a SstPooledDispatcher
request=SstRequest (a WASstHttpServletEngine, #processRequest:, (a SstByteMessage))
result=SstInvocationHandler(http://:8080/)
[] in SstPooledDispatcher>>#dispatchRequest:
self=a SstPooledDispatcher
request=SstRequest (a WASstHttpServletEngine, #processRequest:, (a SstByteMessage))
[] in SstWorkerManager>>#blockFor:forWorker:
self=a SstWorkerManager
workBlock=[] in SstPooledDispatcher>>#dispatchRequest:
worker=SstWorker(Dispatch worker: 195525; occupied)
[] in SstWorker>>#workBlock
self=SstWorker(Dispatch worker: 195525; occupied)
current=[] in SstWorkerManager>>#blockFor:forWorker:
[] in Process>>#executeBlock:withArguments:
self=Process:Dispatch worker: 195525{suspended,3}
aBlock=[] in SstWorker>>#workBlock
args=()
Process>>#executeBlock:withArguments:
self=Process:Dispatch worker: 195525{suspended,3}
aBlock=[] in SstWorker>>#workBlock
args=()
Process>>#newProcessOn:stackSize:withArguments:named:
self=Process:Dispatch worker: 195525{suspended,3}
aBlock=[] in SstWorker>>#workBlock
stackSize=1024
args=()
procName='195525'
==============<STACK TRACE ENDS>=============
More information about the seaside
mailing list