Skip to content

Commit

Permalink
Let ijar warn only once per unsupported attribute
Browse files Browse the repository at this point in the history
Work towards bazelbuild#21781

Closes bazelbuild#22072.

PiperOrigin-RevId: 629359080
Change-Id: I2c813d3a9069ec125a914bfc57e6c9068c83d3bc
  • Loading branch information
fmeum authored and Kila2 committed May 13, 2024
1 parent 0f21e4a commit c193f8b
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 6 deletions.
17 changes: 11 additions & 6 deletions third_party/ijar/classfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <set>
#include <sstream>
#include <string>
#include <unordered_set>
#include <vector>

#include "third_party/ijar/common.h"
Expand Down Expand Up @@ -112,10 +113,11 @@ enum TARGET_TYPE {
struct Constant;

// TODO(adonovan) these globals are unfortunate
static std::vector<Constant*> const_pool_in; // input constant pool
static std::vector<Constant*> const_pool_out; // output constant_pool
static std::set<std::string> used_class_names;
static Constant * class_name;
static std::vector<Constant *> const_pool_in; // input constant pool
static std::vector<Constant *> const_pool_out; // output constant_pool
static std::set<std::string> used_class_names;
static Constant *class_name;
static std::unordered_set<std::string> unknown_attributes;

// Returns the Constant object, given an index into the input constant pool.
// Note: constant(0) == NULL; this invariant is exploited by the
Expand Down Expand Up @@ -1592,8 +1594,11 @@ void HasAttrs::ReadAttrs(const u1 *&p) {
// not relevant for ijar.
if (attr_name != "com.android.tools.r8.SynthesizedClass" &&
attr_name != "com.android.tools.r8.SynthesizedClassV2") {
fprintf(stderr, "ijar: skipping unknown attribute: \"%s\".\n",
attr_name.c_str());
// Only warn about the first occurrence of each unknown attribute.
if (unknown_attributes.insert(attr_name).second) {
fprintf(stderr, "ijar: skipping unknown attribute: \"%s\".\n",
attr_name.c_str());
}
}
p += attribute_length;
}
Expand Down
16 changes: 16 additions & 0 deletions third_party/ijar/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ sh_test(
"records/records.jar",
"sealed/sealed.jar",
":source_debug_extension.jar",
":duplicated_unsupported_attribute.jar",
":keep_for_compile_lib.jar",
":largest_regular.jar",
":smallest_zip64.jar",
Expand Down Expand Up @@ -210,6 +211,21 @@ genrule(
tools = ["gen_source_debug_extension"],
)

java_binary(
name = "gen_duplicated_unsupported_attribute",
srcs = ["GenDuplicatedUnsupportedAttribute.java"],
main_class = "test.GenDuplicatedUnsupportedAttribute",
deps = ["//third_party:asm"],
)

genrule(
name = "gen_duplicated_unsupported_attribute_jar",
srcs = [],
outs = ["duplicated_unsupported_attribute.jar"],
cmd = "$(location :gen_duplicated_unsupported_attribute) $@",
tools = ["gen_duplicated_unsupported_attribute"],
)

java_binary(
name = "gen_dynamic_constant",
srcs = ["GenDynamicConstant.java"],
Expand Down
89 changes: 89 additions & 0 deletions third_party/ijar/test/GenDuplicatedUnsupportedAttribute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2024 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class GenDuplicatedUnsupportedAttribute {
public static void main(String[] args) throws IOException {
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(args[0]))) {
jos.putNextEntry(new ZipEntry("unsupportedattributes/Test1.class"));
jos.write(dump("Test1"));
jos.putNextEntry(new ZipEntry("unsupportedattributes/Test2.class"));
jos.write(dump("Test2"));
}
}

public static byte[] dump(String name) {
ClassWriter cw = new ClassWriter(0);
MethodVisitor mv;

cw.visit(
52,
Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
"unsupportedattributes/" + name,
null,
"java/lang/Object",
null);

// This is the important part for the test - repeat an unsupported attribute.
cw.visitAttribute(
new Attribute("some_unknown_type") {
@Override
protected ByteVector write(
ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
return new ByteVector().putInt(1234);
}
});

{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv =
cw.visitMethod(
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
"main",
"([Ljava/lang/String;)V",
null,
null);
mv.visitCode();
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Hello");
mv.visitMethodInsn(
Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
cw.visitEnd();

return cw.toByteArray();
}
}
8 changes: 8 additions & 0 deletions third_party/ijar/test/ijar_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ SEALED_JAR=$IJAR_SRCDIR/test/sealed/sealed.jar
SEALED_IJAR=$TEST_TMPDIR/sealed_interface.jar
SOURCEDEBUGEXT_JAR=$IJAR_SRCDIR/test/source_debug_extension.jar
SOURCEDEBUGEXT_IJAR=$TEST_TMPDIR/source_debug_extension.jar
DUPLICATEDUNSUPPORTEDATTRIBUTE_JAR=$IJAR_SRCDIR/test/duplicated_unsupported_attribute.jar
DUPLICATEDUNSUPPORTEDATTRIBUTE_IJAR=$TEST_TMPDIR/duplicated_unsupported_attribute.jar
CENTRAL_DIR_LARGEST_REGULAR=$IJAR_SRCDIR/test/largest_regular.jar
CENTRAL_DIR_SMALLEST_ZIP64=$IJAR_SRCDIR/test/smallest_zip64.jar
CENTRAL_DIR_ZIP64=$IJAR_SRCDIR/test/definitely_zip64.jar
Expand Down Expand Up @@ -575,6 +577,12 @@ function test_source_debug_extension_attribute() {
expect_not_log "SourceDebugExtension" "SourceDebugExtension preserved!"
}

function test_duplicated_unsupported_attribute() {
# Check that unsupported attribute warnings are only emitted once
$IJAR $DUPLICATEDUNSUPPORTEDATTRIBUTE_JAR $DUPLICATEDUNSUPPORTEDATTRIBUTE_IJAR >& $TEST_log || fail "ijar failed"
expect_log_once 'skipping unknown attribute: "some_unknown_type"'
}

function test_keep_for_compile() {
$IJAR --strip_jar $KEEP_FOR_COMPILE $TEST_TMPDIR/keep.jar \
|| fail "ijar failed"
Expand Down

0 comments on commit c193f8b

Please sign in to comment.