Repository: cloudspannerecosystem/harbourbridge
Pull request #133 (2021-05-25 13:04:15)

#132: fix nil-pointer dereference crash on startup
We don't initialize sessionState.conv on harbourbridge startup. Normally this isn't an issue because the standard web ui workflows will set it appropriately before it is accessed. However, if pages are accessed out of order, we can, for example, call getDDL with sessionState.conv set to nil and crash.

The fix is to initialize sessionState.conv in the web.go init function -- it is initialized to a valid (but empty) conv struct.


Patch:
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index cc165db..2112086 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -16,7 +16,7 @@
                 "datatables.net": "^1.10.24",
                 "jest": "^26.6.3",
                 "jest-esm-transformer": "^1.0.0",
-                "jquery": "^1.7.4"
+                "jquery": "^3.5.0"
             }
         },
         "node_modules/@babel/code-frame": {
@@ -3934,9 +3934,9 @@
             }
         },
         "node_modules/jquery": {
-            "version": "1.12.4",
-            "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz",
-            "integrity": "sha1-AeHfuikP5z3rp3zurLD5ui/sngw=",
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
+            "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==",
             "dev": true
         },
         "node_modules/js-tokens": {
@@ -10150,9 +10150,9 @@
             }
         },
         "jquery": {
-            "version": "1.12.4",
-            "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz",
-            "integrity": "sha1-AeHfuikP5z3rp3zurLD5ui/sngw=",
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
+            "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==",
             "dev": true
         },
         "js-tokens": {
diff --git a/frontend/package.json b/frontend/package.json
index abcca69..5b80aaa 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,7 +14,7 @@
         "datatables.net": "^1.10.24",
         "jest": "^26.6.3",
         "jest-esm-transformer": "^1.0.0",
-        "jquery": "^1.7.4"
+        "jquery": "^3.5.0"
     },
     "jest": {
         "transform": {
diff --git a/web/web.go b/web/web.go
index ec2d3c1..f4f81da 100644
--- a/web/web.go
+++ b/web/web.go
@@ -1169,6 +1169,7 @@ func init() {
 		}
 		postgresTypeMap[srcType] = l
 	}
+	sessionState.conv = internal.MakeConv()
 }
 
 func WebApp() {


Test patch:
diff --git a/web/web_startup_test.go b/web/web_startup_test.go
new file mode 100644
index 0000000..50b3b23
--- /dev/null
+++ b/web/web_startup_test.go
@@ -0,0 +1,38 @@
+// Copyright 2020 Google LLC
+//
+// 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 web
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+)
+
+// Test robustness of API calls on startup.
+// See https://github.com/cloudspannerecosystem/harbourbridge/issues/132.
+// Note that this test has to be in a standalone test file.
+func TestDdlOnStartup(t *testing.T) {
+	req, err := http.NewRequest("GET", "/ddl", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	rr := httptest.NewRecorder()
+	handler := http.HandlerFunc(getDDL)
+	handler.ServeHTTP(rr, req)
+	if status := rr.Code; status != http.StatusOK {
+		t.Errorf("handler returned wrong status code: got %v want %v",
+			status, http.StatusOK)
+	}
+}