mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
cmd/ebitenmobile: check the Java package before an execution
Closes #2894
This commit is contained in:
parent
11394d246f
commit
5f7c7dbac6
@ -29,6 +29,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
exec "golang.org/x/sys/execabs"
|
||||
"golang.org/x/tools/go/packages"
|
||||
@ -41,15 +42,6 @@ const (
|
||||
//go:embed _files/EbitenViewController.h
|
||||
var objcH string
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
// This message is copied from `gomobile bind -h`
|
||||
fmt.Fprintf(os.Stderr, "%s bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]\n", ebitenmobileCommand)
|
||||
os.Exit(2)
|
||||
}
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func goEnv(name string) string {
|
||||
if val := os.Getenv(name); val != "" {
|
||||
return val
|
||||
@ -90,6 +82,13 @@ var (
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Usage = func() {
|
||||
// This message is copied from `gomobile bind -h`
|
||||
fmt.Fprintf(os.Stderr, "%s bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]\n", ebitenmobileCommand)
|
||||
os.Exit(2)
|
||||
}
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
if len(args) < 1 {
|
||||
flag.Usage()
|
||||
@ -134,6 +133,10 @@ func main() {
|
||||
buildLdflags += " "
|
||||
}
|
||||
buildLdflags += "-extldflags=-Wl,-soname,libgojni.so"
|
||||
|
||||
if !isValidJavaPackageName(bindJavaPkg) {
|
||||
log.Fatalf("invalid Java package name: %s", bindJavaPkg)
|
||||
}
|
||||
}
|
||||
|
||||
dir, err := prepareGomobileCommands()
|
||||
@ -296,3 +299,50 @@ var iosModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework mo
|
||||
{{end}}
|
||||
export *
|
||||
}`))
|
||||
|
||||
func isValidJavaPackageName(name string) bool {
|
||||
if name == "" {
|
||||
return false
|
||||
}
|
||||
// A Java package name consists of one or more Java identifiers separated by dots.
|
||||
for _, token := range strings.Split(name, ".") {
|
||||
if !isValidJavaIdentifier(token) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isValidJavaIdentifier reports whether the given strings is a valid Java identifier.
|
||||
func isValidJavaIdentifier(name string) bool {
|
||||
if name == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Java identifiers must not be a Java keyword.
|
||||
switch name {
|
||||
case "_", "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while":
|
||||
return false
|
||||
}
|
||||
if name == "null" || name == "true" || name == "false" {
|
||||
return false
|
||||
}
|
||||
|
||||
// References:
|
||||
// * https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html#isJavaIdentifierPart(int)
|
||||
// * https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html#isJavaIdentifierStart(int)
|
||||
|
||||
isJavaLetter := func(r rune) bool {
|
||||
return unicode.IsLetter(r) || unicode.Is(unicode.Pc, r) || unicode.Is(unicode.Sc, r)
|
||||
}
|
||||
isJavaDigit := unicode.IsDigit
|
||||
|
||||
// A Java identifier is a Java letter or Java letter followed by Java letters or Java digits.
|
||||
// https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-Identifier
|
||||
for i, r := range name {
|
||||
if !isJavaLetter(r) && (i == 0 || !isJavaDigit(r)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
76
cmd/ebitenmobile/main_test.go
Normal file
76
cmd/ebitenmobile/main_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2024 The Ebitengine Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJavaPackageName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
in string
|
||||
out bool
|
||||
}{
|
||||
{
|
||||
in: "",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: ".",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.goinovation",
|
||||
out: true,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.$goinovation",
|
||||
out: true,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi..goinovation",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.go-inovation",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.strictfp", // strictfp is a Java keyword.
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.null",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.go1inovation",
|
||||
out: true,
|
||||
},
|
||||
{
|
||||
in: "com.hajimehoshi.1goinovation",
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
in: "あ.いうえお",
|
||||
out: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
if got, want := isValidJavaPackageName(tc.in), tc.out; got != want {
|
||||
t.Errorf("isValidJavaPackageName(%q) = %v; want %v", tc.in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user