bpo-29990: Fix range checking in GB18030 decoder (#1509)

diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py
index cd102fd..fdae538 100644
--- a/Lib/test/test_codecencodings_cn.py
+++ b/Lib/test/test_codecencodings_cn.py
@@ -46,6 +46,12 @@
         ("abc\x80\x80\xc1\xc4", "ignore",  u"abc\u804a"),
         ("abc\x84\x39\x84\x39\xc1\xc4", "replace", u"abc\ufffd\u804a"),
         (u"\u30fb", "strict", "\x819\xa79"),
+        # issue29990
+        ("\xff\x30\x81\x30", "strict", None),
+        ("\x81\x30\xff\x30", "strict", None),
+        ("abc\x81\x39\xff\x39\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+        ("abc\xab\x36\xff\x30def", "replace", u'abc\ufffddef'),
+        ("abc\xbf\x38\xff\x32\xc1\xc4", "ignore", u"abc\u804a"),
     )
     has_iso10646 = True
 
diff --git a/Misc/NEWS b/Misc/NEWS
index 181edf1..5763d49 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -42,6 +42,8 @@
 Library
 -------
 
+- bpo-29990: Fix range checking in GB18030 decoder.  Original patch by Ma Lin.
+
 - bpo-30243: Removed the __init__ methods of _json's scanner and encoder.
   Misusing them could cause memory leaks or crashes.  Now scanner and encoder
   objects are completely initialized in the __new__ methods.
diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c
index 6e0d2ce..3bc652f 100644
--- a/Modules/cjkcodecs/_codecs_cn.c
+++ b/Modules/cjkcodecs/_codecs_cn.c
@@ -266,7 +266,9 @@
             REQUIRE_INBUF(4)
             c3 = IN3;
             c4 = IN4;
-            if (c < 0x81 || c3 < 0x81 || c4 < 0x30 || c4 > 0x39)
+            if (c  < 0x81 || c  > 0xFE ||
+                c3 < 0x81 || c3 > 0xFE ||
+                c4 < 0x30 || c4 > 0x39)
                 return 4;
             c -= 0x81;  c2 -= 0x30;
             c3 -= 0x81; c4 -= 0x30;