1 /*
   2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <stdlib.h>
  27 
  28 #include "jni.h"
  29 #include "jni_util.h"
  30 
  31 #include "java_lang_reflect_Proxy.h"
  32 
  33 /* defined in libverify.so/verify.dll (src file common/check_format.c) */
  34 extern jboolean VerifyFixClassname(char *utf_name);
  35 
  36 /*
  37  * Class:     java_lang_reflect_Proxy
  38  * Method:    defineClass0
  39  * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BII)Ljava/lang/Class;
  40  *
  41  * The implementation of this native static method is a copy of that of
  42  * the native instance method Java_java_lang_ClassLoader_defineClass0()
  43  * with the implicit "this" parameter becoming the "loader" parameter.
  44  */
  45 JNIEXPORT jclass JNICALL
  46 Java_java_lang_reflect_Proxy_defineClass0(JNIEnv *env,
  47                                           jclass ignore,
  48                                           jobject loader,
  49                                           jstring name,
  50                                           jbyteArray data,
  51                                           jint offset,
  52                                           jint length)
  53 {
  54     jbyte *body;
  55     char *utfName;
  56     jclass result = 0;
  57     char buf[128];
  58 
  59     if (data == NULL) {
  60         JNU_ThrowNullPointerException(env, 0);
  61         return 0;
  62     }
  63 
  64     /* Work around 4153825. malloc crashes on Solaris when passed a
  65      * negative size.
  66      */
  67     if (length < 0) {
  68         JNU_ThrowArrayIndexOutOfBoundsException(env, 0);
  69         return 0;
  70     }
  71 
  72     body = (jbyte *)malloc(length);
  73 
  74     if (body == 0) {
  75         JNU_ThrowOutOfMemoryError(env, 0);
  76         return 0;
  77     }
  78 
  79     (*env)->GetByteArrayRegion(env, data, offset, length, body);
  80 
  81     if ((*env)->ExceptionOccurred(env))
  82         goto free_body;
  83 
  84     if (name != NULL) {
  85         jsize len = (*env)->GetStringUTFLength(env, name);
  86         jsize unicode_len = (*env)->GetStringLength(env, name);
  87         if (len >= (jsize)sizeof(buf)) {
  88             utfName = malloc(len + 1);
  89             if (utfName == NULL) {
  90                 JNU_ThrowOutOfMemoryError(env, NULL);
  91                 goto free_body;
  92             }
  93         } else {
  94             utfName = buf;
  95         }
  96         (*env)->GetStringUTFRegion(env, name, 0, unicode_len, utfName);
  97         VerifyFixClassname(utfName);
  98     } else {
  99         utfName = NULL;
 100     }
 101 
 102     result = (*env)->DefineClass(env, utfName, loader, body, length);
 103 
 104     if (utfName && utfName != buf)
 105         free(utfName);
 106 
 107  free_body:
 108     free(body);
 109     return result;
 110 }