Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let ijar warn only once per unsupported attribute #22072

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
87 changes: 87 additions & 0 deletions third_party/ijar/test/GenDuplicatedUnsupportedAttribute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// 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 org.objectweb.asm.Attribute;
import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

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