@@ -288,7 +288,25 @@ func rangeVars(root nodes.Node) []nodes.RangeVar {
288288 return vars
289289}
290290
291- // TODO: Validate metadata
291+ // A query name must be a valid Go identifier
292+ //
293+ // https://golang.org/ref/spec#Identifiers
294+ func validateQueryName (name string ) error {
295+ if len (name ) == 0 {
296+ return fmt .Errorf ("invalid query name: %q" , name )
297+ }
298+ for i , c := range name {
299+ isLetter := unicode .IsLetter (c ) || c == '_'
300+ isDigit := unicode .IsDigit (c )
301+ if i == 0 && ! isLetter {
302+ return fmt .Errorf ("invalid query name: %q" , name )
303+ } else if ! (isLetter || isDigit ) {
304+ return fmt .Errorf ("invalid query name: %q" , name )
305+ }
306+ }
307+ return nil
308+ }
309+
292310func parseMetadata (t string ) (string , string , error ) {
293311 for _ , line := range strings .Split (t , "\n " ) {
294312 if ! strings .HasPrefix (line , "-- name:" ) {
@@ -301,13 +319,17 @@ func parseMetadata(t string) (string, string, error) {
301319 if len (part ) != 4 {
302320 return "" , "" , fmt .Errorf ("invalid query comment: %s" , line )
303321 }
322+ queryName := part [2 ]
304323 queryType := strings .TrimSpace (part [3 ])
305324 switch queryType {
306325 case ":one" , ":many" , ":exec" , ":execrows" :
307326 default :
308327 return "" , "" , fmt .Errorf ("invalid query type: %s" , queryType )
309328 }
310- return part [2 ], strings .TrimSpace (part [3 ]), nil
329+ if err := validateQueryName (queryName ); err != nil {
330+ return "" , "" , err
331+ }
332+ return queryName , queryType , nil
311333 }
312334 return "" , "" , nil
313335}
0 commit comments