diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c
index 2e1a7343b..267ecb2a5 100644
--- a/polymer/eduke32/source/gameexec.c
+++ b/polymer/eduke32/source/gameexec.c
@@ -2131,12 +2131,36 @@ skip_check:
                     switch (j)
                     {
                     case STR_MAPNAME:
-                        Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name);
-                        break;
                     case STR_MAPFILENAME:
-                        Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].filename);
+                    {
+                        int32_t idx = ud.volume_number*MAXLEVELS + ud.level_number;
+                        const char *src;
+
+                        if ((unsigned)idx >= ARRAY_SIZE(MapInfo))
+                        {
+                            CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n",
+                                          ud.volume_number, ud.level_number);
+                            break;
+                        }
+
+                        src = j==STR_MAPNAME ? MapInfo[idx].name : MapInfo[idx].filename;
+                        if (src == NULL)
+                        {
+                            CON_ERRPRINTF("attempted access to %s of non-existent map (vol=%d, lev=%d)",
+                                          j==STR_MAPNAME ? "name" : "file name",
+                                          ud.volume_number, ud.level_number);
+                            break;
+                        }
+
+                        Bstrcpy(ScriptQuotes[i], j==STR_MAPNAME ? MapInfo[idx].name : MapInfo[idx].filename);
                         break;
+                    }
                     case STR_PLAYERNAME:
+                        if ((unsigned)vm.g_p >= (unsigned)playerswhenstarted)
+                        {
+                            CON_ERRPRINTF("Invalid player ID %d\n", vm.g_p);
+                            break;
+                        }
                         Bstrcpy(ScriptQuotes[i],g_player[vm.g_p].user_name);
                         break;
                     case STR_VERSION:
@@ -2147,6 +2171,11 @@ skip_check:
                         Bstrcpy(ScriptQuotes[i],GametypeNames[ud.coop]);
                         break;
                     case STR_VOLUMENAME:
+                        if ((unsigned)ud.volume_number >= MAXVOLUMES)
+                        {
+                            CON_ERRPRINTF("invalid volume (%d)\n", ud.volume_number);
+                            break;
+                        }
                         Bstrcpy(ScriptQuotes[i],EpisodeNames[ud.volume_number]);
                         break;
                     default:
diff --git a/polymer/eduke32/source/lunatic/test/qgetsysstr.con b/polymer/eduke32/source/lunatic/test/qgetsysstr.con
new file mode 100644
index 000000000..6704af483
--- /dev/null
+++ b/polymer/eduke32/source/lunatic/test/qgetsysstr.con
@@ -0,0 +1,49 @@
+
+gamevar vol 0 0
+gamevar lev 0 0
+
+// out-of-bounds volume/level numbers
+gamevar badvol_oob 99 0
+gamevar badlev_oob 999 0
+
+// volume/level numbers for which no level is defined
+gamevar badvol_nd 3 0
+gamevar badlev_nd 32 0
+
+definequote 255 <temp>
+
+onevent EVENT_ENTERLEVEL
+    // must fail, since the current player is -1 in this event
+    qgetsysstr 255 STR_PLAYERNAME
+endevent
+
+onevent EVENT_USESTEROIDS
+    getuserdef .volume_number vol
+    setuserdef .volume_number badvol_oob  // LunaCON errors here
+    qgetsysstr 255 STR_VOLUMENAME  // C-CON errors here
+    setuserdef .volume_number vol
+endevent
+
+onevent EVENT_USEJETPACK
+    getuserdef .volume_number vol
+    getuserdef .level_number lev
+
+    setuserdef .volume_number badvol_oob  // LunaCON errors here
+    setuserdef .level_number badlev_oob
+    qgetsysstr 255 STR_MAPNAME  // C-CON errors here
+
+    setuserdef .volume_number vol
+    setuserdef .level_number lev
+endevent
+
+onevent EVENT_JUMP
+    getuserdef .volume_number vol
+    getuserdef .level_number lev
+
+    setuserdef .volume_number badvol_nd
+    setuserdef .level_number badlev_nd
+    qgetsysstr 255 STR_MAPFILENAME  // LunaCON, C-CON error here
+
+    setuserdef .volume_number vol
+    setuserdef .level_number lev
+endevent