рдЧреНрд░реВрд╡реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ


рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ: рд╕реАрдпреВрдмреАрдП рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп , рд╣рдо рдЗрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡реНрдпрд╡рд╕рд╛рдп рддрд░реНрдХ рдХреЗ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд░рдЦрддреЗ рд╣реИрдВред рдЪрд╛рд╣реЗ рдпрд╣ рдЕрд╡рд╕рд░ рдЕрдЪреНрдЫрд╛ рд╣реЛ рдпрд╛ рдмреБрд░рд╛ (рдФрд░ рд╣рдо рдХреЗрд╡рд▓ рд╕реАрдпреВрдмреАрдП рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ) рдкрд░ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдмрд╣рд╕ рдЪрд▓ рд░рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рддрдереНрдп рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдХреЛрдИ рдкреНрд░рд╢реНрди рдирд╣реАрдВ рдЙрдард╛рддрд╛ рд╣реИред рдХрд╕реНрдЯрдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рдЧреНрд░реВрд╡реА рдХреА рдЙрдкрдпреЛрдЧреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ Cdric Champeau рдХреЗ рдЕрдиреБрд╡рд╛рдж рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЧреНрд░реВрд╡реА рд╡рд┐рдХрд╛рд╕ рдЯреАрдо рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛, рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХрд╛ рд╕рдореБрджрд╛рдп рдЖрдиреЗ рд╡рд╛рд▓реЗ рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдордЬрджреВрд░реЛрдВ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддрд╛ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИред


рдЧреНрд░реВрд╡реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯрд┐рдВрдЧ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЧреНрд░реВрд╡реА рдХреЛ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдХреЛрдб рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛ рд╕рдХрддреА рд╣реИрдВ: рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо, рдбреЗрдЯрд╛рдмреЗрд╕, рд░рд┐рдореЛрдЯ рд╕реЗрд╡рд╛рдПрдВ ... рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдбреЗрд╡рд▓рдкрд░ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реАрдорд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИрдВ (рд╕реАрдорд┐рдд рдореЗрдореЛрд░реА, рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рд╕реАрдорд╛, рд░рдирдЯрд╛рдЗрдо ...), рдпрд╛ рдЖрдк рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕рднреА рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред


рдпрд╣ рдкреЛрд╕реНрдЯ рдЖрдкрдХреЛ рдмрддрд╛рдПрдЧрд╛


  • рдХреНрдпреЛрдВ рдЖрдВрддрд░рд┐рдХ dsl рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП groovy рдЕрдЪреНрдЫрд╛ рд╣реИ
  • рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЗрд╕рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдХреНрдпрд╛ рд╣реИрдВ
  • рдХреИрд╕реЗ DSL рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
  • SecureASTCustomizer рдХреЗ рдореВрд▓реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
  • рдкреНрд░рдХрд╛рд░ рдирд┐рдпрдВрддреНрд░рдг рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
  • рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдХрдВрдЯреНрд░реЛрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЛ рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЧрдгрд┐рддреАрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХреЗред рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдХрд▓реНрдк рдПрдХ рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдХреЛ рдПрдореНрдмреЗрдб рдХрд░рдирд╛, рдПрдХ рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдирд╛ рдФрд░ рдЕрдВрдд рдореЗрдВ рдЗрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рджреБрднрд╛рд╖рд┐рдпрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдкрдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЛ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдмрдврд╝рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдореЗрдВ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рднрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╛рдпрдЯреЗрдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдХреЗ рдпрд╛ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдЙрддреНрдкрдиреНрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдХреИрд╢рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рддреЛ рдЧреНрд░реВрд╡реА рдПрдХ рдмрдврд╝рд┐рдпрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИред


рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╕рд┐рд░реНрдл Eval рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:


Example.java


 int sum = (Integer) Eval.me("1+1"); 

1+1 рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдЧреНрд░реВрд╡реА рджреНрд╡рд╛рд░рд╛ рд▓реЛрдб рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдмреЗрд╢рдХ, рдЗрд╕ рдирдореВрдиреЗ рдореЗрдВ рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдордирдорд╛рдирд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╡рд╣реА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдПред рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдореЗрдВ рдЖрдкрдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 1+1 x+y 1+(2*x)**y cos(alpha)*r v=1+x 

рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд╣реАрдВ


 println 'Hello' (0..100).each { println 'Blah' } Pong p = new Pong() println(new File('/etc/passwd').text) System.exit(-1) Eval.me('System.exit(-1)') // a script within a script! 

рдпрд╣ рдпрд╣рд╛рдВ рд╣реИ рдХрд┐ рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рдпрд╣ рднреА рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


  • рднрд╛рд╖рд╛ рдХреА рд╡реНрдпрд╛рдХрд░рдг рдХреЛ рдЙрд╕рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рд╕рдмрд╕реЗрдЯ рддрдХ рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИ
  • рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХреЗрдВ
  • рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХреЗрдВ

рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдбреАрдПрд╕рдПрд▓ рдХреЗ рд▓рд┐рдП, рд▓реЛрдЧ рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рдХреЛрдб рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдбреАрдПрд╕рдПрд▓ рдЗрддрдирд╛ рд╕рд░рд▓ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЧреИрд░-рдбреЗрд╡рд▓рдкрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рдХреБрдЫ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдореИрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдерд╛ред рдореИрдВрдиреЗ рдПрдХ рдЗрдВрдЬрди рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЬреЛ рднрд╛рд╖рд╛рд╡рд┐рджреЛрдВ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд┐рдд рдЧреНрд░реВрд╡реА "рд╕реНрдХреНрд░рд┐рдкреНрдЯ" рдХреЛ рдЪрд▓рд╛рдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рдереА рдХрд┐ рд╡реЗ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ рдПрдХ рдЕрдВрддрд╣реАрди рд▓реВрдк рдмрдирд╛ рд╕рдХрддреЗ рдереЗред рд╕рд░реНрд╡рд░ рдкрд░ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╕реАрдкреАрдпреВ рдХреЗ 100% рднрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдзрд╛рдЧрд╛ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдореБрдЭреЗ рдбреАрдПрд╕рдПрд▓, рдЯреВрд▓реНрд╕ рдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдЦреЛрдЬрдирд╛ рдерд╛ред


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХрдИ рд▓реЛрдЧреЛрдВ рдХреА рд╕рдорд╛рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВред рдкрд┐рдЫрд▓реЗ 4 рд╡рд░реНрд╖реЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рдмрд╣реБрдд рд╕реЗ рдРрд╕реЗ рд▓реЛрдЧреЛрдВ рд╕реЗ рдмрд╛рдд рдХреА рд╣реИ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рд╕рд╡рд╛рд▓ рд╣реИ: рдореИрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЧреНрд░реВрд╡реА рд▓рд┐рдкрд┐рдпреЛрдВ рдореЗрдВ рдмрдХрд╡рд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рдХреИрд╕реЗ рд░реЛрдХ рд╕рдХрддрд╛ рд╣реВрдВ?


рдЕрдиреБрдХреВрд▓рди рд╕рдВрдХрд▓рдХ


рдЙрд╕ рд╕рдордп, рдореЗрд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдирд╛ рдирд┐рд░реНрдгрдп рдерд╛ рдФрд░ рдореБрдЭреЗ рдкрддрд╛ рдерд╛ рдХрд┐ рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдиреЗ рднреА рдХреБрдЫ рдЗрд╕реА рддрд░рд╣ рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИред рдЕрдВрдд рдореЗрдВ, рдЧрд┐рд▓рд┐рдпреВрдо рд▓рд╛рдлреЙрд░реНрдЧ рдиреЗ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдХрд┐ рдореИрдВ рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреНрд░реВрд╡реА рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдПрдХ рддрдВрддреНрд░ рдмрдирд╛рддрд╛ рд╣реВрдВред рдпрд╣ рд╕рдВрдХрд▓рди рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЧреНрд░реВрд╡реА 1.8.0 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред


рд╕рдВрдХрд▓рди рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реИ рдЬреЛ рдЧреНрд░реВрд╡реА рд▓рд┐рдкрд┐рдпреЛрдВ рдХреА рд╕рдВрдХрд▓рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЧреНрд░реВрд╡реА рдЖрдкреВрд░реНрддрд┐:


  • рдЖрдпрд╛рдд рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдЬреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЖрдпрд╛рдд рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЖрдпрд╛рдд рд╡рд┐рд╡рд░рдг рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • Customizer AST (Abstract Syntax Tree) рдкрд░рд┐рд╡рд░реНрддрди, рдЖрдкрдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕реАрдзреЗ рдПрдПрд╕рдЯреА рд░реВрдкрд╛рдВрддрд░рдг рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
  • рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдПрдХ рднрд╛рд╖рд╛ рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдФрд░ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ

рдПрдПрд╕рдЯреА рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдореЗрд╢рди рдХреЗ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдиреЗ рдореБрдЭреЗ @ThreadInterrupt рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдореЗрд╢рди рдХреЗ рд╕рд╛рде рдЕрдВрддрд╣реАрди рд▓реВрдк рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХреА, рд▓реЗрдХрд┐рди SecureASTCustomizer рд╡рд╣ рдЪреАрдЬрд╝ рд╣реИ рдЬреЛ рд╕рдВрднрд╡рддрдГ рдЕрдзрд┐рдХрд╛рдВрд╢ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдмрд╣реБрдд рдЧрд▓рдд рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдореБрдЭреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдорд╛рдлреА рдорд╛рдВрдЧрдиреА рдЪрд╛рд╣рд┐рдПред рддрдм рдореИрдВ рдмреЗрд╣рддрд░ рдирд╛рдо рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдЖ рд╕рдХрддрд╛ рдерд╛ред "SecureASTCustomizer" рдирд╛рдо рдХрд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рдПрдПрд╕рдЯреА рд╣реИ ред рдЗрд╕ рддрдВрддреНрд░ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХреБрдЫ рдПрдПрд╕рдЯреА рдХрд╛рд░реНрдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдирд╛ рдерд╛ред рд╢реАрд░реНрд╖рдХ рдореЗрдВ "рд╕реБрд░рдХреНрд╖рд┐рдд" рд╢рдмреНрдж рдЖрдо рддреМрд░ рдкрд░ рд╢рд╛рдирджрд╛рд░ рд╣реИ, рдФрд░ рдореИрдВ рд╕рдордЭрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпреЛрдВред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬреЗрдирдХрд┐рдиреНрд╕-рдкреНрд░рд╕рд┐рджреНрдз рдХреЛрд╕реБрдХреЗ рдХрд╡рд╛рдЧреБрдЪреА рджреНрд╡рд╛рд░рд╛ рдПрдХ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рднреА рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╢реАрд░реНрд╖рдХ рд╣реИ "рдШрд╛рддрдХ рдЧреНрд░реВрд╡реА рд╕рд┐рдХреНрдпреЛрд░рдХреИрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░" ред рдФрд░ рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд╣реА рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред SecureASTCustomizer рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рднрд╛рд╖рд╛ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдирд┐рд╖реНрдкрд╛рджрди рдирд╣реАрдВред рдЕрдм рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдирд╛рдо GrammarCustomizer рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдХрдВрдкреНрдпреВрдЯрд░ рд╡рд┐рдЬреНрдЮрд╛рди рдореЗрдВ рддреАрди рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╣реИрдВ: рдХреИрд╢ рдЕрдорд╛рдиреНрдп рд╣реЛрдирд╛, рдирд╛рдореЛрдВ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдирд╛, рдФрд░ рдкреНрд░рддрд┐ рдпреВрдирд┐рдЯ рдПрдХ рддреНрд░реБрдЯрд┐ред


рдЕрдм рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрди рдХреЗ рд░реВрдк рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдЖрдкрдХрд╛ рдХрд╛рд░реНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ System.exit рдХреЛ System.exit рд╕реЗ рд░реЛрдХрдирд╛ рд╣реИред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреЙрд▓ рдХреЛ рд╡рд┐рд╢реЗрд╖ рд░рд┐рд╕реАрд╡рд░реЛрдВ рдореЗрдВ рдмреНрд▓реИрдХ рдпрд╛ рд╡реНрд╣рд╛рдЗрдЯ рд▓рд┐рд╕реНрдЯ рдмрдирд╛рдХрд░ рд╡рд░реНрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рд╕реБрд░рдХреНрд╖рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдореИрдВ рд╣рдореЗрд╢рд╛ рд╢реНрд╡реЗрдд рд╕реВрдЪреАрд╡рд╛рджрд┐рдпреЛрдВ рдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдХрдбрд╝рд╛рдИ рд╕реЗ рд░рд╛рдЬреНрдп рдХреЛ рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдП, рд▓реЗрдХрд┐рди рдЕрд╢реНрд╡реЗрдд рдирд╣реАрдВ рдЬреЛ рдХрд┐рд╕реА рднреА рдЪреАрдЬ рдХрд╛ рдирд┐рд╖реЗрдз рдХрд░рддреЗ рд╣реИрдВред рдХреНрдпреЛрдВрдХрд┐ рд╣реИрдХрд░реНрд╕ рд╣рдореЗрд╢рд╛ рд╡рд╣реА рд╕реЛрдЪрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдиреЗ рдирд╣реАрдВ рдорд╛рдирд╛ рд╣реЛрдЧрд╛ред рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред


рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ SecureASTCustomizer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЖрджрд┐рдо рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди рдХреИрд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ SecureASTCustomizer ред рдпрджреНрдпрдкрд┐ рдореИрдВ рдЙрдиреНрд╣реЗрдВ рдЧреНрд░реВрд╡реА рдореЗрдВ рд▓рд┐рдЦ рд╕рдХрддрд╛ рдерд╛, рдореИрдВ рдПрдХреАрдХрд░рдг рдХреЛрдб рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЛ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдВред


 public class Sandbox { public static void main(String[] args) { CompilerConfiguration conf = new CompilerConfiguration(); SecureASTCustomizer customizer = new SecureASTCustomizer(); customizer.setReceiversBlackList(Arrays.asList(System.class.getName())); conf.addCompilationCustomizers(customizer); GroovyShell shell = new GroovyShell(conf); Object v = shell.evaluate("System.exit(-1)"); System.out.println("Result = " +v); } } 

  1. рд╕рдВрдХрд▓рдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдмрдирд╛рдПрдБ
  2. рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдмрдирд╛рдПрдБ
  3. рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ рдХрд┐ System рдХреЙрд▓ рдХреЗ рд░рд┐рд╕реАрд╡рд░ рдХреЗ рд░реВрдк рдореЗрдВ System рд╡рд░реНрдЧ рдХреЛ рдмреНрд▓реИрдХрд▓рд┐рд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
  4. рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдЬреЛрдбрд╝реЗрдВ
  5. рд╢реЗрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдмрд╛рдВрдзреЗрдВ, рдЕрд░реНрдерд╛рдд, рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ
  6. "рдЦрд░рд╛рдм" рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдПрдБ
  7. рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ

рдпрджрд┐ рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреА:


 General error during canonicalization: Method calls not allowed on [java.lang.System] java.lang.SecurityException: Method calls not allowed on [java.lang.System] 

рдпрд╣ рдирд┐рд╖реНрдХрд░реНрд╖ рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрд╡реЗрджрди рджреНрд╡рд╛рд░рд╛ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ System рдХреНрд▓рд╛рд╕ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рд╕рдлрд▓рддрд╛! рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЕрдкрдиреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рд░рдХреНрд╖рд╛ рдХреА рд╣реИ! рд▓реЗрдХрд┐рди рдПрдХ рдорд┐рдирдЯ рд░реБрдХрд┐рдП ...


SecureASTCustomizer рд╣реИрдХ рд╣реЛ рдЧрдпрд╛ рд╣реИ!


рд╕рдВрд░рдХреНрд╖рдг, рдХрд╣рдирд╛? рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореИрдВ рдРрд╕рд╛ рдХрд░реВрдБ рддреЛ:


 def c = System c.exit(-1) 

рдпрджрд┐ рдЖрдк рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд┐рдирд╛ рдФрд░ рд╕реНрдХреНрд░реАрди рдкрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдирд┐рдХрд╛рд╕ рдХреЛрдб -1 рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ! рдХреНрдпрд╛ рд╣реБрдЖ? рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдкрд░, рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдпрд╣ рдкрд╣рдЪрд╛рдирдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рд╣реИ рдХрд┐ c.exit рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ System рд╡рд┐рдзрд┐ рдХрд╛ рдПрдХ рдХреЙрд▓ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдПрд╕рдЯреА рд╕реНрддрд░ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рдпрд╣ рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рдзрд┐ рдХреЙрд▓ c.exit(-1) , рдлрд┐рд░ рдпрд╣ рд░рд┐рд╕реАрд╡рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд╕рдлреЗрдж (рдпрд╛ рдХрд╛рд▓рд╛) рд╕реВрдЪреА рдореЗрдВ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд░рд┐рд╕реАрд╡рд░ c , рдЗрд╕ рдЪрд░ рдХреЛ def рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдФрд░ рдЗрд╕реЗ Object рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдФрд░ рд╕реБрд░рдХреНрд╖рд┐рдд AST рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рд╕реЛрдЪреЗрдВрдЧреЗ рдХрд┐ рдЪрд░ c рдХрд╛ рдкреНрд░рдХрд╛рд░ Object , System рдирд╣реАрдВ!


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдкрд░ рдмрдирд╛рдП рдЧрдП рд╡рд┐рднрд┐рдиреНрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рдиреЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЖрдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдХреБрдЫ рдЕрдЪреНрдЫреЗ рд╣реИрдВ:


 ((Object)System).exit(-1) Class.forName('java.lang.System').exit(-1) ('java.lang.System' as Class).exit(-1) import static java.lang.System.exit exit(-1) 

рдФрд░ рднреА рдмрд╣реБрдд рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЧреНрд░реВрд╡реА рдХрд╛ рдЧрддрд┐рд╢реАрд▓ рд╕реНрд╡рднрд╛рд╡ рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рдЗрди рдореБрджреНрджреЛрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдХ рд╕рдорд╛рдзрд╛рди рдореМрдЬреВрдж рд╣реИред рдПрдХ рд╡рд┐рдХрд▓реНрдк рдорд╛рдирдХ рдЬреЗрд╡реАрдПрдо рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рдмрдВрдзрдХ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдирд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдкреВрд░реА рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рддреБрд░рдВрдд рдПрдХ рднрд╛рд░реА рдФрд░ рдмрдбрд╝рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдФрд░ рдпрд╣ рдЧреМрд░реИрдпрд╛ рдкрд░ рддреЛрдк рджрд╛рдЧрдиреЗ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдкрдврд╝рдиреЗ рд╡рд╛рд▓реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдирд╣реАрдВ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВ ...


рдЗрд╕ рд╕реАрдорд╛ - рдмрд▓реНрдХрд┐ рд╣рдо рдореЗрдВ рд╕реЗ рдХрдИ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд┐рд░рд╛рдЧ - рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЪреЗрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдиреЗрддреГрддреНрд╡ рдХрд┐рдпрд╛ред рдЗрд╕ рддрд░рд╣ рдХреА рдЬрд╛рдВрдЪ рд╕реЗ рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХреА рдорд╛рдиреНрдпрддрд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрджреЗрд╢ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░рд┐рд╕реАрд╡рд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрддрд╛ рдЪрд▓ рдЬрд╛рдПрдЧрд╛ред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдмреНрдпрд╛рдЬ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ:



рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдФрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрд╕реБрдХреЗ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреИрд╢рд┐рдВрдЧ рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╣реИрдХ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЧреНрд░реВрд╡реА рдХреЗ рдЪрд╛рд▓рд╛рди рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпреЗ рдЖрдВрддрд░рд┐рдХ рд╡рд░реНрдЧ рдЧреНрд░реВрд╡реА рдХреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред рджреВрд╕рд░реА рдУрд░, рд╕рд╛рдЗрдорди рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рдПрдПрд╕рдЯреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдХрдИ рд╕рдВрднрд╛рд╡рд┐рдд рдЫрд┐рджреНрд░реЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред


рдирддреАрдЬрддрди, рдореЗрд░реЗ рджреЛрд╕реНрдд рдХреЛрд░рд┐рди рдХреНрд░рд┐рд╢реНрдЪ, рдлреЗрдмреНрд░рд┐рд╕ рдореНрд░рд╛рдЯ рдФрд░ рд╕реЗрдмрд╕реНрдЯрд┐рдпрди рдмреНрд▓реИрдВрдХ, рдФрд░ рдореИрдВрдиреЗ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдПрдХ рдирдпрд╛ рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ рддрдВрддреНрд░ рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд┐рд╕рд╕реЗ рдЗрди рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдПрдВ рдирд╣реАрдВ рд╣реЛрдВрдЧреАред рд╣рдордиреЗ рдЗрд╕реЗ рдирд╛рдЗрд╕ рдореЗрдВ рдПрдХ рд╣реИрдХрд╛рдереЙрди рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рдФрд░ рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ рдЧреНрд░реАрдЪ рд╕рдореНрдореЗрд▓рди рдореЗрдВ рд╣рдордиреЗ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рдИ ред рдпрд╣ рддрдВрддреНрд░ рдПрдПрд╕рдЯреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдФрд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЙрд▓ рд╕реЗ рдкрд╣рд▓реЗ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддрд╛ рд╣реИ, рд╡рд░реНрдЧ рдХреНрд╖реЗрддреНрд░ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдЪрд░ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИ, рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ ... рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрднреА рднреА рддреИрдпрд╛рд░ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕ рдкрд░ рдмрд╣реБрдд рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ "рдирд┐рд╣рд┐рдд" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмреБрд▓рд╛рдП рдЧрдП рддрд░реАрдХреЛрдВ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдЕрднреА рддрдХ рд╣рд▓ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд┐рд▓реНрдбрд░реЛрдВ рдореЗрдВ:


 xml { cars { // cars is a method call on an implicit this: "this".cars(...) car(make:'Renault', model: 'Clio') } } 

рдЖрдЬ рддрдХ, рдореБрдЭреЗ рдЕрднреА рднреА рдЧреНрд░реВрд╡реА рдореЗрдВ рдореЗрдЯрд╛-рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЬреЛ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдХрд┐ рдЬрдм рд░рд┐рд╕реАрд╡рд░ рдХрд┐рд╕реА рдЕрдиреНрдп рд░рд┐рд╕реАрд╡рд░ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╡рд┐рдзрд┐ рдХреЛ рдирд╣реАрдВ рдкрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд┐рдзрд┐ рдХреЙрд▓ рд╕реЗ рдкрд╣рд▓реЗ рдЖрдк рд░рд┐рд╕реАрд╡рд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдЕрдЧрд░ рдХреЙрд▓ рдкрд╛рд╕ рд╣реЛ рдЧрдпрд╛, рддреЛ рдмрд╣реБрдд рджреЗрд░ рд╣реЛ рдЪреБрдХреА рд╣реИ ...


рдФрд░ рд╣рд╛рд▓ рддрдХ рддрдХ, рдореЗрд░реЗ рдкрд╛рд╕ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрд╖реНрдЯрддрдо рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдерд╛ рдЙрд╕ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рд╕реНрдХреНрд░рд┐рдкреНрдЯ рднрд╛рд╖рд╛ рдХреЗ рдЧрддрд┐рд╢реАрд▓ рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред рд▓реЗрдХрд┐рди рдЕрдм рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рднрд╛рд╖рд╛ рдХреА рдереЛрдбрд╝реА рдЧрддрд┐рд╢реАрд▓рддрд╛ рдХрд╛ рддреНрдпрд╛рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ рддреЛ рдЖрдк рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╕реЗ рдмреЗрд╣рддрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ


рдЖрдЗрдП SecureASTCustomizer рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдкрд░ рд▓реМрдЯрддреЗ рд╣реИрдВ: рдпрд╣ рдПрдХ рдЕрдореВрд░реНрдд рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкреЗрдбрд╝ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрджреЗрд╢ рдкреНрд░рдХрд╛рд░реЛрдВ рдФрд░ рд░рд┐рд╕реАрд╡рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдЧреНрд░реВрд╡реА 2 рдХреЗ рд╕рд╛рде, рдЧреНрд░реВрд╡реА рдиреЗ рд╕рдВрдХрд▓рди рдЬреЛрдбрд╝рд╛ рд╣реИ, рдФрд░ рдЧреНрд░реВрд╡реА 2.1 рдореЗрдВ рд╣рдордиреЗ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЬреЛрдбрд╝реЗ рд╣реИрдВред


рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдПрдХ рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЪреАрдЬ рд╣реИ: рд╡реЗ рдЧреНрд░реВрд╡реА рдбреАрдПрд╕рдПрд▓ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЯрд╛рдЗрдк рдЗрдВрдЯреНрд░реИрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрдВрдкрд╛рдЗрд▓рд░ рдХреА рдорджрдж рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рдЙрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдкреАрдврд╝реА рдХреЛ рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╡реЗ рдЖрдорддреМрд░ рдкрд░ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЗрди рдПрдХреНрд╕рдЯреЗрдВрд╢рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЧреНрд░реВрд╡реА рджреНрд╡рд╛рд░рд╛ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╕реНрдерд┐рд░ рд╕рдВрдХрд▓рдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рд▓рдХреНрд╖рдг рдпрд╛ рдорд╛рд░реНрдХрдЕрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░, рдкрд╛рд░реНрд╕рд░ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЬрд╛рдБрдЪ рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдЙрд╕ рдХреЛрдб рдХреЛ рд▓реЗрдВ рдЬрд┐рд╕реЗ рд╣рдорд╛рд░реЗ рд╣реИрдХрд░ рдиреЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдереА:


((Object)System).exit(-1)


рдпрджрд┐ рдЖрдк рдЪреЗрдХ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ:


 1 compilation error: [Static type checking] - Cannot find matching method java.lang.Object#exit(java.lang.Integer). Please check if the declared type is right and if the method exists. 

рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЛрдб рдЕрдм рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реИред рдФрд░ рдЕрдЧрд░ рд╣рдо рдЗрд╕ рдХреЛрдб рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ:


 def c = System c.exit(-1) 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдЯрд╛рдЗрдк рдЪреЗрдХ, рдПрдХ рд╡рд┐рдзрд┐ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рдФрд░ groovy рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ:


 @groovy.transform.TypeChecked // or even @CompileStatic void foo() { def c = System c.exit(-1) } foo() 

рдЯрд╛рдЗрдк рдЪреЗрдХрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ рдХрд┐ System рдХреНрд▓рд╛рд╕ рд╕реЗ exit рдореЗрдердб рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рд╡реИрдз рд╣реИред рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдпрд╣рд╛рдВ рдорджрдж рдирд╣реАрдВ рдорд┐рд▓реЗрдЧреАред рд▓реЗрдХрд┐рди рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрджрд┐ рдпрд╣ рдХреЛрдб рдЯрд╛рдЗрдк рдЪреЗрдХ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рд░рд┐рд╕реАрд╡рд░ рдХреЛ рдХреЙрд▓ рдХреЛ рдЯрд╛рдЗрдк System рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рдХреЙрд▓ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред


рдЯрд╛рдЗрдк рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рд╡рд┐рд╕реНрддрд╛рд░


рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рджреЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдирдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдорджрдж рд╕реЗ "рд╕реБрд░рдХреНрд╖рд┐рдд" рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ: рдпрджрд┐ рдЖрдк рд╕реНрдереИрддрд┐рдХ рд╕рдВрдХрд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ @TypeChecked рдПрдиреЛрдЯреЗрд╢рди (рдпрд╛ @CompileStatic ) рдХреЗ рд▓рд┐рдП extensions рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрдЯ рдХрд░реЗрдВ:


 @TypeChecked(extensions=['SecureExtension1.groovy']) void foo() { def c = System c.exit(-1) } foo() 

рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕рд░реНрдЪ рдХреНрд▓рд╛рд╕рдкрд╛рде рдореЗрдВ рд╕реЛрд░реНрд╕ рдХреЛрдб рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рд╣реЛрдЧрд╛ (рдЖрдк рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░реА-рдХрдиреЗрдХреНрдЯреЗрдб рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЙрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ):


SecureExtension1.groovy


 onMethodSelection { expr, methodNode -> if (methodNode.declaringClass.name=='java.lang.System') { addStaticTypeError("Method call is not allowed!", expr) } } 

  1. рдЬрдм рдкреНрд░рдХрд╛рд░ рдЪреЗрдХрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ
  2. рдпрджрд┐ рд╡рд┐рдзрд┐ рд╡рд░реНрдЧ System
  3. рдлрд┐рд░ рдЯрд╛рдЗрдк рдХрд░реЗрдВ рдЪреЗрдХрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ

рдЖрдкрдХреЛ рдмрд╕ рдЗрддрдирд╛ рд╣реА рдЪрд╛рд╣рд┐рдП рдЕрдм рдХреЛрдб рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рдПрдБ рдФрд░ рдЖрдкрдХреЛ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА!


 /home/cchampeau/tmp/securetest.groovy: 6: [Static type checking] - Method call is not allowed! @ line 6, column 3. c.exit(-1) ^ 1 error 

рдЗрд╕ рдмрд╛рд░, рдЪреЗрдХрд░ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, c System рдХреНрд▓рд╛рд╕ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк c рдкрд╣рдЪрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдХреЙрд▓ рдХреЛ рдордирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдФрд░ рдпрд╣ рдЙрди рд╕рднреА рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдПрд╕рдЯреА рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ, рдЪреЗрдХ рд╣рд╛рд░реНрдбрдХреЛрдб рдХрд┐рдП рдЧрдП рд╣реИрдВ , рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рдмрдирд╛рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рддреЛ рдЪрд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рдХреЛ рдФрд░ рдЬрдЯрд┐рд▓ рдмрдирд╛рддреЗ рд╣реИрдВред


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд┐рд╕реА рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдбреАрдПрд╕рдПрд▓:


  • (рдХрдо рд╕реЗ рдХрдо) score рдЪрд░ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд░реЗрдЧрд╛
  • рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЧрдгрд┐рддреАрдп рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдХреЙрд▓рд┐рдВрдЧ рдХреЙрд╕ , рдПрдмреНрд╕ , ... рд╡рд┐рдзрд┐рдпреЛрдВ рд╕рд╣рд┐рдд)
  • рдЕрдиреНрдп рд╕рднреА рддрд░реАрдХреЛрдВ рд╕реЗ рдордирд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

рдирдореВрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ:


abs(cos(1+score))


рдпрд╣ рдбреАрдПрд╕рдПрд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдКрдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИ:


Sandbox.java


 CompilerConfiguration conf = new CompilerConfiguration(); ImportCustomizer customizer = new ImportCustomizer(); customizer.addStaticStars("java.lang.Math"); conf.addCompilationCustomizers(customizer); Binding binding = new Binding(); binding.setVariable("score", 2.0d); GroovyShell shell = new GroovyShell(binding,conf); Double userScore = (Double) shell.evaluate("abs(cos(1+score))"); System.out.println("userScore = " + userScore); 

  1. рдЗрдВрдкреЛрд░реНрдЯ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝рд░ рдЬреЛрдбрд╝реЗрдВ рдЬреЛ рд╕рднреА рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ рдореЗрдВ import static java.lang.Math.* рдЬреЛрдбрд╝ рджреЗрдЧрд╛
  2. рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП score рдЪрд░ рдЙрдкрд▓рдмреНрдз рдХрд░рд╛рдПрдВ
  3. рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ

рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдХреИрд╢ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╣реИрдВред рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬ рджреЗрдЦреЗрдВред


рддреЛ, рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рднреА рд╣реИрдХрд░ рдХреЛ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдо рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ @CompileStatic рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ @CompileStatic :


  • рдпрд╣ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗ
  • рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░

рдЕрдкрдиреА рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ рдореЗрдВ @CompileStatic рдПрдиреЛрдЯреЗрд╢рди рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 ASTTransformationCustomizer astcz = new ASTTransformationCustomizer(CompileStatic.class); conf.addCompilationCustomizers(astcz); 

рдЕрдм рдпрджрд┐ рдЖрдк рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:


 Script1.groovy: 1: [Static type checking] - The variable [score] is undeclared. @ line 1, column 11. abs(cos(1+score)) ^ Script1.groovy: 1: [Static type checking] - Cannot find matching method int#plus(java.lang.Object). Please check if the declared type is right and if the method exists. @ line 1, column 9. abs(cos(1+score)) ^ 2 errors 

рдХреНрдпрд╛ рд╣реБрдЖ? рдпрджрд┐ рдЖрдк рд╕рдВрдХрд▓рдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдЪрд░ "рд╕реНрдХреЛрд░" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдк рдПрдХ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ double рд╡реИрд░рд┐рдПрдмрд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕реЗ рдЖрдЙрдЯрдкреБрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ: рдЖрдк рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рджреЗ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрдХрд▓рди рдареАрдХ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ score рдЪрд░ double рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИред


рдЗрд╕рд▓рд┐рдП, рдЖрдк рдЙрд╕ рддрд░реАрдХреЗ рдХреЛ рдереЛрдбрд╝рд╛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ @CompileStatic рдПрдиреЛрдЯреЗрд╢рди @CompileStatic :


 ASTTransformationCustomizer astcz = new ASTTransformationCustomizer( singletonMap("extensions", singletonList("SecureExtension2.groovy")), CompileStatic.class); 

рдпрд╣ @CompileStatic(extensions=['SecureExtension2.groovy']) рджреНрд╡рд╛рд░рд╛ рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХрд╛ "рдЕрдиреБрдХрд░рдг" рдХрд░рддрд╛ рд╣реИред рдЕрдм, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ score рдЪрд░ рдХреЛ рдкрд╣рдЪрд╛рди рд▓реЗрдЧрд╛:


SecureExtension2.groovy


 unresolvedVariable { var -> if (var.name=='score') { return makeDynamic(var, double_TYPE) } } 

  1. рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдЪреЗрдХрд░ рдЪрд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛
  2. рдпрджрд┐ рдЪрд░ рдирд╛рдо score
  3. рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдбрд╛рдпрдиреЗрдорд┐рдХ рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк double рд╕рд╛рде рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рджреЗрдВ

рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдбреАрдПрд╕рдПрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдкреВрд░рд╛ рд╡рд┐рд╡рд░рдг рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдЗрд╕ рдЦрдВрдб рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕рдВрдпреБрдХреНрдд рд╕рдВрдХрд▓рди рдореЛрдб рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ: рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ score рдЪрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдПрдХ рдбреАрдПрд╕рдПрд▓ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЪрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ - double , рдЗрд╕рд▓рд┐рдП makeDynamic рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдпрд╣рд╛рдВ рд╣реИ: "рдареАрдХ рд╣реИ, рдЪрд┐рдВрддрд╛ рдордд рдХрд░реЛ, рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕ рдЪрд░ рдХреЛ double рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред "ред рд╡рд╣ рд╕рдм рд╣реИ!


рдкрд╣рд▓реЗ рдкреВрд░рд╛ "рд╕реБрд░рдХреНрд╖рд┐рдд" рдПрдХреНрд╕рдЯреЗрдВрд╢рди


рдЕрдм рдЗрд╕реЗ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦ рджреЗрдВред рд╣рдордиреЗ рдПрдХ рдЯрд╛рдЗрдк-рдЪреЗрдХрд┐рдВрдЧ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рдПрдХ рддрд░рдл System рдХреНрд▓рд╛рд╕ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рдХреЙрд▓ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ рдФрд░ рджреВрд╕рд░рд╛ рдЬреЛ score рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рджреВрд╕рд░реА рдУрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдкреВрд░реНрдг рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдорд┐рд▓рддрд╛ рд╣реИ:


SecureExtension3.groovy


 // disallow calls on System onMethodSelection { expr, methodNode -> if (methodNode.declaringClass.name=='java.lang.System') { addStaticTypeError("Method call is not allowed!", expr) } } // resolve the score variable unresolvedVariable { var -> if (var.name=='score') { return makeDynamic(var, double_TYPE) } } 

рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдирдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдЬрд╛рд╡рд╛ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦреЗрдВ:


 ASTTransformationCustomizer astcz = new ASTTransformationCustomizer( singletonMap("extensions", singletonList("SecureExtension3.groovy")), CompileStatic.class); 

рдХреЛрдб рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рдПрдБ - рдпрд╣ рдЕрднреА рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЕрдм рдпрд╣ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:


 abs(cos(1+score)) System.exit(-1) 

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рд╕рдВрдХрд▓рди рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рдПрдЧрд╛:


 Script1.groovy: 1: [Static type checking] - Method call is not allowed! @ line 1, column 19. abs(cos(1+score));System.exit(-1) ^ 1 error 

рдмрдзрд╛рдИ рд╣реЛ, рдЖрдкрдиреЗ рдЕрднреА рдкрд╣рд▓рд╛ рдЯрд╛рдЗрдк-рдЪреЗрдХрд┐рдВрдЧ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдХреЛ рдЪрд▓рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ!


рдмрдврд╝рд╛рдпрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдиреНрдпрд╛рд╕


рдЗрд╕рд▓рд┐рдП, рд╕рдм рдХреБрдЫ рдареАрдХ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд╣рдо System рдХреНрд▓рд╛рд╕ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рдХреЙрд▓ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирдИ рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЛ рдЬрд▓реНрдж рд╣реА рдЦреЛрдЬрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд╣рдореЗрдВ рджреБрд░реНрднрд╛рд╡рдирд╛рдкреВрд░реНрдг рдХреЛрдб рдХреЗ рд▓реЙрдиреНрдЪ рдХреЛ рд░реЛрдХрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рд╕рдм рдХреБрдЫ рд╣рд╛рд░реНрдбрдХреЛрдб рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЕрдкрдиреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЛ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдФрд░ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рдХрдард┐рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рд╕реАрдзрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рд╡рд┐рдЪрд╛рд░, рдереНрд░реЗрдбрд░реНрд╕ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдбреЗрдЯрд╛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереНрд░реЗрдб рд▓реЛрдХрд▓ рд╡реИрд░рд┐рдПрдмрд▓ (рдХрд░реНрд╡ рд╡рд┐рдзрд┐, рдпрд╕) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЪрд░ рдХреА рд╕реВрдЪреА рдХреЛ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рдмрдирд╛рдПрдВрдЧреЗред рдпрд╣ рдЬрд╛рд╡рд╛ рдХреЛрдб рдЬреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛:


Sandbox.java


 public class Sandbox { public static final String VAR_TYPES = "sandboxing.variable.types"; public static final ThreadLocal<Map<String, Object>> COMPILE_OPTIONS = new ThreadLocal<>(); public static void main(String[] args) { CompilerConfiguration conf = new CompilerConfiguration(); ImportCustomizer customizer = new ImportCustomizer(); customizer.addStaticStars("java.lang.Math"); ASTTransformationCustomizer astcz = new ASTTransformationCustomizer( singletonMap("extensions", singletonList("SecureExtension4.groovy")), CompileStatic.class); conf.addCompilationCustomizers(astcz); conf.addCompilationCustomizers(customizer); Binding binding = new Binding(); binding.setVariable("score", 2.0d); try { Map<String,ClassNode> variableTypes = new HashMap<String, ClassNode>(); variableTypes.put("score", ClassHelper.double_TYPE); Map<String,Object> options = new HashMap<String, Object>(); options.put(VAR_TYPES, variableTypes); COMPILE_OPTIONS.set(options); GroovyShell shell = new GroovyShell(binding, conf); Double userScore = (Double) shell.evaluate("abs(cos(1+score));System.exit(-1)"); System.out.println("userScore = " + userScore); } finally { COMPILE_OPTIONS.remove(); } } } 

  1. ThreadLocal ,
  2. тАФ SecureExtension4.groovy
  3. variableTypes тАФ тАЬ тЖТ тАЭ
  4. score
  5. options тАФ
  6. "variable types" VAR_TYPES
  7. thread local
  8. , , thread local

:


 import static Sandbox.* def typesOfVariables = COMPILE_OPTIONS.get()[VAR_TYPES] unresolvedVariable { var -> if (typesOfVariables[var.name]) { return makeDynamic(var, typesOfVariables[var.name]) } } 

  1. thread local
  2. , ,
  3. type checker

thread local, , type checker . , unresolvedVariable , , , type checker, . , . !


. , .



. , . , , . , System.exit , :


 java.lang.System#exit(int) 

, Java, :


 public class Sandbox { public static final String WHITELIST_PATTERNS = "sandboxing.whitelist.patterns"; // ... public static void main(String[] args) { // ... try { Map<String,ClassNode> variableTypes = new HashMap<String, ClassNode>(); variableTypes.put("score", ClassHelper.double_TYPE); Map<String,Object> options = new HashMap<String, Object>(); List<String> patterns = new ArrayList<String>(); patterns.add("java\\.lang\\.Math#"); options.put(VAR_TYPES, variableTypes); options.put(WHITELIST_PATTERNS, patterns); COMPILE_OPTIONS.set(options); GroovyShell shell = new GroovyShell(binding, conf); Double userScore = (Double) shell.evaluate("abs(cos(1+score));System.exit(-1)"); System.out.println("userScore = " + userScore); } finally { COMPILE_OPTIONS.remove(); } } } 

  1. java.lang.Math

:


 import groovy.transform.CompileStatic import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.Parameter import org.codehaus.groovy.transform.stc.ExtensionMethodNode import static Sandbox.* @CompileStatic private static String prettyPrint(ClassNode node) { node.isArray()?"${prettyPrint(node.componentType)}[]":node.toString(false) } @CompileStatic private static String toMethodDescriptor(MethodNode node) { if (node instanceof ExtensionMethodNode) { return toMethodDescriptor(node.extensionMethodNode) } def sb = new StringBuilder() sb.append(node.declaringClass.toString(false)) sb.append("#") sb.append(node.name) sb.append('(') sb.append(node.parameters.collect { Parameter it -> prettyPrint(it.originType) }.join(',')) sb.append(')') sb } def typesOfVariables = COMPILE_OPTIONS.get()[VAR_TYPES] def whiteList = COMPILE_OPTIONS.get()[WHITELIST_PATTERNS] onMethodSelection { expr, MethodNode methodNode -> def descr = toMethodDescriptor(methodNode) if (!whiteList.any { descr =~ it }) { addStaticTypeError("You tried to call a method which is not allowed, what did you expect?: $descr", expr) } } unresolvedVariable { var -> if (typesOfVariables[var.name]) { return makeDynamic(var, typesOfVariables[var.name]) } } 

  1. MethodNode
  2. thread local
  3. ,

, :


 Script1.groovy: 1: [Static type checking] - You tried to call a method which is not allowed, what did you expect?: java.lang.System#exit(int) @ line 1, column 19. abs(cos(1+score));System.exit(-1) ^ 1 error 

, ! , , . , ! , , . , ( foo.text , foo.getText() ).



, type checker' "property selection", , . , , . , , тАФ . .


SandboxingTypeCheckingExtension.groovy


 import groovy.transform.CompileStatic import org.codehaus.groovy.ast.ClassCodeVisitorSupport import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.Parameter import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys import org.codehaus.groovy.transform.stc.ExtensionMethodNode import org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport import static Sandbox.* class SandboxingTypeCheckingExtension extends GroovyTypeCheckingExtensionSupport.TypeCheckingDSL { @CompileStatic private static String prettyPrint(ClassNode node) { node.isArray()?"${prettyPrint(node.componentType)}[]":node.toString(false) } @CompileStatic private static String toMethodDescriptor(MethodNode node) { if (node instanceof ExtensionMethodNode) { return toMethodDescriptor(node.extensionMethodNode) } def sb = new StringBuilder() sb.append(node.declaringClass.toString(false)) sb.append("#") sb.append(node.name) sb.append('(') sb.append(node.parameters.collect { Parameter it -> prettyPrint(it.originType) }.join(',')) sb.append(')') sb } @Override Object run() { // Fetch white list of regular expressions of authorized method calls def whiteList = COMPILE_OPTIONS.get()[WHITELIST_PATTERNS] def typesOfVariables = COMPILE_OPTIONS.get()[VAR_TYPES] onMethodSelection { expr, MethodNode methodNode -> def descr = toMethodDescriptor(methodNode) if (!whiteList.any { descr =~ it }) { addStaticTypeError("You tried to call a method which is not allowed, what did you expect?: $descr", expr) } } unresolvedVariable { var -> if (isDynamic(var) && typesOfVariables[var.name]) { storeType(var, typesOfVariables[var.name]) handled = true } } // handling properties (like foo.text) is harder because the type checking extension // does not provide a specific hook for this. Harder, but not impossible! afterVisitMethod { methodNode -> def visitor = new PropertyExpressionChecker(context.source, whiteList) visitor.visitMethod(methodNode) } } private class PropertyExpressionChecker extends ClassCodeVisitorSupport { private final SourceUnit unit private final List<String> whiteList PropertyExpressionChecker(final SourceUnit unit, final List<String> whiteList) { this.unit = unit this.whiteList = whiteList } @Override protected SourceUnit getSourceUnit() { unit } @Override void visitPropertyExpression(final PropertyExpression expression) { super.visitPropertyExpression(expression) ClassNode owner = expression.objectExpression.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER) if (owner) { if (expression.spreadSafe && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(owner, classNodeFor(Collection))) { owner = typeCheckingVisitor.inferComponentType(owner, ClassHelper.int_TYPE) } def descr = "${prettyPrint(owner)}#${expression.propertyAsString}" if (!whiteList.any { descr =~ it }) { addStaticTypeError("Property is not allowed: $descr", expression) } } } } }```     sandbox',     assert' ,  ,     : ``Sandbox.java`` ```java public class Sandbox { public static final String WHITELIST_PATTERNS = "sandboxing.whitelist.patterns"; public static final String VAR_TYPES = "sandboxing.variable.types"; public static final ThreadLocal<Map<String, Object>> COMPILE_OPTIONS = new ThreadLocal<Map<String, Object>>(); public static void main(String[] args) { CompilerConfiguration conf = new CompilerConfiguration(); ImportCustomizer customizer = new ImportCustomizer(); customizer.addStaticStars("java.lang.Math"); ASTTransformationCustomizer astcz = new ASTTransformationCustomizer( singletonMap("extensions", singletonList("SandboxingTypeCheckingExtension.groovy")), CompileStatic.class); conf.addCompilationCustomizers(astcz); conf.addCompilationCustomizers(customizer); Binding binding = new Binding(); binding.setVariable("score", 2.0d); try { Map<String, ClassNode> variableTypes = new HashMap<String, ClassNode>(); variableTypes.put("score", ClassHelper.double_TYPE); Map<String, Object> options = new HashMap<String, Object>(); List<String> patterns = new ArrayList<String>(); // allow method calls on Math patterns.add("java\\.lang\\.Math#"); // allow constructors calls on File patterns.add("File#<init>"); // because we let the user call each/times/... patterns.add("org\\.codehaus\\.groovy\\.runtime\\.DefaultGroovyMethods"); options.put(VAR_TYPES, variableTypes); options.put(WHITELIST_PATTERNS, patterns); COMPILE_OPTIONS.set(options); GroovyShell shell = new GroovyShell(binding, conf); Object result; try { result = shell.evaluate("Eval.me('1')"); // error assert false; } catch (MultipleCompilationErrorsException e) { System.out.println("Successful sandboxing: "+e.getMessage()); } try { result = shell.evaluate("System.exit(-1)"); // error assert false; } catch (MultipleCompilationErrorsException e) { System.out.println("Successful sandboxing: "+e.getMessage()); } try { result = shell.evaluate("((Object)Eval).me('1')"); // error assert false; } catch (MultipleCompilationErrorsException e) { System.out.println("Successful sandboxing: "+e.getMessage()); } try { result = shell.evaluate("new File('/etc/passwd').getText()"); // getText is not allowed assert false; } catch (MultipleCompilationErrorsException e) { System.out.println("Successful sandboxing: "+e.getMessage()); } try { result = shell.evaluate("new File('/etc/passwd').text"); // getText is not allowed assert false; } catch (MultipleCompilationErrorsException e) { System.out.println("Successful sandboxing: "+e.getMessage()); } Double userScore = (Double) shell.evaluate("abs(cos(1+score))"); System.out.println("userScore = " + userScore); } finally { COMPILE_OPTIONS.remove(); } } } 

рдирд┐рд╖реНрдХрд░реНрд╖


Groovy JVM. , . , , , . , Groovy, sandboxing' (, , ).


, , . , . , , .


, sandboxing', , тАФ SecureASTCustomizer . , , : secure AST customizer , (, ), ( , ).


, : , , . Groovy . Groovy, , - pull request, - !

Source: https://habr.com/ru/post/hi445114/


All Articles