|
28 | 28 | 4건 유효 잔존 → **혼재 판정으로 보존**, 커밋별 판정표를 총괄에 제출(코드 변경 0). |
29 | 29 |
|
30 | 30 | ## 다음 |
31 | | -- ★`origin/main` 이 `upstream/main` 보다 **20커밋 뒤처짐**(2026-07-25 실측). upstream 동기화 |
32 | | - 티켓이 선행돼야 `wie-ktf-hardening` 잔존분 정리가 안전하다. |
33 | | -- (wie-ktf-hardening 유효 잔존 4건 — 전부 호스트 프로세스 abort 급 패닉/미구현, upstream 상납 가치 있음) |
34 | | - `Timer.schedule(TimerTask,long)` 1회성 / `StringBuffer.insert(I,String)` / |
35 | | - `StringBuffer.append([CII)` null→NPE / `System.arraycopy`·`String.<init>([B)([C)`· |
36 | | - `ByteArrayInputStream.<init>([B)` null 가드 + `Integer.byteValue()/shortValue()`. |
37 | | -- ★위 착수 전 upstream `agent/runtime-api-gaps`(6309d47, +33k lines, 미머지)가 잔존 4건을 |
38 | | - 삼키는지 확인할 것(중복 노동 방지). |
39 | | -- 발권 대기 태스크 없음 — 열린 PR 0, origin 작업 브랜치는 보존 판정된 `wie-ktf-hardening` 1건. |
| 31 | + |
| 32 | +### ①(최우선) upstream 동기화 — 2026-08-15 실측 |
| 33 | +`git rev-list --left-right --count origin/main...upstream/main` → **`9 32`** |
| 34 | +(origin 이 9 앞섬 · **32 뒤처짐**. 2026-07-25 의 「20 뒤처짐」은 낡았다.) |
| 35 | +- 공통조상 `62cf0c6` · upstream tip `95ebc5c` · origin tip `2e61e93`. |
| 36 | +- ★**충돌 예상 17파일**(`git merge-tree --write-tree --name-only origin/main upstream/main` 실측): |
| 37 | + `Cargo.lock` · `classfile/src/{class,constant_pool,error,lib}.rs` · |
| 38 | + `java_runtime/src/classes/java/io.rs` · `java_runtime/src/classes/java/io/input_stream_reader.rs` · |
| 39 | + `java_runtime/src/classes/java/io/unsupported_encoding_exception.rs`(add/add) · |
| 40 | + `java_runtime/src/classes/java/lang.rs` · `.../java/lang/string.rs` · `.../java/lang/thread.rs` · |
| 41 | + `java_runtime/src/loader.rs` · 테스트 2건 · `jvm_rust/src/class_definition.rs` · |
| 42 | + `src/runtime.rs` · `test_utils/src/lib.rs`. |
| 43 | +- ★**충돌의 성격 = «우리 PR #3·#5 와 upstream 의 독립 구현이 정면 충돌»**. upstream 에도 |
| 44 | + `class_format_error.rs` · `unsupported_encoding_exception.rs` 가 **독자적으로 존재**한다 |
| 45 | + (`423d1bd Hide classfile errors behind class definition errors`, `fe5d116` 등). |
| 46 | + ⇒ 단순 «우리 것 채택»이 아니라 **의미 대조 후 선택**이 필요하다. |
| 47 | +- ★**주의 — 이 축에서 우리가 upstream 보다 앞선 지점이 있다.** upstream |
| 48 | + `input_stream_reader.rs` 는 charset 을 **UTF-8/EUC-KR 만 하드코딩**하고 그 외는 |
| 49 | + `UnsupportedEncodingException` 을 던진다. 우리 PR #5 는 공용 `charset::Charset` 으로 |
| 50 | + 일반화해 **ISO-8859-1/US-ASCII 도 동작**한다. 머지 시 upstream 판본을 그대로 취하면 **퇴행**이다. |
| 51 | + |
| 52 | +### ②`wie-ktf-hardening` 잔존분 — 2026-08-15 재판정으로 **4건 → 2건** |
| 53 | +★**선행 확인 종결**: upstream `agent/runtime-api-gaps`(`6309d47`)는 **미머지가 아니다** — |
| 54 | +**PR #190 로 2026-07-25 04:59Z 스쿼시 머지**(머지커밋 `c4665b0`, +33,109/−1,040)됐고 |
| 55 | +그래서 브랜치가 upstream 에서 **삭제**됐다. 즉 「삼키는지」는 이제 **upstream/main 에 직접 묻는다**. |
| 56 | +항목별 판정(전부 `upstream/main` 트리 실측): |
| 57 | + |
| 58 | +| 항목 | upstream/main 현재 | 판정 | |
| 59 | +|---|---|---| |
| 60 | +| `Timer.schedule(TimerTask;J)V` 1회성 | `timer.rs` `schedule_once` 존재 | **삼킴 → 무효** | |
| 61 | +| `StringBuffer.insert(ILjava/lang/String;)` | `insert_string` 존재 | **삼킴 → 무효** | |
| 62 | +| `StringBuffer.append([CII)` null→NPE | null 가드 **+ 범위 가드**까지 존재 | **삼킴 → 무효** | |
| 63 | +| `ByteArrayInputStream.<init>([B)` null 가드 | `is_null()` 가드 존재(`be77dc6`) | **삼킴 → 무효** | |
| 64 | +| `Class.forName` null/not-found 가드 | 둘 다 존재 | **삼킴 → 무효** | |
| 65 | +| `Integer.byteValue()/shortValue()` | `java/lang/Number` 가 **구현 제공**, Integer 가 상속(`#176`) | **삼킴 → 무효** | |
| 66 | +| `System.arraycopy` null 가드 | **부재** | ★**유효 잔존** | |
| 67 | +| `String.<init>([B)` / `([C)` null 가드 | **부재** | ★**유효 잔존** | |
| 68 | + |
| 69 | +★유효 잔존 2건의 **파괴력 근거**(추정 아님): `ClassInstanceRef::deref` 가 |
| 70 | +`self.instance.as_ref().unwrap()` 이라 **null 참조를 넘기면 Rust 패닉 = 호스트 프로세스 abort**다 |
| 71 | +(`jvm/src/class_instance.rs`). `System::arraycopy` 는 `jvm.load_array(&src, …)`, |
| 72 | +`String::init_with_byte_array`/`init_with_char_array` 는 `jvm.array_length(&value)` 로 곧장 deref 한다. |
| 73 | +※**형제 호출부도 같이 봐라**: `String::init_with_partial_byte_array` 도 가드가 없다 |
| 74 | +(반면 `init_with_partial_char_array` 는 upstream 이 이미 가드를 넣었다 — 짝이 안 맞는다). |
| 75 | +※**전역 수리는 불가** — `Deref` 는 `Result` 를 못 돌려준다. upstream 방식(진입부 `is_null()` 가드)이 정답이다. |
| 76 | + |
| 77 | +### ③다음 회차 발권 후보(우선순위 순) |
| 78 | +1. **`rustjava-upstream-sync-32-commits`**(P1·L·high) — ①의 머지. 완료 정의 = 충돌 17파일 해소 + |
| 79 | + `cargo fmt --check`/`clippy`/`test` green + **PR #5 의 charset 일반화 퇴행 0**(회귀 픽스처 |
| 80 | + `test_data/UnsupportedCharset` 통과로 잠근다). |
| 81 | +2. **`rustjava-null-guard-arraycopy-and-string-init`**(P2·S·low) — ②의 유효 잔존 2건. |
| 82 | + ★**①의 뒤**여야 한다(같은 파일이 충돌 목록에 있다). 재현 = |
| 83 | + `System.arraycopy(null,0,dst,0,0)` · `new String((byte[])null)` · `new String((char[])null)` |
| 84 | + 각각 현재 **패닉**, 기대 `NullPointerException`. 형제 `String.<init>([BII)` 도 함께. |
| 85 | +3. **`rustjava-invokedynamic-and-cp-tags-15-18`**(P2·M·med) — 아래 미해결 항목. |
| 86 | + |
| 87 | +### ④미해결 — ★「이미 처리됐다」는 통설은 실측으로 **거짓**이다 |
| 88 | +- ★`jvm_rust/src/interpreter.rs` `Opcode::Invokedynamic(_) => todo!()` 는 |
| 89 | + **origin/main·upstream/main 양쪽에 그대로 살아 있다**(2026-08-15 실측). |
| 90 | + `rustjava-classfile-parse-error-propagation` 은 **클래스파일 파싱** 경로를 고쳤을 뿐 |
| 91 | + **인터프리터 opcode 는 건드리지 않았다** — 이 축은 미해결이다. |
| 92 | +- ★javac 21 익명 내부 클래스 "Malformed class file": 미해결. 원인 후보가 좁혀졌다 — |
| 93 | + `classfile/src/constant_pool.rs` 의 태그 분기가 **origin·upstream 모두 1~12 까지뿐**이고 |
| 94 | + **15(MethodHandle)·16(MethodType)·17(Dynamic)·18(InvokeDynamic) 분기가 없다.** |
| 95 | + javac 9+ 는 문자열 `+` 연결조차 invokedynamic 으로 낸다. |
| 96 | + ⇒ STATE 구판의 「태그 15~18 아님」은 **근거 없이 배제한 것**으로 보인다. 위 invokedynamic 축과 **한 티켓으로 묶어라**. |
| 97 | +- ★InputStreamReader 디코더: **origin/main 에서 미해결**(read 마다 |
| 98 | + `Charset::resolve(...).new_stream_decoder()` 로 새로 만든다). `rustjava-unsupported-charset-exception` |
| 99 | + 이 고친 것은 **미지원 charset 패닉**이지 **경계 유실**이 아니다 — 별개 결함이다. |
| 100 | + ※단 upstream 은 완화책을 갖고 있다(`endOfInput` 필드 + UTF-8 lead-byte 역주사 · EUC-KR `>=0x81` |
| 101 | + 홀드백). ⇒ **①의 머지로 함께 들어온다.** 별건 발권 전에 ① 이후 상태를 다시 재라. |
| 102 | + |
| 103 | +### ⑤운영 메모 |
| 104 | +- 발권 대기 태스크 없음 — 열린 PR 0(2026-08-15 확인), origin 작업 브랜치는 보존 판정된 |
| 105 | + `wie-ktf-hardening` 1건. 그 브랜치는 위 ②로 **잔존 가치가 2건까지 줄었다** — |
| 106 | + 2 건을 새 브랜치로 옮겨 심고 나면 **보존 근거가 소멸**한다. |
40 | 107 | - ★PR 발권 시 `--repo Jun025/RustJava` 명시(2026-07-22 upstream 오발행 사고 재발 방지). |
41 | | -- (범위 밖 잔여) `jvm_rust/src/interpreter.rs:629` `todo!()` (invokedynamic) — 별건 티켓 필요 |
42 | | -- (신규 발견) javac 21 산출 익명 내부 클래스(.class)가 "Malformed class file" 로 파싱 실패 — |
43 | | - 원인 미조사(태그 15~18 아님). 별건 티켓 필요. |
44 | | -- (신규 발견) InputStreamReader 가 read 마다 스트림 디코더를 새로 생성 — EUC-KR 등 multibyte |
45 | | - 가 버퍼 경계에 걸리면 부분 시퀀스 유실 가능(기존 문제, 이번 범위 밖). 별건 티켓 권장. |
| 108 | +- ★upstream 발신(PR·이슈·코멘트·push)은 **티켓이 명시 허가할 때만**. 기본은 조회뿐. |
0 commit comments