33var assert = require ( 'assert' )
44var express = require ( '../' )
55 , request = require ( 'supertest' ) ;
6+ var qs = require ( 'qs' ) ;
67
78describe ( 'req' , function ( ) {
89 describe ( '.query' , function ( ) {
@@ -38,6 +39,22 @@ describe('req', function(){
3839 . get ( '/?user.name=tj' )
3940 . expect ( 200 , '{"user.name":"tj"}' , done ) ;
4041 } ) ;
42+
43+ it ( 'should not be able to access object prototype properties' , function ( done ) {
44+ var app = createApp ( 'extended' , true ) ;
45+
46+ request ( app )
47+ . get ( '/?foo=yee' )
48+ . expect ( 200 , / T y p e E r r o r : r e q \. q u e r y \. h a s O w n P r o p e r t y i s n o t a f u n c t i o n / , done ) ;
49+ } ) ;
50+
51+ it ( 'should be able to use object prototype property names as keys' , function ( done ) {
52+ var app = createApp ( 'extended' , true ) ;
53+
54+ request ( app )
55+ . get ( '/?hasOwnProperty=yee' )
56+ . expect ( 200 , '{"query":{"hasOwnProperty":"yee"},"error":"TypeError: req.query.hasOwnProperty is not a function"}' , done ) ;
57+ } ) ;
4158 } ) ;
4259
4360 describe ( 'when "query parser" is simple' , function ( ) {
@@ -48,6 +65,22 @@ describe('req', function(){
4865 . get ( '/?user%5Bname%5D=tj' )
4966 . expect ( 200 , '{"user[name]":"tj"}' , done ) ;
5067 } ) ;
68+
69+ it ( 'should not be able to access object prototype properties' , function ( done ) {
70+ var app = createApp ( 'simple' , true ) ;
71+
72+ request ( app )
73+ . get ( '/?foo=yee' )
74+ . expect ( 200 , / T y p e E r r o r : r e q \. q u e r y \. h a s O w n P r o p e r t y i s n o t a f u n c t i o n / , done ) ;
75+ } ) ;
76+
77+ it ( 'should be able to use object prototype property names as keys' , function ( done ) {
78+ var app = createApp ( 'simple' , true ) ;
79+
80+ request ( app )
81+ . get ( '/?hasOwnProperty=yee' )
82+ . expect ( 200 , '{"query":{"hasOwnProperty":"yee"},"error":"TypeError: req.query.hasOwnProperty is not a function"}' , done ) ;
83+ } ) ;
5184 } ) ;
5285
5386 describe ( 'when "query parser" is a function' , function ( ) {
@@ -60,6 +93,18 @@ describe('req', function(){
6093 . get ( '/?user%5Bname%5D=tj' )
6194 . expect ( 200 , '{"length":17}' , done ) ;
6295 } ) ;
96+
97+ // test exists to verify behavior for folks wishing to workaround our qs defaults
98+ it ( 'should drop object prototype property names and be able to access object prototype properties' , function ( done ) {
99+ var app = createApp (
100+ function ( str ) {
101+ return qs . parse ( str )
102+ } , true ) ;
103+
104+ request ( app )
105+ . get ( '/?hasOwnProperty=biscuits' )
106+ . expect ( 200 , '{"query":{},"hasOwnProperty":false}' , done ) ;
107+ } ) ;
63108 } ) ;
64109
65110 describe ( 'when "query parser" disabled' , function ( ) {
@@ -70,6 +115,22 @@ describe('req', function(){
70115 . get ( '/?user%5Bname%5D=tj' )
71116 . expect ( 200 , '{}' , done ) ;
72117 } ) ;
118+
119+ it ( 'should not be able to access object prototype properties' , function ( done ) {
120+ var app = createApp ( 'extended' , true ) ;
121+
122+ request ( app )
123+ . get ( '/?foo=yee' )
124+ . expect ( 200 , / T y p e E r r o r : r e q \. q u e r y \. h a s O w n P r o p e r t y i s n o t a f u n c t i o n / , done ) ;
125+ } ) ;
126+
127+ it ( 'should be able to use object prototype property names as keys' , function ( done ) {
128+ var app = createApp ( 'extended' , true ) ;
129+
130+ request ( app )
131+ . get ( '/?hasOwnProperty=yee' )
132+ . expect ( 200 , '{"query":{"hasOwnProperty":"yee"},"error":"TypeError: req.query.hasOwnProperty is not a function"}' , done ) ;
133+ } ) ;
73134 } ) ;
74135
75136 describe ( 'when "query parser" enabled' , function ( ) {
@@ -80,6 +141,22 @@ describe('req', function(){
80141 . get ( '/?user%5Bname%5D=tj' )
81142 . expect ( 200 , '{"user[name]":"tj"}' , done ) ;
82143 } ) ;
144+
145+ it ( 'should not be able to access object prototype properties' , function ( done ) {
146+ var app = createApp ( 'extended' , true ) ;
147+
148+ request ( app )
149+ . get ( '/?foo=yee' )
150+ . expect ( 200 , / T y p e E r r o r : r e q \. q u e r y \. h a s O w n P r o p e r t y i s n o t a f u n c t i o n / , done ) ;
151+ } ) ;
152+
153+ it ( 'should be able to use object prototype property names as keys' , function ( done ) {
154+ var app = createApp ( 'extended' , true ) ;
155+
156+ request ( app )
157+ . get ( '/?hasOwnProperty=yee' )
158+ . expect ( 200 , '{"query":{"hasOwnProperty":"yee"},"error":"TypeError: req.query.hasOwnProperty is not a function"}' , done ) ;
159+ } ) ;
83160 } ) ;
84161
85162 describe ( 'when "query parser fn" is missing' , function ( ) {
@@ -97,6 +174,22 @@ describe('req', function(){
97174 . get ( '/?user[name]=tj&user.name=tj' )
98175 . expect ( 200 , '{"user":{"name":"tj"},"user.name":"tj"}' , done ) ;
99176 } ) ;
177+
178+ it ( 'should not be able to access object prototype properties' , function ( done ) {
179+ var app = createApp ( 'extended' , true ) ;
180+
181+ request ( app )
182+ . get ( '/?foo=yee' )
183+ . expect ( 200 , / T y p e E r r o r : r e q \. q u e r y \. h a s O w n P r o p e r t y i s n o t a f u n c t i o n / , done ) ;
184+ } ) ;
185+
186+ it ( 'should be able to use object prototype property names as keys' , function ( done ) {
187+ var app = createApp ( 'extended' , true ) ;
188+
189+ request ( app )
190+ . get ( '/?hasOwnProperty=yee' )
191+ . expect ( 200 , '{"query":{"hasOwnProperty":"yee"},"error":"TypeError: req.query.hasOwnProperty is not a function"}' , done ) ;
192+ } ) ;
100193 } ) ;
101194
102195 describe ( 'when "query parser" an unknown value' , function ( ) {
@@ -108,15 +201,25 @@ describe('req', function(){
108201 } )
109202} )
110203
111- function createApp ( setting ) {
204+ function createApp ( setting , isPrototypePropertyTest ) {
112205 var app = express ( ) ;
113206
114207 if ( setting !== undefined ) {
115208 app . set ( 'query parser' , setting ) ;
116209 }
117210
118211 app . use ( function ( req , res ) {
119- res . send ( req . query ) ;
212+ if ( isPrototypePropertyTest ) {
213+ try {
214+ var hasOwnProperty = req . query . hasOwnProperty ( '✨ express ✨' ) ;
215+ res . send ( { query : req . query , hasOwnProperty : hasOwnProperty } ) ;
216+ } catch ( error ) {
217+ res . send ( { query : req . query , error : error . toString ( ) } ) ;
218+ }
219+ }
220+ else {
221+ res . send ( req . query ) ;
222+ }
120223 } ) ;
121224
122225 return app ;
0 commit comments