From 3a57197979512a4e23f1420b3074b7a8d63c518e Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 25 Nov 2024 17:14:46 -0700 Subject: [PATCH 1/4] Mask off 63 from shift operand, #1034 --- .../JS/JavascriptCompiler.cs | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs index 2a57c02af2..597ab027f2 100644 --- a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs +++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs @@ -415,33 +415,50 @@ public override void EnterMultiplicative(JavascriptParser.MultiplicativeContext public override void EnterShift(JavascriptParser.ShiftContext context) { - CompileBinary(context, context.additive, additiveContext => + EnterAdditive(context.additive(0)); + + if (context.children.Count == 1) // if we don't have a shift token { - EnterAdditive(additiveContext); + return; + } - if (context.children.Count > 1) // if we have a shift token - { - compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) - } - }, terminalNode => + compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) + int argIndex = 1; + + for (int i = 1; i < context.children.Count; i += 2) { - if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHL) - { - compiler.PushOpWithConvert(OpCodes.Shl); - } - else if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHR) - { - compiler.PushOpWithConvert(OpCodes.Shr); - } - else if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHU) + if (context.children[i] is ITerminalNode terminalNode) { - compiler.PushOpWithConvert(OpCodes.Shr_Un); + EnterAdditive(context.additive(argIndex++)); + compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) + + // mask off 63 to prevent overflow (fixes issue on x86 .NET Framework, #1034) + compiler.Emit(OpCodes.Ldc_I4, 0x3F); + compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) + compiler.Emit(OpCodes.And); + + if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHL) + { + compiler.PushOpWithConvert(OpCodes.Shl); + } + else if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHR) + { + compiler.PushOpWithConvert(OpCodes.Shr); + } + else if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHU) + { + compiler.PushOpWithConvert(OpCodes.Shr_Un); + } + else + { + throw new ParseException("Unknown shift token", context.Start.StartIndex); + } } else { - throw new ParseException("Unknown shift token", context.Start.StartIndex); + throw new ParseException("Unexpected child", context.Start.StartIndex); } - }); + } } public override void EnterRelational(JavascriptParser.RelationalContext context) From 1e1d9ef334fd0ddf4c39d8c6c52359ccd20e8749 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 25 Nov 2024 17:58:49 -0700 Subject: [PATCH 2/4] Use 32-bit operand for shift operations, #1034 --- src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs index 597ab027f2..4c0f5dab67 100644 --- a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs +++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs @@ -430,11 +430,10 @@ public override void EnterShift(JavascriptParser.ShiftContext context) if (context.children[i] is ITerminalNode terminalNode) { EnterAdditive(context.additive(argIndex++)); - compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) + compiler.Emit(OpCodes.Conv_I4); // cast to int (truncate) // mask off 63 to prevent overflow (fixes issue on x86 .NET Framework, #1034) compiler.Emit(OpCodes.Ldc_I4, 0x3F); - compiler.Emit(OpCodes.Conv_I8); // cast to long (truncate) compiler.Emit(OpCodes.And); if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHL) From 461b406fe3c2cc8b3f45e99ed273275e8e8ca53f Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 25 Nov 2024 18:30:01 -0700 Subject: [PATCH 3/4] Revert masking change to see if 32-bit operand fixes issue --- src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs index 4c0f5dab67..8f7b2c45d4 100644 --- a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs +++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs @@ -430,11 +430,7 @@ public override void EnterShift(JavascriptParser.ShiftContext context) if (context.children[i] is ITerminalNode terminalNode) { EnterAdditive(context.additive(argIndex++)); - compiler.Emit(OpCodes.Conv_I4); // cast to int (truncate) - - // mask off 63 to prevent overflow (fixes issue on x86 .NET Framework, #1034) - compiler.Emit(OpCodes.Ldc_I4, 0x3F); - compiler.Emit(OpCodes.And); + compiler.Emit(OpCodes.Conv_I4); // cast shift operand to int (truncate) if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHL) { From 0238bf222d4f1003a71e21b73410788c7aaa3790 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 25 Nov 2024 20:33:00 -0700 Subject: [PATCH 4/4] Add back mask for .NET Framework fix --- src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs index 8f7b2c45d4..4c0f5dab67 100644 --- a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs +++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs @@ -430,7 +430,11 @@ public override void EnterShift(JavascriptParser.ShiftContext context) if (context.children[i] is ITerminalNode terminalNode) { EnterAdditive(context.additive(argIndex++)); - compiler.Emit(OpCodes.Conv_I4); // cast shift operand to int (truncate) + compiler.Emit(OpCodes.Conv_I4); // cast to int (truncate) + + // mask off 63 to prevent overflow (fixes issue on x86 .NET Framework, #1034) + compiler.Emit(OpCodes.Ldc_I4, 0x3F); + compiler.Emit(OpCodes.And); if (terminalNode.Symbol.Type == JavascriptParser.AT_BIT_SHL) {