comparison src/share/native/java/io/io_util.c @ 787:ff572b4f1ca4

6788196: (porting) Bounds checks in io_util.c rely on undefined behaviour Reviewed-by: alanb Contributed-by: gbenson@redhat.com
author martin
date Wed, 07 Jan 2009 11:50:32 -0800
parents b6d6877c1155
children 0272e442cc5b
comparison
equal deleted inserted replaced
3:cc23dc29acfa 4:0383e5c0e683
56 56
57 /* The maximum size of a stack-allocated buffer. 57 /* The maximum size of a stack-allocated buffer.
58 */ 58 */
59 #define BUF_SIZE 8192 59 #define BUF_SIZE 8192
60 60
61 /*
62 * Returns true if the array slice defined by the given offset and length
63 * is out of bounds.
64 */
65 static int
66 outOfBounds(JNIEnv *env, jint off, jint len, jbyteArray array) {
67 return ((off < 0) ||
68 (len < 0) ||
69 // We are very careful to avoid signed integer overflow,
70 // the result of which is undefined in C.
71 ((*env)->GetArrayLength(env, array) - off < len));
72 }
61 73
62 int 74 int
63 readBytes(JNIEnv *env, jobject this, jbyteArray bytes, 75 readBytes(JNIEnv *env, jobject this, jbyteArray bytes,
64 jint off, jint len, jfieldID fid) 76 jint off, jint len, jfieldID fid)
65 { 77 {
66 int nread, datalen; 78 int nread;
67 char stackBuf[BUF_SIZE]; 79 char stackBuf[BUF_SIZE];
68 char *buf = 0; 80 char *buf = 0;
69 FD fd; 81 FD fd;
70 82
71 if (IS_NULL(bytes)) { 83 if (IS_NULL(bytes)) {
72 JNU_ThrowNullPointerException(env, 0); 84 JNU_ThrowNullPointerException(env, 0);
73 return -1; 85 return -1;
74 } 86 }
75 datalen = (*env)->GetArrayLength(env, bytes); 87
76 88 if (outOfBounds(env, off, len, bytes)) {
77 if ((off < 0) || (off > datalen) ||
78 (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
79 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0); 89 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
80 return -1; 90 return -1;
81 } 91 }
82 92
83 if (len == 0) { 93 if (len == 0) {
134 144
135 void 145 void
136 writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, 146 writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
137 jint off, jint len, jfieldID fid) 147 jint off, jint len, jfieldID fid)
138 { 148 {
139 int n, datalen; 149 int n;
140 char stackBuf[BUF_SIZE]; 150 char stackBuf[BUF_SIZE];
141 char *buf = 0; 151 char *buf = 0;
142 FD fd; 152 FD fd;
143 153
144 if (IS_NULL(bytes)) { 154 if (IS_NULL(bytes)) {
145 JNU_ThrowNullPointerException(env, 0); 155 JNU_ThrowNullPointerException(env, 0);
146 return; 156 return;
147 } 157 }
148 datalen = (*env)->GetArrayLength(env, bytes); 158
149 159 if (outOfBounds(env, off, len, bytes)) {
150 if ((off < 0) || (off > datalen) ||
151 (len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
152 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0); 160 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
153 return; 161 return;
154 } 162 }
155 163
156 if (len == 0) { 164 if (len == 0) {