diff --git a/src/jtag/core.c b/src/jtag/core.c
index 4c91abeeed7c8c40d653a60c1e48863b45c72e46..7ed5976ccac8fc24711566ca66bcae64f3af6f04 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1073,6 +1073,7 @@ void jtag_tap_init(jtag_tap_t *tap)
 	tap->expected_mask = malloc(tap->ir_length);
 	tap->cur_instr = malloc(tap->ir_length);
 
+	/// @todo cope sanely with ir_length bigger than 32 bits
 	buf_set_u32(tap->expected, 0, tap->ir_length, tap->ir_capture_value);
 	buf_set_u32(tap->expected_mask, 0, tap->ir_length, tap->ir_capture_mask);
 	buf_set_ones(tap->cur_instr, tap->ir_length);
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 152dd762f5a628a719189ed8a50f50a46c644e08..abc100622586b3fa3cfba425ace8396947ef9bdf 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -296,6 +296,15 @@ static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap)
 	return JIM_OK;
 }
 
+static int is_bad_irval(int ir_length, jim_wide w)
+{
+	jim_wide v = 1;
+
+	v <<= ir_length;
+	v -= 1;
+	v = ~v;
+	return (w & v) != 0;
+}
 
 extern void jtag_tap_init(jtag_tap_t *tap);
 extern void jtag_tap_free(jtag_tap_t *tap);
@@ -411,22 +420,28 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi )
 				Jim_SetResult_sprintf( goi->interp, "option: %s bad parameter", n->name );
 				return e;
 			}
-			if( (w < 0) || (w > 0xffff) ){
-				/* wacky value */
-				Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)",
-									   n->name, (int)(w), (int)(w));
-				return JIM_ERR;
-			}
 			switch(n->value){
 			case NTAP_OPT_IRLEN:
+				if (w < (jim_wide) sizeof(pTap->ir_capture_value))
+					LOG_WARNING("huge IR length %d", (int) w);
 				pTap->ir_length = w;
 				reqbits &= (~(NTREQ_IRLEN));
 				break;
 			case NTAP_OPT_IRMASK:
+				if (is_bad_irval(pTap->ir_length, w)) {
+					LOG_ERROR("IR mask %x too big",
+							(int) w);
+					return ERROR_FAIL;
+				}
 				pTap->ir_capture_mask = w;
 				reqbits &= (~(NTREQ_IRMASK));
 				break;
 			case NTAP_OPT_IRCAPTURE:
+				if (is_bad_irval(pTap->ir_length, w)) {
+					LOG_ERROR("IR capture %x too big",
+							(int) w);
+					return ERROR_FAIL;
+				}
 				pTap->ir_capture_value = w;
 				reqbits &= (~(NTREQ_IRCAPTURE));
 				break;