Snap for 11419993 from 21a96299a04bc426108fba63e6a70ca8b91f92c9 to mainline-permission-release

Change-Id: I3a6a3948334ce285b7bb3dd7f3150c57cc8d3493
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index cfd54bc..5fe19fd 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -598,6 +598,10 @@
             if (type == Type.MATCH && (lifetime != 0 || min != 0)) {
                 throw new IllegalArgumentException("lifetime, min must be 0 for MATCH sections");
             }
+            // Clamp the lifetime to INT_MAX to prevent it from ever going negative.
+            if (lifetime > Integer.MAX_VALUE) {
+                lifetime = Integer.MAX_VALUE;
+            }
             this.lifetime = lifetime;
 
             // It has already been asserted that min is 0 for MATCH sections.
@@ -1050,10 +1054,10 @@
                     //
                     // if lft < (oldLft + 2) // 3 -> PASS
                     // if lft > oldLft            -> PASS
-                    // gen.addJumpIfR0LessThan((int) ((section.lifetime + 2) / 3),
+                    // gen.addJumpIfR0LessThan(((section.lifetime + 2) / 3),
                     //        nextFilterLabel);
                     if (lft < (section.lifetime + 2) / 3) return MatchType.MATCH_PASS;
-                    // gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                    // gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
                     if (lft > section.lifetime) return MatchType.MATCH_PASS;
                 } else if (section.lifetime < section.min) {
                     // Case 2a) 0 < old lft < min
@@ -1077,7 +1081,7 @@
                     // if lft > oldLft -> PASS
                     // gen.addJumpIfR0Equals(0, nextFilterLabel);
                     if (lft == 0) return MatchType.MATCH_PASS;
-                    // gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                    // gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
                     if (lft > section.lifetime) return MatchType.MATCH_PASS;
                 } else {
                     // Case 4a) otherwise
@@ -1090,10 +1094,10 @@
                     if (lft == 0) return MatchType.MATCH_PASS;
                     // gen.addJumpIfR0LessThan(section.min, continueLabel);
                     if (lft < section.min) continue;
-                    // gen.addJumpIfR0LessThan((int) ((section.lifetime + 2) / 3),
+                    // gen.addJumpIfR0LessThan(((section.lifetime + 2) / 3),
                     //         nextFilterLabel);
                     if (lft < (section.lifetime + 2) / 3) return MatchType.MATCH_PASS;
-                    // gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                    // gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
                     if (lft > section.lifetime) return MatchType.MATCH_PASS;
                 }
             }
@@ -1178,9 +1182,9 @@
                         //
                         // if lft < (oldLft + 2) // 3 -> PASS
                         // if lft > oldLft            -> PASS
-                        gen.addJumpIfR0LessThan((int) ((section.lifetime + 2) / 3),
+                        gen.addJumpIfR0LessThan(((section.lifetime + 2) / 3),
                                 nextFilterLabel);
-                        gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                        gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
                     } else if (section.lifetime < section.min) {
                         // Case 2a) 0 < old lft < min
                         //
@@ -1200,7 +1204,7 @@
                         // if lft == 0     -> PASS
                         // if lft > oldLft -> PASS
                         gen.addJumpIfR0Equals(0, nextFilterLabel);
-                        gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                        gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
                     } else {
                         final String continueLabel = "Continue" + getUniqueNumberLocked();
                         // Case 4a) otherwise
@@ -1211,9 +1215,9 @@
                         // if lft > oldLft              -> PASS
                         gen.addJumpIfR0Equals(0, nextFilterLabel);
                         gen.addJumpIfR0LessThan(section.min, continueLabel);
-                        gen.addJumpIfR0LessThan((int) ((section.lifetime + 2) / 3),
+                        gen.addJumpIfR0LessThan(((section.lifetime + 2) / 3),
                                 nextFilterLabel);
-                        gen.addJumpIfR0GreaterThan((int) section.lifetime, nextFilterLabel);
+                        gen.addJumpIfR0GreaterThan(section.lifetime, nextFilterLabel);
 
                         // CONTINUE
                         gen.defineLabel(continueLabel);
diff --git a/src/android/net/apf/ApfV4Generator.java b/src/android/net/apf/ApfV4Generator.java
index ebb5ac9..54a95a1 100644
--- a/src/android/net/apf/ApfV4Generator.java
+++ b/src/android/net/apf/ApfV4Generator.java
@@ -357,11 +357,20 @@
             return this;
         }
 
-        Instruction addUnsigned(int imm) {
+        Instruction addUnsigned(long imm) {
             mIntImms.add(IntImmediate.newUnsigned(imm));
             return this;
         }
 
+        // in practice, 'int' always enough for packet offset
+        Instruction addPacketOffset(int imm) {
+            return addUnsigned(imm);
+        }
+
+        // in practice, 'int' always enough for data offset
+        Instruction addDataOffset(int imm) {
+            return addUnsigned(imm);
+        }
 
         Instruction addTwosCompSigned(int imm) {
             mIntImms.add(IntImmediate.newTwosComplementSigned(imm));
@@ -714,7 +723,7 @@
      * bytes from the beginning of the packet into {@code register}.
      */
     public ApfV4Generator addLoad8(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDB, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDB, r).addPacketOffset(ofs));
     }
 
     /**
@@ -722,7 +731,7 @@
      * bytes from the beginning of the packet into {@code register}.
      */
     public ApfV4Generator addLoad16(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDH, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDH, r).addPacketOffset(ofs));
     }
 
     /**
@@ -730,7 +739,7 @@
      * bytes from the beginning of the packet into {@code register}.
      */
     public ApfV4Generator addLoad32(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDW, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDW, r).addPacketOffset(ofs));
     }
 
     /**
@@ -739,7 +748,7 @@
      * the sum of {@code offset} and the value in register R1.
      */
     public ApfV4Generator addLoad8Indexed(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDBX, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDBX, r).addPacketOffset(ofs));
     }
 
     /**
@@ -748,7 +757,7 @@
      * the sum of {@code offset} and the value in register R1.
      */
     public ApfV4Generator addLoad16Indexed(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDHX, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDHX, r).addPacketOffset(ofs));
     }
 
     /**
@@ -757,7 +766,7 @@
      * the sum of {@code offset} and the value in register R1.
      */
     public ApfV4Generator addLoad32Indexed(Register r, int ofs) {
-        return append(new Instruction(Opcodes.LDWX, r).addUnsigned(ofs));
+        return append(new Instruction(Opcodes.LDWX, r).addPacketOffset(ofs));
     }
 
     /**
@@ -770,14 +779,14 @@
     /**
      * Add an instruction to the end of the program to multiply register R0 by {@code value}.
      */
-    public ApfV4Generator addMul(int val) {
+    public ApfV4Generator addMul(long val) {
         return append(new Instruction(Opcodes.MUL).addUnsigned(val));
     }
 
     /**
      * Add an instruction to the end of the program to divide register R0 by {@code value}.
      */
-    public ApfV4Generator addDiv(int val) {
+    public ApfV4Generator addDiv(long val) {
         return append(new Instruction(Opcodes.DIV).addUnsigned(val));
     }
 
@@ -884,7 +893,7 @@
      * Add an instruction to the end of the program to jump to {@code target} if register R0's
      * value is greater than {@code value}.
      */
-    public ApfV4Generator addJumpIfR0GreaterThan(int val, String tgt) {
+    public ApfV4Generator addJumpIfR0GreaterThan(long val, String tgt) {
         return append(new Instruction(Opcodes.JGT).addUnsigned(val).setTargetLabel(tgt));
     }
 
@@ -892,7 +901,7 @@
      * Add an instruction to the end of the program to jump to {@code target} if register R0's
      * value is less than {@code value}.
      */
-    public ApfV4Generator addJumpIfR0LessThan(int val, String tgt) {
+    public ApfV4Generator addJumpIfR0LessThan(long val, String tgt) {
         return append(new Instruction(Opcodes.JLT).addUnsigned(val).setTargetLabel(tgt));
     }
 
diff --git a/src/android/net/apf/ApfV6Generator.java b/src/android/net/apf/ApfV6Generator.java
index 48d4806..5ca41f7 100644
--- a/src/android/net/apf/ApfV6Generator.java
+++ b/src/android/net/apf/ApfV6Generator.java
@@ -170,7 +170,7 @@
      * @return the ApfGenerator object
      */
     public ApfV4Generator addDataCopy(int src, int len) {
-        return append(new Instruction(Opcodes.PKTDATACOPY, Rbit1).addUnsigned(src).addU8(len));
+        return append(new Instruction(Opcodes.PKTDATACOPY, Rbit1).addDataOffset(src).addU8(len));
     }
 
     /**
@@ -183,7 +183,7 @@
      * @return the ApfGenerator object
      */
     public ApfV4Generator addPacketCopy(int src, int len) {
-        return append(new Instruction(Opcodes.PKTDATACOPY, Rbit0).addUnsigned(src).addU8(len));
+        return append(new Instruction(Opcodes.PKTDATACOPY, Rbit0).addPacketOffset(src).addU8(len));
     }
 
     /**
diff --git a/tests/unit/src/android/net/apf/ApfV5Test.kt b/tests/unit/src/android/net/apf/ApfV5Test.kt
index bcf28ba..b867191 100644
--- a/tests/unit/src/android/net/apf/ApfV5Test.kt
+++ b/tests/unit/src/android/net/apf/ApfV5Test.kt
@@ -15,13 +15,15 @@
  */
 package android.net.apf
 
+import android.net.apf.ApfTestUtils.MIN_PKT_SIZE
+import android.net.apf.ApfTestUtils.assertPass
 import android.net.apf.ApfV4Generator.IllegalInstructionException
 import android.net.apf.ApfV4Generator.MIN_APF_VERSION
+import android.net.apf.ApfV4Generator.MIN_APF_VERSION_IN_DEV
 import android.net.apf.ApfV4Generator.Register.R0
 import android.net.apf.ApfV4Generator.Register.R1
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import java.lang.IllegalArgumentException
 import kotlin.test.assertContentEquals
 import kotlin.test.assertFailsWith
 import org.junit.Test
@@ -344,6 +346,20 @@
         ) + qnames, program)
     }
 
+    @Test
+    fun testWriteToTxBuffer() {
+        val gen = ApfV6Generator()
+        gen.addAllocate(74)
+        gen.addWriteU8(0x01)
+        gen.addWriteU16(0x0102)
+        gen.addWriteU32(0x01020304)
+        gen.addTransmit()
+        val program = gen.generate()
+        assertPass(MIN_APF_VERSION_IN_DEV, program, ByteArray(MIN_PKT_SIZE))
+        assertContentEquals(byteArrayOf(0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x04),
+          ApfJniUtils.getTransmittedPacket())
+    }
+
     private fun encodeInstruction(opcode: Int, immLength: Int, register: Int): Byte {
         val immLengthEncoding = if (immLength == 4) 3 else immLength
         return opcode.shl(3).or(immLengthEncoding.shl(1)).or(register).toByte()