/* BASIC2026 portable final-submission PDF sanitizer. */
typedef struct {
    int annotations,flatten_forms,javascript,attachments,actions,metadata;
    int bookmarks,page_labels,thumbnails,layers,keep_links,keep_tags;
} B2026PdfSanitizeSettings;

typedef struct {
    int annotation_removed,form_removed,javascript_removed,attachment_removed;
    int action_removed,metadata_removed,bookmark_removed,page_label_removed;
    int thumbnail_removed,layer_removed,links_preserved,tags_preserved,verified;
} B2026PdfSanitizeStats;

static int b2026_pdf_san_bool(HashVariable *h,const char *jp,const char *en,int fallback,int *out){
    HashEntry *e=b2026_pdf_tf_entry(h,jp,en);if(e==NULL){*out=fallback;return 1;}
    if(e->value.type!=TYPE_NUMBER||!isfinite(e->value.val.number))return 0;*out=e->value.val.number!=0.0;return 1;
}

static int b2026_pdf_san_settings(HashVariable *h,B2026PdfSanitizeSettings *s){
    return b2026_pdf_san_bool(h,"注釈削除","removeAnnotations",1,&s->annotations)&&
        b2026_pdf_san_bool(h,"フォーム固定","flattenForms",1,&s->flatten_forms)&&
        b2026_pdf_san_bool(h,"JavaScript削除","removeJavaScript",1,&s->javascript)&&
        b2026_pdf_san_bool(h,"添付ファイル削除","removeAttachments",1,&s->attachments)&&
        b2026_pdf_san_bool(h,"外部動作削除","removeActions",1,&s->actions)&&
        b2026_pdf_san_bool(h,"メタデータ削除","removeMetadata",1,&s->metadata)&&
        b2026_pdf_san_bool(h,"ブックマーク削除","removeBookmarks",1,&s->bookmarks)&&
        b2026_pdf_san_bool(h,"ページラベル削除","removePageLabels",1,&s->page_labels)&&
        b2026_pdf_san_bool(h,"サムネイル削除","removeThumbnails",1,&s->thumbnails)&&
        b2026_pdf_san_bool(h,"レイヤー情報削除","removeLayers",1,&s->layers)&&
        b2026_pdf_san_bool(h,"リンクを維持","keepLinks",0,&s->keep_links)&&
        b2026_pdf_san_bool(h,"構造タグを維持","keepStructureTags",1,&s->keep_tags);
}

static void b2026_pdf_san_pair_number(const char *target,const char *jp,const char *en,double value){if(target==NULL)return;hash_set_number(target,jp,value);hash_set_number(target,en,value);}
static void b2026_pdf_san_pair_string(const char *target,const char *jp,const char *en,const char *value){if(target==NULL)return;hash_set_string(target,jp,value!=NULL?value:"");hash_set_string(target,en,value!=NULL?value:"");}
static void b2026_pdf_san_report(const char *target,const char *path,int ok,const B2026PdfSanitizeStats *st){
    HashVariable *h;if(target==NULL||*target=='\0')return;h=ensure_local_hash(get_hash_frame(target),target);clear_hash_entries(h);
    b2026_pdf_san_pair_number(target,"成功","ok",ok?1.0:0.0);b2026_pdf_san_pair_string(target,"保存先","path",ok?path:"");
    b2026_pdf_san_pair_number(target,"注釈削除数","annotationRemoved",st!=NULL?(double)st->annotation_removed:0.0);
    b2026_pdf_san_pair_number(target,"フォーム削除数","formRemoved",st!=NULL?(double)st->form_removed:0.0);
    b2026_pdf_san_pair_number(target,"JavaScript削除数","javascriptRemoved",st!=NULL?(double)st->javascript_removed:0.0);
    b2026_pdf_san_pair_number(target,"添付ファイル削除数","attachmentsRemoved",st!=NULL?(double)st->attachment_removed:0.0);
    b2026_pdf_san_pair_number(target,"外部動作削除数","actionsRemoved",st!=NULL?(double)st->action_removed:0.0);
    b2026_pdf_san_pair_number(target,"メタデータ削除","metadataRemoved",st!=NULL?(double)st->metadata_removed:0.0);
    b2026_pdf_san_pair_number(target,"ブックマーク削除","bookmarksRemoved",st!=NULL?(double)st->bookmark_removed:0.0);
    b2026_pdf_san_pair_number(target,"ページラベル削除","pageLabelsRemoved",st!=NULL?(double)st->page_label_removed:0.0);
    b2026_pdf_san_pair_number(target,"サムネイル削除数","thumbnailsRemoved",st!=NULL?(double)st->thumbnail_removed:0.0);
    b2026_pdf_san_pair_number(target,"レイヤー情報削除","layersRemoved",st!=NULL?(double)st->layer_removed:0.0);
    b2026_pdf_san_pair_number(target,"リンク維持数","linksPreserved",st!=NULL?(double)st->links_preserved:0.0);
    b2026_pdf_san_pair_number(target,"構造タグ維持","structureTagsPreserved",st!=NULL?(double)st->tags_preserved:0.0);
    b2026_pdf_san_pair_string(target,"検証結果","verification",ok&&st!=NULL&&st->verified?"PASS":"FAIL");
}

static int b2026_pdf_san_remove_key(B2026PdfDocument *doc,int oi,const char *key,int *count){
    B2026PdfKeyRange r;B2026PdfObject *o;if(oi<0||oi>=doc->object_count)return 0;o=&doc->objects[oi];
    for(;;){
        if(!b2026_pdf_tf_find_key(o->body,o->body_length,key,&r)){
            /* Arrays, scalar objects and other non-dictionary objects simply do not
               contain dictionary keys.  They are not malformed for this purpose. */
            if(b2026_pdf_memfind(o->body,o->body_length,"<<",2U)==NULL)return 1;
            return 0;
        }
        if(!r.found)return 1;if(!b2026_pdf_tf_set_key(doc,oi,key,NULL,1))return 0;if(count!=NULL)++*count;
    }
}

static int b2026_pdf_san_has_dict_token(const B2026PdfObject *o,const char *token){
    const unsigned char *stream=b2026_pdf_memfind(o->body,o->body_length,"stream",6U);size_t n=stream!=NULL?(size_t)(stream-o->body):o->body_length;
    return b2026_pdf_memfind(o->body,n,token,strlen(token))!=NULL;
}

static int b2026_pdf_san_widget_appearances(B2026PdfDocument *doc,int *painted,int *missing){
    int page,serial=1;*painted=*missing=0;
    for(page=0;page<doc->page_count;++page){int pi=doc->page_objects[page];B2026PdfObject *p=&doc->objects[pi];B2026PdfKeyRange r;char *annots=NULL;size_t q,n;
        if(!b2026_pdf_tf_find_key(p->body,p->body_length,"/Annots",&r))return 0;if(!r.found)continue;
        annots=b2026_pdf_tf_value_copy(doc,p->body+r.value_start,r.value_end-r.value_start,1);if(annots==NULL)return 0;n=strlen(annots);q=0U;
        while(q<n){char *e;long a,g;size_t s,u;int oi;if(!isdigit((unsigned char)annots[q])){++q;continue;}a=strtol(annots+q,&e,10);s=b2026_pdf_tf_space((unsigned char*)annots,n,(size_t)(e-annots));if(s>=n||!isdigit((unsigned char)annots[s])){++q;continue;}g=strtol(annots+s,&e,10);u=b2026_pdf_tf_space((unsigned char*)annots,n,(size_t)(e-annots));if(u<n&&annots[u]=='R'&&a>0&&a<=INT_MAX&&g>=0&&g<=INT_MAX&&(oi=b2026_pdf_object_lookup(doc,(int)a,(int)g))>=0){if(b2026_pdf_dict_name_is(doc->objects[oi].body,doc->objects[oi].body_length,"/Subtype","Widget")){int before=*painted,wm=0,other=0;if(!b2026_pdf_flat_annotation(doc,pi,oi,serial++,painted,&other,&wm)){free(annots);return 0;}if(wm||*painted==before)*missing=1;}q=u+1U;}else ++q;}
        free(annots);
    }return 1;
}

static int b2026_pdf_san_contains_ci(const char *text,const char *needle){
    size_t i,j,n=text!=NULL?strlen(text):0U,m=needle!=NULL?strlen(needle):0U;if(m==0U)return 1;
    for(i=0U;i+m<=n;++i){for(j=0U;j<m&&tolower((unsigned char)text[i+j])==tolower((unsigned char)needle[j]);++j){}if(j==m)return 1;}return 0;
}

static int b2026_pdf_san_action_is_safe(B2026PdfDocument *doc,B2026PdfObject *annotation){
    B2026PdfKeyRange a,next;char *value;int safe=0;if(!b2026_pdf_tf_find_key(annotation->body,annotation->body_length,"/A",&a)||!a.found)return 1;
    value=b2026_pdf_tf_value_copy(doc,annotation->body+a.value_start,a.value_end-a.value_start,1);if(value==NULL)return 0;
    if(!b2026_pdf_tf_find_key((unsigned char*)value,strlen(value),"/Next",&next)){free(value);return 0;}
    if(!next.found&&b2026_pdf_dict_name_is((unsigned char*)value,strlen(value),"/S","GoTo"))safe=1;
    if(!next.found&&b2026_pdf_dict_name_is((unsigned char*)value,strlen(value),"/S","URI")&&!b2026_pdf_san_contains_ci(value,"javascript:"))safe=1;
    free(value);return safe;
}

static int b2026_pdf_san_filter_annotations(B2026PdfDocument *doc,const B2026PdfSanitizeSettings *s,B2026PdfSanitizeStats *st){
    int page;for(page=0;page<doc->page_count;++page){int pi=doc->page_objects[page];B2026PdfObject *p=&doc->objects[pi];B2026PdfKeyRange r;B2026PdfTextBuffer out;char *annots=NULL;size_t q,n;int kept=0;memset(&out,0,sizeof(out));
        if(!b2026_pdf_tf_find_key(p->body,p->body_length,"/Annots",&r))return 0;if(!r.found)continue;annots=b2026_pdf_tf_value_copy(doc,p->body+r.value_start,r.value_end-r.value_start,1);if(annots==NULL)return 0;n=strlen(annots);q=0U;if(!b2026_pdf_text_append_char(&out,'['))goto fail;
        while(q<n){char *e;long a,g;size_t z,u;int oi,is_link,is_widget,is_attachment,keep;if(!isdigit((unsigned char)annots[q])){if(annots[q]=='<'||annots[q]=='('){goto fail;}++q;continue;}a=strtol(annots+q,&e,10);z=b2026_pdf_tf_space((unsigned char*)annots,n,(size_t)(e-annots));if(z>=n||!isdigit((unsigned char)annots[z])){++q;continue;}g=strtol(annots+z,&e,10);u=b2026_pdf_tf_space((unsigned char*)annots,n,(size_t)(e-annots));if(u>=n||annots[u]!='R'||a<=0||a>INT_MAX||g<0||g>INT_MAX||(oi=b2026_pdf_object_lookup(doc,(int)a,(int)g))<0)goto fail;
            is_link=b2026_pdf_dict_name_is(doc->objects[oi].body,doc->objects[oi].body_length,"/Subtype","Link");is_widget=b2026_pdf_dict_name_is(doc->objects[oi].body,doc->objects[oi].body_length,"/Subtype","Widget");is_attachment=b2026_pdf_dict_name_is(doc->objects[oi].body,doc->objects[oi].body_length,"/Subtype","FileAttachment");
            keep=!is_widget&&!(s->attachments&&is_attachment)&&(!s->annotations||(is_link&&s->keep_links));
            if(keep){char ref[64];if(s->actions){int removed=0;if(!b2026_pdf_san_remove_key(doc,oi,"/AA",&st->action_removed))goto fail;if(!is_link||!b2026_pdf_san_action_is_safe(doc,&doc->objects[oi])){if(!b2026_pdf_san_remove_key(doc,oi,"/A",&removed))goto fail;st->action_removed+=removed;}}
                snprintf(ref,sizeof(ref)," %ld %ld R",a,g);if(!b2026_pdf_text_append_bytes(&out,ref,strlen(ref)))goto fail;++kept;if(is_link)++st->links_preserved;
            }else{++st->annotation_removed;if(is_widget)++st->form_removed;if(is_attachment)++st->attachment_removed;}
            q=u+1U;
        }
        if(!b2026_pdf_text_append_bytes(&out," ]",2U))goto fail;if(kept){if(!b2026_pdf_tf_set_key(doc,pi,"/Annots",out.data,0))goto fail;}else if(!b2026_pdf_tf_set_key(doc,pi,"/Annots",NULL,1))goto fail;free(out.data);free(annots);continue;
fail:free(out.data);free(annots);return 0;
    }return 1;
}

static int b2026_pdf_san_strip_names(B2026PdfDocument *doc,const B2026PdfSanitizeSettings *s,B2026PdfSanitizeStats *st){
    B2026PdfKeyRange r;char *names=NULL,ref[64];int ni,removed=0;if(doc->root_object<0)return 0;if(!b2026_pdf_tf_find_key(doc->objects[doc->root_object].body,doc->objects[doc->root_object].body_length,"/Names",&r))return 0;if(!r.found)return 1;
    names=b2026_pdf_tf_value_copy(doc,doc->objects[doc->root_object].body+r.value_start,r.value_end-r.value_start,1);if(names==NULL)return 0;ni=b2026_pdf_tf_add_body(doc,names);free(names);if(ni<0)return 0;
    if(s->attachments){removed=0;if(!b2026_pdf_san_remove_key(doc,ni,"/EmbeddedFiles",&removed))return 0;st->attachment_removed+=removed;}
    if(s->javascript){removed=0;if(!b2026_pdf_san_remove_key(doc,ni,"/JavaScript",&removed))return 0;st->javascript_removed+=removed;}
    snprintf(ref,sizeof(ref),"%d 0 R",doc->objects[ni].old_number);return b2026_pdf_tf_set_key(doc,doc->root_object,"/Names",ref,0);
}

static int b2026_pdf_san_strip(B2026PdfDocument *doc,const B2026PdfSanitizeSettings *s,B2026PdfSanitizeStats *st){
    int i,removed=0,had_tags=0;if(doc->root_object<0)return 0;
    if(s->flatten_forms){int painted=0,missing=0;if(!b2026_pdf_san_widget_appearances(doc,&painted,&missing))return 0;if(missing)return -1;}
    if(!b2026_pdf_san_filter_annotations(doc,s,st))return 0;
    if(!b2026_pdf_san_strip_names(doc,s,st))return 0;
    had_tags=b2026_pdf_san_has_dict_token(&doc->objects[doc->root_object],"/StructTreeRoot");
    {static const char *always[]={"/Type","/Pages","/AcroForm","/Metadata"};int k;for(k=0;k<4;++k)if(!b2026_pdf_san_remove_key(doc,doc->root_object,always[k],NULL))return 0;}
    if(s->javascript){removed=0;if(!b2026_pdf_san_remove_key(doc,doc->root_object,"/JavaScript",&removed))return 0;st->javascript_removed+=removed;}
    if(s->actions){static const char *keys[]={"/OpenAction","/AA","/Requirements"};int k;for(k=0;k<3;++k){removed=0;if(!b2026_pdf_san_remove_key(doc,doc->root_object,keys[k],&removed))return 0;st->action_removed+=removed;}}
    if(s->bookmarks){removed=0;if(!b2026_pdf_san_remove_key(doc,doc->root_object,"/Outlines",&removed))return 0;st->bookmark_removed+=removed;}
    if(s->page_labels){removed=0;if(!b2026_pdf_san_remove_key(doc,doc->root_object,"/PageLabels",&removed))return 0;st->page_label_removed+=removed;}
    if(s->layers){removed=0;if(!b2026_pdf_san_remove_key(doc,doc->root_object,"/OCProperties",&removed))return 0;st->layer_removed+=removed;}
    if(!s->keep_tags){if(!b2026_pdf_san_remove_key(doc,doc->root_object,"/StructTreeRoot",NULL)||!b2026_pdf_san_remove_key(doc,doc->root_object,"/MarkInfo",NULL))return 0;}
    for(i=0;i<doc->object_count;++i){B2026PdfObject *o=&doc->objects[i];if(o->is_page){if(s->thumbnails){removed=0;if(!b2026_pdf_san_remove_key(doc,i,"/Thumb",&removed))return 0;st->thumbnail_removed+=removed;}if(s->actions){removed=0;if(!b2026_pdf_san_remove_key(doc,i,"/AA",&removed))return 0;st->action_removed+=removed;}}
        if(s->metadata){removed=0;if(!b2026_pdf_san_remove_key(doc,i,"/Metadata",&removed))return 0;st->metadata_removed+=removed;}
    }
    if(s->metadata){if(doc->info_object>=0||doc->metadata_object>=0)st->metadata_removed=1;doc->info_object=-1;doc->metadata_object=-1;}
    st->tags_preserved=s->keep_tags&&had_tags?1:0;return 1;
}

static int b2026_pdf_san_reenable_annotations(B2026PdfDocument *doc){
    int p;for(p=0;p<doc->page_count;++p){B2026PdfObject *page=&doc->objects[doc->page_objects[p]];B2026PdfKeyRange r;char *a=NULL;size_t q,n;if(!b2026_pdf_tf_find_key(page->body,page->body_length,"/Annots",&r))return 0;if(!r.found)continue;a=b2026_pdf_tf_value_copy(doc,page->body+r.value_start,r.value_end-r.value_start,1);if(a==NULL)return 0;n=strlen(a);q=0U;while(q<n){char *e;long x,g;size_t z,u;int oi;if(!isdigit((unsigned char)a[q])){++q;continue;}x=strtol(a+q,&e,10);z=b2026_pdf_tf_space((unsigned char*)a,n,(size_t)(e-a));if(z>=n||!isdigit((unsigned char)a[z])){++q;continue;}g=strtol(a+z,&e,10);u=b2026_pdf_tf_space((unsigned char*)a,n,(size_t)(e-a));if(u<n&&a[u]=='R'&&x>0&&x<=INT_MAX&&g>=0&&g<=INT_MAX&&(oi=b2026_pdf_object_lookup(doc,(int)x,(int)g))>=0)doc->objects[oi].included=1;q=u<n?u+1U:q+1U;}free(a);}return 1;
}

static int b2026_pdf_san_object_has_key(const B2026PdfObject *o,const char *key){
    B2026PdfKeyRange r;if(o==NULL)return 0;if(!b2026_pdf_tf_find_key(o->body,o->body_length,key,&r))return 0;return r.found;
}

static int b2026_pdf_san_names_has_key(B2026PdfDocument *doc,const char *key){
    B2026PdfKeyRange r,nr;char *names;int found=0;if(doc->root_object<0)return 0;
    if(!b2026_pdf_tf_find_key(doc->objects[doc->root_object].body,doc->objects[doc->root_object].body_length,"/Names",&r)||!r.found)return 0;
    names=b2026_pdf_tf_value_copy(doc,doc->objects[doc->root_object].body+r.value_start,r.value_end-r.value_start,1);if(names==NULL)return 0;
    if(b2026_pdf_tf_find_key((unsigned char*)names,strlen(names),key,&nr)&&nr.found)found=1;free(names);return found;
}

static int b2026_pdf_san_verify(const char *path,int pages,const B2026PdfSanitizeSettings *s){
    B2026PdfDocument d;B2026PdfObject *root=NULL;int rc,i;memset(&d,0,sizeof(d));rc=b2026_pdf_load(&d,path,0);if(rc<=0||d.page_count!=pages)goto fail;
    if(d.root_object>=0)root=&d.objects[d.root_object];
    if(root!=NULL&&b2026_pdf_san_object_has_key(root,"/AcroForm"))goto fail;
    if(s->javascript&&b2026_pdf_san_names_has_key(&d,"/JavaScript"))goto fail;
    if(s->attachments&&b2026_pdf_san_names_has_key(&d,"/EmbeddedFiles"))goto fail;
    if(root!=NULL&&s->bookmarks&&b2026_pdf_san_object_has_key(root,"/Outlines"))goto fail;
    if(root!=NULL&&s->page_labels&&b2026_pdf_san_object_has_key(root,"/PageLabels"))goto fail;
    if(root!=NULL&&s->layers&&b2026_pdf_san_object_has_key(root,"/OCProperties"))goto fail;
    if(s->metadata&&(d.info_object>=0||d.metadata_object>=0))goto fail;
    if(b2026_pdf_count_token(d.bytes,d.length,"startxref")!=1)goto fail;
    for(i=0;i<d.object_count;++i){B2026PdfObject *o=&d.objects[i];
        if(s->javascript&&(b2026_pdf_san_object_has_key(o,"/JavaScript")||b2026_pdf_san_object_has_key(o,"/JS")||b2026_pdf_dict_name_is(o->body,o->body_length,"/S","JavaScript")))goto fail;
        if(s->attachments&&b2026_pdf_san_object_has_key(o,"/EmbeddedFiles"))goto fail;
        if(s->metadata&&b2026_pdf_dict_name_is(o->body,o->body_length,"/Type","Metadata"))goto fail;
        if(o->is_page&&s->thumbnails&&b2026_pdf_san_object_has_key(o,"/Thumb"))goto fail;
        if(s->actions&&(b2026_pdf_dict_name_is(o->body,o->body_length,"/S","Launch")||b2026_pdf_dict_name_is(o->body,o->body_length,"/S","JavaScript")||b2026_pdf_dict_name_is(o->body,o->body_length,"/S","SubmitForm")||b2026_pdf_dict_name_is(o->body,o->body_length,"/S","ImportData")||b2026_pdf_dict_name_is(o->body,o->body_length,"/S","GoToR")))goto fail;
        if(b2026_pdf_dict_name_is(o->body,o->body_length,"/Subtype","Widget"))goto fail;
        if(s->annotations&&b2026_pdf_dict_name_is(o->body,o->body_length,"/Type","Annot")&&!(s->keep_links&&b2026_pdf_dict_name_is(o->body,o->body_length,"/Subtype","Link")))goto fail;
    }
    b2026_pdf_document_free(&d);return 1;
fail:b2026_pdf_document_free(&d);return 0;
}

static const char *b2026_pdf_sanitize(const char *target_name,int argc,const B2026PdfArg *args){
    B2026PdfSanitizeSettings settings;B2026PdfSanitizeStats stats;B2026PdfDocument doc;B2026PdfPageList pages;HashVariable *hash=NULL;const char *source,*result;char *output=NULL,*stage=NULL;int path_args,rc,i;memset(&settings,0,sizeof(settings));memset(&stats,0,sizeof(stats));memset(&doc,0,sizeof(doc));memset(&pages,0,sizeof(pages));
    if(argc<1||argc>3){b2026_pdf_san_report(target_name,"",0,&stats);return b2026_pdf_fail(4250,"","SANITIZE requires path$ [, settings{}] or output$, source$ [, settings{}] / サニタイズにはPDFパスと任意設定、または保存先と入力元と任意設定が必要です");}
    path_args=argc;if(args[argc-1].kind==3){if(!b2026_pdf_tf_hash(&args[argc-1],&hash)){b2026_pdf_san_report(target_name,"",0,&stats);return b2026_pdf_fail(4251,"","sanitize settings do not exist / サニタイズ設定の連想配列がありません");}--path_args;}
    if((path_args!=1&&path_args!=2)||args[0].kind!=1||args[0].text==NULL||(path_args==2&&(args[1].kind!=1||args[1].text==NULL))||!b2026_pdf_san_settings(hash,&settings)){b2026_pdf_san_report(target_name,"",0,&stats);return b2026_pdf_fail(4251,"","invalid sanitize paths or settings / サニタイズのパスまたは設定が正しくありません");}
    source=path_args==2?args[1].text:args[0].text;output=b2026_pdf_output_path(args[0].text);if(output==NULL)goto memory_fail;
    rc=b2026_pdf_load(&doc,source,4);if(rc<=0){b2026_pdf_fail(4252,source,b2026_pdf_load_error(rc));goto fail;}
    stats.javascript_removed=settings.javascript&&(b2026_pdf_memfind(doc.bytes,doc.length,"/JavaScript",11U)!=NULL||b2026_pdf_memfind(doc.bytes,doc.length,"/JS",3U)!=NULL)?1:0;
    stats.attachment_removed=settings.attachments&&b2026_pdf_memfind(doc.bytes,doc.length,"/EmbeddedFiles",14U)!=NULL?1:0;
    rc=b2026_pdf_san_strip(&doc,&settings,&stats);if(rc==-1){b2026_pdf_fail(4253,source,"a form widget has no usable appearance; sanitizing was refused to avoid losing its value / 外観を持たないフォームWidgetがあるため値の消失を避けてサニタイズを拒否しました");goto fail;}if(rc==0)goto memory_fail;
    for(i=0;i<doc.page_count;++i)if(!b2026_pdf_pages_push(&pages,&doc,doc.page_objects[i],-1))goto memory_fail;
    if(!b2026_pdf_select_reachable_objects(&doc,1,&pages,1)||!b2026_pdf_san_reenable_annotations(&doc))goto memory_fail;
    stage=b2026_atomic_temp_path(output);if(stage==NULL||!b2026_pdf_write_output(stage,&doc,1,&pages,0,0,1)){if(stage!=NULL)b2026_atomic_discard_file(stage);b2026_pdf_fail(4254,output,"sanitized PDF could not be written atomically or exceeded 2 GiB / サニタイズ済みPDFを原子的に保存できないか2GiB上限を超えました");goto fail;}
    if(!b2026_pdf_san_verify(stage,doc.page_count,&settings)){b2026_atomic_discard_file(stage);b2026_pdf_fail(4255,output,"post-write sanitization verification failed / サニタイズ後の検証に失敗しました");goto fail;}stats.verified=1;
    if(!b2026_atomic_commit_file(stage,output)){b2026_atomic_discard_file(stage);b2026_pdf_fail(4256,output,"verified sanitized PDF could not be committed / 検証済みサニタイズPDFを保存先へ反映できません");goto fail;}free(stage);stage=NULL;
    b2026_pdf_san_report(target_name,output,1,&stats);result=runtime_temp_string_copy(output);free(output);free(pages.items);b2026_pdf_document_free(&doc);return result;
memory_fail:b2026_pdf_fail(4199,source,"out of memory or unsupported PDF resources / メモリ不足または未対応のPDF資源です");
fail:if(stage!=NULL){b2026_atomic_discard_file(stage);free(stage);}b2026_pdf_san_report(target_name,"",0,&stats);free(output);free(pages.items);b2026_pdf_document_free(&doc);return runtime_temp_string_copy("");
}
