You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[rustjava-2026-09-23-validation-rules-name-their-position-adopt-p0] fix(classfile): extra-bytes 거부가 클래스가 끝난 바이트 위치를 말한다
parse-level 거부 3종을 재어 정확한 위치를 쥔 extra bytes 만 Location::ByteOffset(u32) 로 싣는다.
truncated/unparsable 은 nom 오프셋이 1바이트 변이의 약 절반에서 손상 지점 ±8B 밖이라 유지,
version<45 는 위치 없음. ClassFileError 24→32B(크기 잠금 갱신 · 이유 기록).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: REPORT.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,8 @@
1
1
# REPORT
2
+
## [2026-09-24] «파일 끝에 남는 바이트» 거부가 클래스가 끝난 위치를 말한다 (rustjava-2026-09-23-validation-rules-name-their-position-adopt-p0)
3
+
- 무엇을: parse-level 거부 3종을 재어, 정확한 위치를 쥔 «extra bytes» 하나만 `Location::ByteOffset` 으로 오프셋을 싣는다. «truncated or unparsable» 은 nom 오프셋이 손상 지점을 절반 가까이 빗나가 두었고, «version < 45.0» 은 가리킬 자리가 없다.
4
+
- 왜: 채택 제안 `2026-09-23-validation-rules-name-their-position#p0`. 제안의 예상(«truncated» 가 후보, 나머지는 없음)은 측정으로 뒤집혔다.
5
+
- 사용자 영향: 덧붙은 바이트가 있는 파일의 `ClassFormatError` 가 `(at byte offset N)` 을 붙여 어디서 잘라야 할지 말한다. `ClassFileError` 가 24 → 32 바이트로 커졌다. 후속 추천 0건 — 상세 `docs/worklog/2026-09-24-extra-bytes-name-their-offset.{md,json}`.
2
6
## [2026-09-24] GC 가 호스트 오류에 패닉하지 않고 `Err` 를 돌려준다 (wie-2026-09-22-lgt-object-reference-gate-adopt-p0)
3
7
- 무엇을: `Jvm::collect_garbage` 의 도달성 순회가 `get_field`·`get_static_field`·배열 `load` 오류를 `.unwrap()` 대신 호출자에게 돌려준다. 내부 불변식 두 곳은 `JavaError::Unraisable` 로 대상을 이름으로 말한다. 오류가 나면 아무것도 해제하지 않는다.
4
8
- 왜: wie 제안 `2026-09-22-lgt-object-reference-gate#p0` 의 나머지 절반이다(변종은 #94 에서 끝났다). 변종만 있으면 호스트가 올린 오류가 GC 경로에서 다시 패닉이 된다.
Copy file name to clipboardExpand all lines: STATE.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,7 @@
7
7
(둘 다 이것보다 오래됐고 MERGEABLE/CONFLICTING 처분이 이미 걸려 있다). 겹침은 전부 **append 형 합집합**이라 해소는 기계적이다)
8
8
9
9
## 완료
10
+
-[rustjava-2026-09-23-validation-rules-name-their-position-adopt-p0] parse-level 거부 3종 판정: extra bytes 만 정확한 위치 → `Location::ByteOffset(u32)` · truncated/unparsable 은 nom 오프셋이 1바이트 변이의 약 절반에서 손상 지점 ±8B 밖이라 유지 · version<45 는 위치 없음. `ClassFileError` 24→32B(크기 잠금 갱신). 변이 3종 red. 채택 `2026-09-23-validation-rules-name-their-position#p0`. 상세 `docs/worklog/2026-09-24-extra-bytes-name-their-offset.md`.
10
11
-[wie-2026-09-22-lgt-object-reference-gate-adopt-p0] GC 도달성 순회 `Result` 전파 — `get_field`·`get_static_field`·`load` unwrap 3곳 → `?`(호스트 오류 그대로) · 불변식 unwrap 2곳 → `Unraisable` · 오류 시 중단(해제 0). 새 변종 0 · 공개 서명 변경 0. 양방향: 새 시험 ok ↔ unwrap 복원 시 panic FAILED. 채택 `2026-09-22-lgt-object-reference-gate#p0` · `2026-09-24-unraisable-error-variant#p0`. wie 효력은 crates.io 릴리스 뒤. 상세 `docs/worklog/2026-09-24-gc-walk-propagates-host-errors.md`.
11
12
-[rustjava-2026-09-20-name-the-missing-bootstrap-class-adopt-p0] ★**공개 API 변경(breaking)**: `JavaError::Unraisable(String)` 신설 — Java 예외로 만들 수 없는 실패. `Jvm::new` 패닉 2곳 → `Err(Unraisable)`(빠진 클래스 이름 포함) · `Jvm::exception` 재귀 바닥(같은 스레드에서 «같은 예외»를 다시 만들거나 깊이 8 → `Unraisable`, 첫 실패 명명) · `[Ljava/lang/String;` 숨김 재현이 stack overflow → loader 질문 2회. ★외부 소비자: `let JavaError::JavaException(..) = ..` irrefutable 구조분해가 컴파일 에러가 된다(이 repo 3곳 수정 · wie 는 crates.io 0.1.1 소비라 판올림 때 발생). 채택 `2026-09-20-name-the-missing-bootstrap-class#p0` · `2026-09-20-string-array-hiding-overflows-stack#p0`. 상세 `docs/worklog/2026-09-24-unraisable-error-variant.md`.
12
13
보정(-fix): `stream_handler.rs``publish` 의 `if let Err(JavaException)` 2곳 → `match` + `Unraisable` 전파(삼킴 제거) · 회귀 `stream_handler_propagates_unraisable_output_failures`.
"summary": "Of class.rs's three parse-level refusals, only 'extra bytes' holds an exact position (where the class ended); it now carries Location::ByteOffset. 'truncated or unparsable' was measured and left without one — its nom offset missed the damaged byte by more than 8 bytes in about half of single-byte mutations.",
| truncated or unparsable | 쥐지만 **믿을 수 없다**| nom 오류의 `input` 은 파일의 부분 슬라이스라 오프셋 복원은 된다. 그러나 1바이트 변이(값 0/0xff/0x01 × 전 위치)에서 오프셋이 손상 바이트 ±8B 안에 든 것은 Hello **358/639**, StringConcat **535/1151** — 절반 가까이가 엉뚱한 곳을 가리킨다(예: 풀 개수 바이트 8 손상 → 302 보고). 오류 지점마다 뜻도 다르다: `MapRes` = 감싼 구조의 시작(속성 본문 오류는 속성 시작으로 접힌다) · `Verify`/`Switch` = 필드를 읽은 «뒤». 절단은 Eof 로 전건(417/417 · 848/848) 오프셋 ≤ 절단점이지만 절단점과 8B 넘게 떨어진 경우가 121/417 · 388/848(최대 151B — 속성 본문 `take`). |**위치 없음 유지**|
10
+
| extra bytes after the end | ★**정확히 쥔다** — 제안의 「가리킬 자리 없음」은 반증 |`file.len() - remaining.len()` = 파서가 클래스를 끝낸 바이트. 뜻이 하나다. |**`Location::ByteOffset(u32)` 로 싣는다**|
11
+
| version predates 45.0 | 없다 | 버전은 늘 바이트 6..8 고정 — 위치는 정보가 아니다(값이 정보이고 그건 이미 문장이 말한다). | 유지 |
12
+
13
+
## 변경
14
+
-`classfile/src/error.rs`: `Location::ByteOffset(u32)` — 여섯째 종류이자 «표 인덱스가 아닌» 유일한 종류. Display `at byte offset N`.
15
+
-`classfile/src/class.rs`: extra-bytes 거부 → `InvalidFormatAt { cause(불변), ByteOffset }`. 4 GiB 초과 파일은 `u32` 에 못 담아 종전 `InvalidFormat` 로 떨어진다(틀린 수 대신 수 없음).
16
+
- 문면: 전 `extra bytes after the end of the class file` → 후 `extra bytes after the end of the class file (at byte offset 417)`(Hello.class + 3바이트 · `located_message` 경유).
17
+
- ★대가: `ClassFileError` 24 → **32 바이트**(64-bit). `u32` 는 `&'static str` 옆에 두 `u16` 처럼 들어가지 않는다. 크기 잠금 시험을 새 값으로 갱신하고 이유를 적었다. `[u16; 2]` 로 쪼개면 24 에 맞지만 공개 API 에 어색한 타입을 둔다 — 기각.
18
+
- 공개 API: `Location` 에 변종 추가. `Location` 은 2026-09-23(`c40db08e`)에 생겼고 태그·릴리스 전이라 외부 파괴 0.
0 commit comments