You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.9 KiB
50 lines
1.9 KiB
6 years ago
|
property ForwardUncommitted
|
||
|
message "A ServletResponse was forwarded before being committed."
|
||
|
// TODO assume InterleavedResponse_Weak
|
||
|
prefix <javax.servlet>
|
||
|
prefix <javax.servlet.{ServletOutputStream,ServletResponse}>
|
||
|
prefix <java.io.PrintWriter>
|
||
|
start -> start: *
|
||
|
start -> tracking: R = <ServletResponse.\<init\>>
|
||
|
tracking -> ok: flushBuffer(r)
|
||
|
tracking -> gotWriter: W = getWriter(r)
|
||
|
gotWriter -> ok: flush(w)
|
||
|
gotWrite -> ok: flushBuffer(r)
|
||
|
tracking -> gotStream: S = getOutputStream(r)
|
||
|
gotStream -> ok: flush(s)
|
||
|
gotStream -> ok: flushBuffer(r)
|
||
|
tracking -> error: <RequestDispatcher.forward>(*, *, r)
|
||
|
gotWriter -> error: <RequestDispatcher.forward>(*, *, r)
|
||
|
gotStream -> error: <RequestDispatcher.forward>(*, *, r)
|
||
|
|
||
|
// The documentation of ServletResponse.getOutputStream says that "either this
|
||
|
// method getWriter may be called to write to the body, not both." So,
|
||
|
// technically, the property is InterleavedResponse1. However, this property is
|
||
|
// broken, which is why we also have the weaker version InterleavedResponse2.
|
||
|
property InterleavedResponse1
|
||
|
message "A ServletResponse was asked for both a writer and a stream."
|
||
|
prefix <javax.servlet.ServletResponse>
|
||
|
start -> start: *
|
||
|
start -> gotWriter: W = getWriter(R)
|
||
|
start -> gotStream: S = getOutputStream(R)
|
||
|
gotWriter -> error: getOutputStream(r)
|
||
|
gotStream -> error: getWriter(r)
|
||
|
|
||
|
property InterleavedResponse2
|
||
|
// vertex names: w = got writer; W = used writer; similarly for s, S
|
||
|
message "Incompatible methods for putting data into a response were used."
|
||
|
prefix <javax.servlet.ServletResponse>
|
||
|
start -> start: *
|
||
|
start -> w: W = getWriter(R)
|
||
|
start -> s: S = getOutputStream(R)
|
||
|
w -> sw: S = getOutputStream(r)
|
||
|
s -> sw: W = getWriter(r)
|
||
|
w -> W: *(w)
|
||
|
sw -> sW: *(w)
|
||
|
s -> S: *(s)
|
||
|
sw -> Sw: *(s)
|
||
|
W -> sW: S = getOutputStream(r)
|
||
|
S -> Sw: W = getWriter(r)
|
||
|
sW -> error: *(s)
|
||
|
Sw -> error: *(w)
|