@@ -292,26 +292,38 @@ func TestSinksRubyProject(t *testing.T) {
292292 sr := engine .Sinks (r )
293293
294294 if len (sr .Sinks ) == 0 {
295- t .Fatal ("expected sinks from Ruby language def " )
295+ t .Fatal ("expected sinks from detected tools " )
296296 }
297297
298- // All sinks in this fixture come from Ruby (only ruby/language.toml has sinks).
299- bySymbol := make (map [string ]brief.SinkEntry )
298+ // Index by tool+symbol since multiple tools can have a sink with the same name.
299+ type key struct { tool , symbol string }
300+ idx := make (map [key ]brief.SinkEntry )
300301 for _ , s := range sr .Sinks {
301- if s .Tool != "Ruby" {
302- t .Errorf ("unexpected sink from %q: %v" , s .Tool , s )
303- }
304- bySymbol [s .Symbol ] = s
302+ idx [key {s .Tool , s .Symbol }] = s
305303 }
306304
307- if e , ok := bySymbol ["eval" ]; ! ok {
308- t .Error ("expected eval sink" )
305+ // Ruby stdlib sinks
306+ if e , ok := idx [key {"Ruby" , "eval" }]; ! ok {
307+ t .Error ("expected Ruby eval sink" )
309308 } else if e .Threat != "code_injection" || e .CWE != "CWE-95" {
310- t .Errorf ("eval sink = %+v" , e )
309+ t .Errorf ("Ruby eval sink = %+v" , e )
310+ }
311+ if _ , ok := idx [key {"Ruby" , "Marshal.load" }]; ! ok {
312+ t .Error ("expected Ruby Marshal.load sink" )
313+ }
314+
315+ // Rails framework sinks
316+ if e , ok := idx [key {"Rails" , "html_safe" }]; ! ok {
317+ t .Error ("expected Rails html_safe sink" )
318+ } else if e .Threat != "xss" {
319+ t .Errorf ("Rails html_safe threat = %q, want xss" , e .Threat )
311320 }
312321
313- if _ , ok := bySymbol ["Marshal.load" ]; ! ok {
314- t .Error ("expected Marshal.load sink" )
322+ // ActiveRecord ORM sinks
323+ if e , ok := idx [key {"ActiveRecord" , "find_by_sql" }]; ! ok {
324+ t .Error ("expected ActiveRecord find_by_sql sink" )
325+ } else if e .Threat != "sql_injection" {
326+ t .Errorf ("ActiveRecord find_by_sql threat = %q, want sql_injection" , e .Threat )
315327 }
316328}
317329
0 commit comments