Fix #315
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 1d372a3..1251004 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -19,6 +19,8 @@
 #307: JsonGenerationException: Split surrogate on writeRaw() input thrown for
   input of a certain size
  (reported by Mike N)
+#315: `OutOfMemoryError` when writing BigDecimal
+ (reported by gmethwin@github)
 
 2.7.6 (23-Jul-2016)
 
diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
index d1b97a0..128fbcf 100644
--- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
+++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
@@ -1,6 +1,7 @@
 package com.fasterxml.jackson.core.base;
 
 import java.io.*;
+import java.math.BigDecimal;
 
 import com.fasterxml.jackson.core.*;
 import com.fasterxml.jackson.core.json.DupDetector;
@@ -41,6 +42,16 @@
     protected final static String WRITE_RAW = "write a raw (unencoded) value";
     protected final static String WRITE_STRING = "write a string";
 
+    /**
+     * This value is the limit of scale allowed for serializing {@link BigDecimal}
+     * in "plain" (non-engineering) notation; intent is to prevent asymmetric
+     * attack whereupon simple eng-notation with big scale is used to generate
+     * huge "plain" serialization. See [core#315] for details.
+     * 
+     * @since 2.7.7
+     */
+    protected final static int MAX_BIG_DECIMAL_SCALE = 9999;
+    
     /*
     /**********************************************************
     /* Configuration
@@ -414,6 +425,26 @@
         return new DefaultPrettyPrinter();
     }
 
+    /**
+     * Helper method used to serialize a {@link java.math.BigDecimal} as a String,
+     * for serialization, taking into account configuration settings
+     *
+     * @since 2.7.7
+     */
+    protected String _asString(BigDecimal value) throws IOException {
+        if (Feature.WRITE_BIGDECIMAL_AS_PLAIN.enabledIn(_features)) {
+            // 24-Aug-2016, tatu: [core#315] prevent possible DoS vector
+            int scale = value.scale();
+            if ((scale < -MAX_BIG_DECIMAL_SCALE) || (scale > MAX_BIG_DECIMAL_SCALE)) {
+                _reportError(String.format(
+"Attempt to write plain `java.math.BigDecimal` (see JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN) with illegal scale (%d): needs to be between [-%d, %d]",
+scale, MAX_BIG_DECIMAL_SCALE, MAX_BIG_DECIMAL_SCALE));
+            }
+            return value.toPlainString();
+        }
+        return value.toString();
+    }
+
     /*
     /**********************************************************
     /* UTF-8 related helper method(s)
diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
index 4d0c636..5524691 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
@@ -906,14 +906,10 @@
         _verifyValueWrite(WRITE_NUMBER);
         if (value == null) {
             _writeNull();
-        } else if (_cfgNumbersAsStrings) {
-            String raw = Feature.WRITE_BIGDECIMAL_AS_PLAIN.enabledIn(_features)
-                    ? value.toPlainString() : value.toString();
-            _writeQuotedRaw(raw);
-        } else if (Feature.WRITE_BIGDECIMAL_AS_PLAIN.enabledIn(_features)) {
-            writeRaw(value.toPlainString());
+        } else  if (_cfgNumbersAsStrings) {
+            _writeQuotedRaw(_asString(value));
         } else {
-            writeRaw(value.toString());
+            writeRaw(_asString(value));
         }
     }
 
diff --git a/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
index 316886b..2340ea2 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
@@ -683,13 +683,10 @@
         _verifyValueWrite(WRITE_NUMBER);
         if (value == null) {
             _writeNull();
-        } else if (_cfgNumbersAsStrings) {
-            String raw = isEnabled(Feature.WRITE_BIGDECIMAL_AS_PLAIN) ? value.toPlainString() : value.toString();
-            _writeQuotedRaw(raw);
-        } else if (isEnabled(Feature.WRITE_BIGDECIMAL_AS_PLAIN)) {
-            writeRaw(value.toPlainString());
+        } else  if (_cfgNumbersAsStrings) {
+            _writeQuotedRaw(_asString(value));
         } else {
-            writeRaw(value.toString());
+            writeRaw(_asString(value));
         }
     }
 
@@ -698,7 +695,7 @@
     {
         _verifyValueWrite(WRITE_NUMBER);
         if (_cfgNumbersAsStrings) {
-            _writeQuotedRaw(encodedValue);            
+            _writeQuotedRaw(encodedValue);
         } else {
             writeRaw(encodedValue);
         }
diff --git a/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java b/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
index 68b7b7b..d2f6c28 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
@@ -17,10 +17,10 @@
 
     public void testConfigDefaults() throws IOException
     {
-        JsonGenerator jg = JSON_F.createGenerator(new StringWriter());
-        assertFalse(jg.isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS));
-        assertFalse(jg.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
-        jg.close();
+        JsonGenerator g = JSON_F.createGenerator(new StringWriter());
+        assertFalse(g.isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS));
+        assertFalse(g.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
+        g.close();
     }
 
     public void testFieldNameQuoting() throws IOException
@@ -65,7 +65,7 @@
                      _writeNumbers(jf));
     }
 
-    // [Issue#85]
+    // [core#85]
     public void testBigDecimalAsPlain() throws IOException
     {
         JsonFactory jf = new JsonFactory();
@@ -85,7 +85,7 @@
         assertEquals("100", sw.toString());
     }
 
-    // [issue#184]
+    // [core#184]
     public void testBigDecimalAsPlainString() throws Exception
     {
         JsonFactory jf = new JsonFactory();
@@ -106,6 +106,61 @@
         jg.close();
         assertEquals(quote("100"), bos.toString("UTF-8"));
     }
+
+    // [core#315]
+    public void testTooBigBigDecimal() throws Exception
+    {
+        JsonFactory f = new JsonFactory();
+        f.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
+
+        // 24-Aug-2016, tatu: Initial check limits scale to [-9999,+9999]
+        BigDecimal BIG = new BigDecimal("1E+9999");
+        BigDecimal TOO_BIG = new BigDecimal("1E+10000");
+        BigDecimal SMALL = new BigDecimal("1E-9999");
+        BigDecimal TOO_SMALL = new BigDecimal("1E-10000");
+
+        for (boolean useBytes : new boolean[] { false, true } ) {
+            for (boolean asString : new boolean[] { false, true } ) {
+                JsonGenerator g;
+                
+                if (useBytes) {
+                    g = f.createGenerator(new ByteArrayOutputStream());
+                } else {
+                    g = f.createGenerator(new StringWriter());
+                }
+                if (asString) {
+                    g.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
+                }
+
+                // first, ok cases:
+                g.writeStartArray();
+                g.writeNumber(BIG);
+                g.writeNumber(SMALL);
+                g.writeEndArray();
+                g.close();
+
+                // then invalid
+                for (BigDecimal input : new BigDecimal[] { TOO_BIG, TOO_SMALL }) {
+                    if (useBytes) {
+                        g = f.createGenerator(new ByteArrayOutputStream());
+                    } else {
+                        g = f.createGenerator(new StringWriter());
+                    }
+                    if (asString) {
+                        g.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
+                    }
+                    try {
+                        g.writeNumber(input);
+                        fail("Should not have written without exception: "+input);
+                    } catch (JsonGenerationException e) {
+                        verifyException(e, "Attempt to write plain `java.math.BigDecimal`");
+                        verifyException(e, "illegal scale");
+                    }
+                    g.close();
+                }
+            }
+        }
+    }
     
     private String _writeNumbers(JsonFactory jf) throws IOException
     {