xmlschemas.c 805 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894
  1. /*
  2. * schemas.c : implementation of the XML Schema handling and
  3. * schema validity checking
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Daniel Veillard <veillard@redhat.com>
  8. */
  9. /*
  10. * TODO:
  11. * - when types are redefined in includes, check that all
  12. * types in the redef list are equal
  13. * -> need a type equality operation.
  14. * - if we don't intend to use the schema for schemas, we
  15. * need to validate all schema attributes (ref, type, name)
  16. * against their types.
  17. * - Eliminate item creation for: ??
  18. *
  19. * URGENT TODO:
  20. * - For xsi-driven schema acquisition, augment the IDCs after every
  21. * acquisition episode (xmlSchemaAugmentIDC).
  22. *
  23. * NOTES:
  24. * - Eliminated item creation for: <restriction>, <extension>,
  25. * <simpleContent>, <complexContent>, <list>, <union>
  26. *
  27. * PROBLEMS:
  28. * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
  29. * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
  30. * XPath will have trouble to resolve to this namespace, since not known.
  31. *
  32. *
  33. * CONSTRAINTS:
  34. *
  35. * Schema Component Constraint:
  36. * All Group Limited (cos-all-limited)
  37. * Status: complete
  38. * (1.2)
  39. * In xmlSchemaGroupDefReferenceTermFixup() and
  40. * (2)
  41. * In xmlSchemaParseModelGroup()
  42. * TODO: Actually this should go to component-level checks,
  43. * but is done here due to performance. Move it to an other layer
  44. * is schema construction via an API is implemented.
  45. */
  46. /* To avoid EBCDIC trouble when parsing on zOS */
  47. #if defined(__MVS__)
  48. #pragma convert("ISO8859-1")
  49. #endif
  50. #define IN_LIBXML
  51. #include "libxml.h"
  52. #ifdef LIBXML_SCHEMAS_ENABLED
  53. #include <string.h>
  54. #include <libxml/xmlmemory.h>
  55. #include <libxml/parser.h>
  56. #include <libxml/parserInternals.h>
  57. #include <libxml/hash.h>
  58. #include <libxml/uri.h>
  59. #include <libxml/xmlschemas.h>
  60. #include <libxml/schemasInternals.h>
  61. #include <libxml/xmlschemastypes.h>
  62. #include <libxml/xmlautomata.h>
  63. #include <libxml/xmlregexp.h>
  64. #include <libxml/dict.h>
  65. #include <libxml/encoding.h>
  66. #include <libxml/xmlIO.h>
  67. #ifdef LIBXML_PATTERN_ENABLED
  68. #include <libxml/pattern.h>
  69. #endif
  70. #ifdef LIBXML_READER_ENABLED
  71. #include <libxml/xmlreader.h>
  72. #endif
  73. #include "private/error.h"
  74. #include "private/string.h"
  75. /* #define WXS_ELEM_DECL_CONS_ENABLED */
  76. /* #define ENABLE_PARTICLE_RESTRICTION 1 */
  77. #define ENABLE_REDEFINE
  78. /* #define ENABLE_NAMED_LOCALS */
  79. /* #define ENABLE_IDC_NODE_TABLES_TEST */
  80. #define DUMP_CONTENT_MODEL
  81. #ifdef LIBXML_READER_ENABLED
  82. /* #define XML_SCHEMA_READER_ENABLED */
  83. #endif
  84. #define UNBOUNDED (1 << 30)
  85. #define TODO \
  86. xmlGenericError(xmlGenericErrorContext, \
  87. "Unimplemented block at %s:%d\n", \
  88. __FILE__, __LINE__);
  89. #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  90. /*
  91. * The XML Schemas namespaces
  92. */
  93. static const xmlChar *xmlSchemaNs = (const xmlChar *)
  94. "http://www.w3.org/2001/XMLSchema";
  95. static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  96. "http://www.w3.org/2001/XMLSchema-instance";
  97. static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  98. "http://www.w3.org/2000/xmlns/";
  99. /*
  100. * Come casting macros.
  101. */
  102. #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  103. #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  104. #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  105. #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  106. #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  107. #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  108. #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  109. #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  110. #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  111. #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  112. #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  113. #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  114. #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  115. #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  116. #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  117. #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  118. #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  119. /*
  120. * Macros to query common properties of components.
  121. */
  122. #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  123. #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  124. /*
  125. * Macros for element declarations.
  126. */
  127. #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  128. #define WXS_SUBST_HEAD(item) (item)->refDecl
  129. /*
  130. * Macros for attribute declarations.
  131. */
  132. #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  133. /*
  134. * Macros for attribute uses.
  135. */
  136. #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
  137. #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  138. #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  139. #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  140. /*
  141. * Macros for attribute groups.
  142. */
  143. #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  144. #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  145. /*
  146. * Macros for particles.
  147. */
  148. #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  149. #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  150. #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  151. #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  152. /*
  153. * Macros for model groups definitions.
  154. */
  155. #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  156. /*
  157. * Macros for model groups.
  158. */
  159. #define WXS_IS_MODEL_GROUP(i) \
  160. (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  161. ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  162. ((i)->type == XML_SCHEMA_TYPE_ALL))
  163. #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  164. /*
  165. * Macros for schema buckets.
  166. */
  167. #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  168. ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  169. #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  170. ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  171. #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  172. #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  173. /*
  174. * Macros for complex/simple types.
  175. */
  176. #define WXS_IS_ANYTYPE(i) \
  177. (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  178. ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  179. #define WXS_IS_COMPLEX(i) \
  180. (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  181. ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  182. #define WXS_IS_SIMPLE(item) \
  183. ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  184. ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  185. (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  186. #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  187. (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  188. ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  189. #define WXS_IS_RESTRICTION(t) \
  190. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  191. #define WXS_IS_EXTENSION(t) \
  192. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  193. #define WXS_IS_TYPE_NOT_FIXED(i) \
  194. (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  195. (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  196. #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  197. (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  198. (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  199. #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  200. #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  201. /*
  202. * Macros for exclusively for complex types.
  203. */
  204. #define WXS_HAS_COMPLEX_CONTENT(item) \
  205. ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  206. (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  207. (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  208. #define WXS_HAS_SIMPLE_CONTENT(item) \
  209. ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  210. (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  211. #define WXS_HAS_MIXED_CONTENT(item) \
  212. (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  213. #define WXS_EMPTIABLE(t) \
  214. (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  215. #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  216. #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  217. #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  218. /*
  219. * Macros for exclusively for simple types.
  220. */
  221. #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  222. #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  223. #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  224. #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  225. /*
  226. * Misc parser context macros.
  227. */
  228. #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  229. #define WXS_HAS_BUCKETS(ctx) \
  230. ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  231. (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  232. #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  233. #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  234. #define WXS_SCHEMA(ctx) (ctx)->schema
  235. #define WXS_ADD_LOCAL(ctx, item) \
  236. do { \
  237. if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
  238. xmlFree(item); \
  239. item = NULL; \
  240. } \
  241. } while (0)
  242. #define WXS_ADD_GLOBAL(ctx, item) \
  243. do { \
  244. if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
  245. xmlFree(item); \
  246. item = NULL; \
  247. } \
  248. } while (0)
  249. #define WXS_ADD_PENDING(ctx, item) \
  250. xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  251. /*
  252. * xmlSchemaItemList macros.
  253. */
  254. #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  255. /*
  256. * Misc macros.
  257. */
  258. #define IS_SCHEMA(node, type) \
  259. ((node != NULL) && (node->ns != NULL) && \
  260. (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  261. (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  262. #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  263. /*
  264. * Since we put the default/fixed values into the dict, we can
  265. * use pointer comparison for those values.
  266. * REMOVED: (xmlStrEqual((v1), (v2)))
  267. */
  268. #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  269. #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  270. #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  271. #define HFAILURE if (res == -1) goto exit_failure;
  272. #define HERROR if (res != 0) goto exit_error;
  273. #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  274. /*
  275. * Some flags used for various schema constraints.
  276. */
  277. #define SUBSET_RESTRICTION 1<<0
  278. #define SUBSET_EXTENSION 1<<1
  279. #define SUBSET_SUBSTITUTION 1<<2
  280. #define SUBSET_LIST 1<<3
  281. #define SUBSET_UNION 1<<4
  282. typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  283. typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  284. typedef struct _xmlSchemaItemList xmlSchemaItemList;
  285. typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  286. struct _xmlSchemaItemList {
  287. void **items; /* used for dynamic addition of schemata */
  288. int nbItems; /* used for dynamic addition of schemata */
  289. int sizeItems; /* used for dynamic addition of schemata */
  290. };
  291. #define XML_SCHEMA_CTXT_PARSER 1
  292. #define XML_SCHEMA_CTXT_VALIDATOR 2
  293. typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  294. typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  295. struct _xmlSchemaAbstractCtxt {
  296. int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  297. void *dummy; /* Fix alignment issues */
  298. };
  299. typedef struct _xmlSchemaBucket xmlSchemaBucket;
  300. typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  301. #define XML_SCHEMA_SCHEMA_MAIN 0
  302. #define XML_SCHEMA_SCHEMA_IMPORT 1
  303. #define XML_SCHEMA_SCHEMA_INCLUDE 2
  304. #define XML_SCHEMA_SCHEMA_REDEFINE 3
  305. /**
  306. * xmlSchemaSchemaRelation:
  307. *
  308. * Used to create a graph of schema relationships.
  309. */
  310. typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  311. typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  312. struct _xmlSchemaSchemaRelation {
  313. xmlSchemaSchemaRelationPtr next;
  314. int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  315. const xmlChar *importNamespace;
  316. xmlSchemaBucketPtr bucket;
  317. };
  318. #define XML_SCHEMA_BUCKET_MARKED 1<<0
  319. #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  320. struct _xmlSchemaBucket {
  321. int type;
  322. int flags;
  323. const xmlChar *schemaLocation;
  324. const xmlChar *origTargetNamespace;
  325. const xmlChar *targetNamespace;
  326. xmlDocPtr doc;
  327. xmlSchemaSchemaRelationPtr relations;
  328. int located;
  329. int parsed;
  330. int imported;
  331. int preserveDoc;
  332. xmlSchemaItemListPtr globals; /* Global components. */
  333. xmlSchemaItemListPtr locals; /* Local components. */
  334. };
  335. /**
  336. * xmlSchemaImport:
  337. * (extends xmlSchemaBucket)
  338. *
  339. * Reflects a schema. Holds some information
  340. * about the schema and its toplevel components. Duplicate
  341. * toplevel components are not checked at this level.
  342. */
  343. typedef struct _xmlSchemaImport xmlSchemaImport;
  344. typedef xmlSchemaImport *xmlSchemaImportPtr;
  345. struct _xmlSchemaImport {
  346. int type; /* Main OR import OR include. */
  347. int flags;
  348. const xmlChar *schemaLocation; /* The URI of the schema document. */
  349. /* For chameleon includes, @origTargetNamespace will be NULL */
  350. const xmlChar *origTargetNamespace;
  351. /*
  352. * For chameleon includes, @targetNamespace will be the
  353. * targetNamespace of the including schema.
  354. */
  355. const xmlChar *targetNamespace;
  356. xmlDocPtr doc; /* The schema node-tree. */
  357. /* @relations will hold any included/imported/redefined schemas. */
  358. xmlSchemaSchemaRelationPtr relations;
  359. int located;
  360. int parsed;
  361. int imported;
  362. int preserveDoc;
  363. xmlSchemaItemListPtr globals;
  364. xmlSchemaItemListPtr locals;
  365. /* The imported schema. */
  366. xmlSchemaPtr schema;
  367. };
  368. /*
  369. * (extends xmlSchemaBucket)
  370. */
  371. typedef struct _xmlSchemaInclude xmlSchemaInclude;
  372. typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  373. struct _xmlSchemaInclude {
  374. int type;
  375. int flags;
  376. const xmlChar *schemaLocation;
  377. const xmlChar *origTargetNamespace;
  378. const xmlChar *targetNamespace;
  379. xmlDocPtr doc;
  380. xmlSchemaSchemaRelationPtr relations;
  381. int located;
  382. int parsed;
  383. int imported;
  384. int preserveDoc;
  385. xmlSchemaItemListPtr globals; /* Global components. */
  386. xmlSchemaItemListPtr locals; /* Local components. */
  387. /* The owning main or import schema bucket. */
  388. xmlSchemaImportPtr ownerImport;
  389. };
  390. /**
  391. * xmlSchemaBasicItem:
  392. *
  393. * The abstract base type for schema components.
  394. */
  395. typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  396. typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  397. struct _xmlSchemaBasicItem {
  398. xmlSchemaTypeType type;
  399. void *dummy; /* Fix alignment issues */
  400. };
  401. /**
  402. * xmlSchemaAnnotItem:
  403. *
  404. * The abstract base type for annotated schema components.
  405. * (Extends xmlSchemaBasicItem)
  406. */
  407. typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  408. typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  409. struct _xmlSchemaAnnotItem {
  410. xmlSchemaTypeType type;
  411. xmlSchemaAnnotPtr annot;
  412. };
  413. /**
  414. * xmlSchemaTreeItem:
  415. *
  416. * The abstract base type for tree-like structured schema components.
  417. * (Extends xmlSchemaAnnotItem)
  418. */
  419. typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  420. typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  421. struct _xmlSchemaTreeItem {
  422. xmlSchemaTypeType type;
  423. xmlSchemaAnnotPtr annot;
  424. xmlSchemaTreeItemPtr next;
  425. xmlSchemaTreeItemPtr children;
  426. };
  427. #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  428. /**
  429. * xmlSchemaAttributeUsePtr:
  430. *
  431. * The abstract base type for tree-like structured schema components.
  432. * (Extends xmlSchemaTreeItem)
  433. */
  434. typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  435. typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  436. struct _xmlSchemaAttributeUse {
  437. xmlSchemaTypeType type;
  438. xmlSchemaAnnotPtr annot;
  439. xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  440. /*
  441. * The attr. decl. OR a QName-ref. to an attr. decl. OR
  442. * a QName-ref. to an attribute group definition.
  443. */
  444. xmlSchemaAttributePtr attrDecl;
  445. int flags;
  446. xmlNodePtr node;
  447. int occurs; /* required, optional */
  448. const xmlChar * defValue;
  449. xmlSchemaValPtr defVal;
  450. };
  451. /**
  452. * xmlSchemaAttributeUseProhibPtr:
  453. *
  454. * A helper component to reflect attribute prohibitions.
  455. * (Extends xmlSchemaBasicItem)
  456. */
  457. typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  458. typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  459. struct _xmlSchemaAttributeUseProhib {
  460. xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  461. xmlNodePtr node;
  462. const xmlChar *name;
  463. const xmlChar *targetNamespace;
  464. int isRef;
  465. };
  466. /**
  467. * xmlSchemaRedef:
  468. */
  469. typedef struct _xmlSchemaRedef xmlSchemaRedef;
  470. typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  471. struct _xmlSchemaRedef {
  472. xmlSchemaRedefPtr next;
  473. xmlSchemaBasicItemPtr item; /* The redefining component. */
  474. xmlSchemaBasicItemPtr reference; /* The referencing component. */
  475. xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  476. const xmlChar *refName; /* The name of the to-be-redefined component. */
  477. const xmlChar *refTargetNs; /* The target namespace of the
  478. to-be-redefined comp. */
  479. xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  480. };
  481. /**
  482. * xmlSchemaConstructionCtxt:
  483. */
  484. typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  485. typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  486. struct _xmlSchemaConstructionCtxt {
  487. xmlSchemaPtr mainSchema; /* The main schema. */
  488. xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  489. xmlDictPtr dict;
  490. xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  491. /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  492. xmlSchemaBucketPtr bucket; /* The current schema bucket */
  493. xmlSchemaItemListPtr pending; /* All Components of all schemas that
  494. need to be fixed. */
  495. xmlHashTablePtr substGroups;
  496. xmlSchemaRedefPtr redefs;
  497. xmlSchemaRedefPtr lastRedef;
  498. };
  499. #define XML_SCHEMAS_PARSE_ERROR 1
  500. #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  501. struct _xmlSchemaParserCtxt {
  502. int type;
  503. void *errCtxt; /* user specific error context */
  504. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  505. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  506. int err;
  507. int nberrors;
  508. xmlStructuredErrorFunc serror;
  509. xmlSchemaConstructionCtxtPtr constructor;
  510. int ownsConstructor; /* TODO: Move this to parser *flags*. */
  511. /* xmlSchemaPtr topschema; */
  512. /* xmlHashTablePtr namespaces; */
  513. xmlSchemaPtr schema; /* The main schema in use */
  514. int counter;
  515. const xmlChar *URL;
  516. xmlDocPtr doc;
  517. int preserve; /* Whether the doc should be freed */
  518. const char *buffer;
  519. int size;
  520. /*
  521. * Used to build complex element content models
  522. */
  523. xmlAutomataPtr am;
  524. xmlAutomataStatePtr start;
  525. xmlAutomataStatePtr end;
  526. xmlAutomataStatePtr state;
  527. xmlDictPtr dict; /* dictionary for interned string names */
  528. xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  529. int options;
  530. xmlSchemaValidCtxtPtr vctxt;
  531. int isS4S;
  532. int isRedefine;
  533. int xsiAssemble;
  534. int stop; /* If the parser should stop; i.e. a critical error. */
  535. const xmlChar *targetNamespace;
  536. xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  537. xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  538. int redefCounter; /* Used for redefinitions. */
  539. xmlSchemaItemListPtr attrProhibs;
  540. };
  541. /**
  542. * xmlSchemaQNameRef:
  543. *
  544. * A component reference item (not a schema component)
  545. * (Extends xmlSchemaBasicItem)
  546. */
  547. typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  548. typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  549. struct _xmlSchemaQNameRef {
  550. xmlSchemaTypeType type;
  551. xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  552. xmlSchemaTypeType itemType;
  553. const xmlChar *name;
  554. const xmlChar *targetNamespace;
  555. xmlNodePtr node;
  556. };
  557. /**
  558. * xmlSchemaParticle:
  559. *
  560. * A particle component.
  561. * (Extends xmlSchemaTreeItem)
  562. */
  563. typedef struct _xmlSchemaParticle xmlSchemaParticle;
  564. typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  565. struct _xmlSchemaParticle {
  566. xmlSchemaTypeType type;
  567. xmlSchemaAnnotPtr annot;
  568. xmlSchemaTreeItemPtr next; /* next particle */
  569. xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  570. a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  571. etc.) */
  572. int minOccurs;
  573. int maxOccurs;
  574. xmlNodePtr node;
  575. };
  576. /**
  577. * xmlSchemaModelGroup:
  578. *
  579. * A model group component.
  580. * (Extends xmlSchemaTreeItem)
  581. */
  582. typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  583. typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  584. struct _xmlSchemaModelGroup {
  585. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  586. xmlSchemaAnnotPtr annot;
  587. xmlSchemaTreeItemPtr next; /* not used */
  588. xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  589. xmlNodePtr node;
  590. };
  591. #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  592. #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  593. /**
  594. * xmlSchemaModelGroupDef:
  595. *
  596. * A model group definition component.
  597. * (Extends xmlSchemaTreeItem)
  598. */
  599. typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  600. typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  601. struct _xmlSchemaModelGroupDef {
  602. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  603. xmlSchemaAnnotPtr annot;
  604. xmlSchemaTreeItemPtr next; /* not used */
  605. xmlSchemaTreeItemPtr children; /* the "model group" */
  606. const xmlChar *name;
  607. const xmlChar *targetNamespace;
  608. xmlNodePtr node;
  609. int flags;
  610. };
  611. typedef struct _xmlSchemaIDC xmlSchemaIDC;
  612. typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  613. /**
  614. * xmlSchemaIDCSelect:
  615. *
  616. * The identity-constraint "field" and "selector" item, holding the
  617. * XPath expression.
  618. */
  619. typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  620. typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  621. struct _xmlSchemaIDCSelect {
  622. xmlSchemaIDCSelectPtr next;
  623. xmlSchemaIDCPtr idc;
  624. int index; /* an index position if significant for IDC key-sequences */
  625. const xmlChar *xpath; /* the XPath expression */
  626. void *xpathComp; /* the compiled XPath expression */
  627. };
  628. /**
  629. * xmlSchemaIDC:
  630. *
  631. * The identity-constraint definition component.
  632. * (Extends xmlSchemaAnnotItem)
  633. */
  634. struct _xmlSchemaIDC {
  635. xmlSchemaTypeType type;
  636. xmlSchemaAnnotPtr annot;
  637. xmlSchemaIDCPtr next;
  638. xmlNodePtr node;
  639. const xmlChar *name;
  640. const xmlChar *targetNamespace;
  641. xmlSchemaIDCSelectPtr selector;
  642. xmlSchemaIDCSelectPtr fields;
  643. int nbFields;
  644. xmlSchemaQNameRefPtr ref;
  645. };
  646. /**
  647. * xmlSchemaIDCAug:
  648. *
  649. * The augmented IDC information used for validation.
  650. */
  651. typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  652. typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  653. struct _xmlSchemaIDCAug {
  654. xmlSchemaIDCAugPtr next; /* next in a list */
  655. xmlSchemaIDCPtr def; /* the IDC definition */
  656. int keyrefDepth; /* the lowest tree level to which IDC
  657. tables need to be bubbled upwards */
  658. };
  659. /**
  660. * xmlSchemaPSVIIDCKeySequence:
  661. *
  662. * The key sequence of a node table item.
  663. */
  664. typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  665. typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  666. struct _xmlSchemaPSVIIDCKey {
  667. xmlSchemaTypePtr type;
  668. xmlSchemaValPtr val;
  669. };
  670. /**
  671. * xmlSchemaPSVIIDCNode:
  672. *
  673. * The node table item of a node table.
  674. */
  675. typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  676. typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  677. struct _xmlSchemaPSVIIDCNode {
  678. xmlNodePtr node;
  679. xmlSchemaPSVIIDCKeyPtr *keys;
  680. int nodeLine;
  681. int nodeQNameID;
  682. };
  683. /**
  684. * xmlSchemaPSVIIDCBinding:
  685. *
  686. * The identity-constraint binding item of the [identity-constraint table].
  687. */
  688. typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  689. typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  690. struct _xmlSchemaPSVIIDCBinding {
  691. xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  692. xmlSchemaIDCPtr definition; /* the IDC definition */
  693. xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  694. int nbNodes; /* number of entries in the node table */
  695. int sizeNodes; /* size of the node table */
  696. xmlSchemaItemListPtr dupls;
  697. };
  698. #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  699. #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  700. #define XPATH_STATE_OBJ_MATCHES -2
  701. #define XPATH_STATE_OBJ_BLOCKED -3
  702. typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  703. typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  704. /**
  705. * xmlSchemaIDCStateObj:
  706. *
  707. * The state object used to evaluate XPath expressions.
  708. */
  709. typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  710. typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  711. struct _xmlSchemaIDCStateObj {
  712. int type;
  713. xmlSchemaIDCStateObjPtr next; /* next if in a list */
  714. int depth; /* depth of creation */
  715. int *history; /* list of (depth, state-id) tuples */
  716. int nbHistory;
  717. int sizeHistory;
  718. xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  719. matcher */
  720. xmlSchemaIDCSelectPtr sel;
  721. void *xpathCtxt;
  722. };
  723. #define IDC_MATCHER 0
  724. /**
  725. * xmlSchemaIDCMatcher:
  726. *
  727. * Used to evaluate IDC selectors (and fields).
  728. */
  729. struct _xmlSchemaIDCMatcher {
  730. int type;
  731. int depth; /* the tree depth at creation time */
  732. xmlSchemaIDCMatcherPtr next; /* next in the list */
  733. xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  734. xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  735. int idcType;
  736. xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  737. elements */
  738. int sizeKeySeqs;
  739. xmlSchemaItemListPtr targets; /* list of target-node
  740. (xmlSchemaPSVIIDCNodePtr) entries */
  741. xmlHashTablePtr htab;
  742. };
  743. /*
  744. * Element info flags.
  745. */
  746. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
  747. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  748. #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
  749. #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
  750. #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
  751. #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
  752. #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
  753. #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
  754. #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
  755. #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
  756. #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
  757. /**
  758. * xmlSchemaNodeInfo:
  759. *
  760. * Holds information of an element node.
  761. */
  762. struct _xmlSchemaNodeInfo {
  763. int nodeType;
  764. xmlNodePtr node;
  765. int nodeLine;
  766. const xmlChar *localName;
  767. const xmlChar *nsName;
  768. const xmlChar *value;
  769. xmlSchemaValPtr val; /* the pre-computed value if any */
  770. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  771. int flags; /* combination of node info flags */
  772. int valNeeded;
  773. int normVal;
  774. xmlSchemaElementPtr decl; /* the element/attribute declaration */
  775. int depth;
  776. xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  777. for the scope element*/
  778. xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  779. element */
  780. xmlRegExecCtxtPtr regexCtxt;
  781. const xmlChar **nsBindings; /* Namespace bindings on this element */
  782. int nbNsBindings;
  783. int sizeNsBindings;
  784. int hasKeyrefs;
  785. int appliedXPath; /* Indicates that an XPath has been applied. */
  786. };
  787. #define XML_SCHEMAS_ATTR_UNKNOWN 1
  788. #define XML_SCHEMAS_ATTR_ASSESSED 2
  789. #define XML_SCHEMAS_ATTR_PROHIBITED 3
  790. #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  791. #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  792. #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  793. #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  794. #define XML_SCHEMAS_ATTR_DEFAULT 8
  795. #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  796. #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  797. #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  798. #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  799. #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  800. #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  801. #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  802. #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  803. #define XML_SCHEMAS_ATTR_META 17
  804. /*
  805. * @metaType values of xmlSchemaAttrInfo.
  806. */
  807. #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  808. #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  809. #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  810. #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  811. #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  812. typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  813. typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  814. struct _xmlSchemaAttrInfo {
  815. int nodeType;
  816. xmlNodePtr node;
  817. int nodeLine;
  818. const xmlChar *localName;
  819. const xmlChar *nsName;
  820. const xmlChar *value;
  821. xmlSchemaValPtr val; /* the pre-computed value if any */
  822. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  823. int flags; /* combination of node info flags */
  824. xmlSchemaAttributePtr decl; /* the attribute declaration */
  825. xmlSchemaAttributeUsePtr use; /* the attribute use */
  826. int state;
  827. int metaType;
  828. const xmlChar *vcValue; /* the value constraint value */
  829. xmlSchemaNodeInfoPtr parent;
  830. };
  831. #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  832. /**
  833. * xmlSchemaValidCtxt:
  834. *
  835. * A Schemas validation context
  836. */
  837. struct _xmlSchemaValidCtxt {
  838. int type;
  839. void *errCtxt; /* user specific data block */
  840. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  841. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  842. xmlStructuredErrorFunc serror;
  843. xmlSchemaPtr schema; /* The schema in use */
  844. xmlDocPtr doc;
  845. xmlParserInputBufferPtr input;
  846. xmlCharEncoding enc;
  847. xmlSAXHandlerPtr sax;
  848. xmlParserCtxtPtr parserCtxt;
  849. void *user_data; /* TODO: What is this for? */
  850. char *filename;
  851. int err;
  852. int nberrors;
  853. xmlNodePtr node;
  854. xmlNodePtr cur;
  855. /* xmlSchemaTypePtr type; */
  856. xmlRegExecCtxtPtr regexp;
  857. xmlSchemaValPtr value;
  858. int valueWS;
  859. int options;
  860. xmlNodePtr validationRoot;
  861. xmlSchemaParserCtxtPtr pctxt;
  862. int xsiAssemble;
  863. int depth;
  864. xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
  865. int sizeElemInfos;
  866. xmlSchemaNodeInfoPtr inode; /* the current element information */
  867. xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
  868. xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
  869. xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
  870. xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
  871. xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
  872. int nbIdcNodes;
  873. int sizeIdcNodes;
  874. xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
  875. int nbIdcKeys;
  876. int sizeIdcKeys;
  877. int flags;
  878. xmlDictPtr dict;
  879. #ifdef LIBXML_READER_ENABLED
  880. xmlTextReaderPtr reader;
  881. #endif
  882. xmlSchemaAttrInfoPtr *attrInfos;
  883. int nbAttrInfos;
  884. int sizeAttrInfos;
  885. int skipDepth;
  886. xmlSchemaItemListPtr nodeQNames;
  887. int hasKeyrefs;
  888. int createIDCNodeTables;
  889. int psviExposeIDCNodeTables;
  890. /* Locator for error reporting in streaming mode */
  891. xmlSchemaValidityLocatorFunc locFunc;
  892. void *locCtxt;
  893. };
  894. /**
  895. * xmlSchemaSubstGroup:
  896. *
  897. *
  898. */
  899. typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
  900. typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
  901. struct _xmlSchemaSubstGroup {
  902. xmlSchemaElementPtr head;
  903. xmlSchemaItemListPtr members;
  904. };
  905. /**
  906. * xmlIDCHashEntry:
  907. *
  908. * an entry in hash tables to quickly look up keys/uniques
  909. */
  910. typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
  911. typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
  912. struct _xmlIDCHashEntry {
  913. xmlIDCHashEntryPtr next; /* next item with same hash */
  914. int index; /* index into associated item list */
  915. };
  916. /************************************************************************
  917. * *
  918. * Some predeclarations *
  919. * *
  920. ************************************************************************/
  921. static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
  922. xmlSchemaPtr schema,
  923. xmlNodePtr node);
  924. static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
  925. xmlSchemaPtr schema,
  926. xmlNodePtr node);
  927. static int
  928. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  929. xmlSchemaAbstractCtxtPtr ctxt);
  930. static const xmlChar *
  931. xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
  932. static int
  933. xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  934. xmlNodePtr node);
  935. static int
  936. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  937. xmlSchemaParserCtxtPtr ctxt);
  938. static void
  939. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
  940. static xmlSchemaWhitespaceValueType
  941. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
  942. static xmlSchemaTreeItemPtr
  943. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  944. xmlNodePtr node, xmlSchemaTypeType type,
  945. int withParticle);
  946. static const xmlChar *
  947. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
  948. static xmlSchemaTypeLinkPtr
  949. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
  950. static void
  951. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  952. const char *funcName,
  953. const char *message) LIBXML_ATTR_FORMAT(3,0);
  954. static int
  955. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
  956. xmlSchemaTypePtr type,
  957. xmlSchemaTypePtr baseType,
  958. int subset);
  959. static void
  960. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  961. xmlSchemaParserCtxtPtr ctxt);
  962. static void
  963. xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
  964. static xmlSchemaQNameRefPtr
  965. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  966. xmlSchemaPtr schema,
  967. xmlNodePtr node);
  968. /************************************************************************
  969. * *
  970. * Helper functions *
  971. * *
  972. ************************************************************************/
  973. /**
  974. * xmlSchemaItemTypeToStr:
  975. * @type: the type of the schema item
  976. *
  977. * Returns the component name of a schema item.
  978. */
  979. static const xmlChar *
  980. xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
  981. {
  982. switch (type) {
  983. case XML_SCHEMA_TYPE_BASIC:
  984. return(BAD_CAST "simple type definition");
  985. case XML_SCHEMA_TYPE_SIMPLE:
  986. return(BAD_CAST "simple type definition");
  987. case XML_SCHEMA_TYPE_COMPLEX:
  988. return(BAD_CAST "complex type definition");
  989. case XML_SCHEMA_TYPE_ELEMENT:
  990. return(BAD_CAST "element declaration");
  991. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  992. return(BAD_CAST "attribute use");
  993. case XML_SCHEMA_TYPE_ATTRIBUTE:
  994. return(BAD_CAST "attribute declaration");
  995. case XML_SCHEMA_TYPE_GROUP:
  996. return(BAD_CAST "model group definition");
  997. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  998. return(BAD_CAST "attribute group definition");
  999. case XML_SCHEMA_TYPE_NOTATION:
  1000. return(BAD_CAST "notation declaration");
  1001. case XML_SCHEMA_TYPE_SEQUENCE:
  1002. return(BAD_CAST "model group (sequence)");
  1003. case XML_SCHEMA_TYPE_CHOICE:
  1004. return(BAD_CAST "model group (choice)");
  1005. case XML_SCHEMA_TYPE_ALL:
  1006. return(BAD_CAST "model group (all)");
  1007. case XML_SCHEMA_TYPE_PARTICLE:
  1008. return(BAD_CAST "particle");
  1009. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1010. return(BAD_CAST "unique identity-constraint");
  1011. /* return(BAD_CAST "IDC (unique)"); */
  1012. case XML_SCHEMA_TYPE_IDC_KEY:
  1013. return(BAD_CAST "key identity-constraint");
  1014. /* return(BAD_CAST "IDC (key)"); */
  1015. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1016. return(BAD_CAST "keyref identity-constraint");
  1017. /* return(BAD_CAST "IDC (keyref)"); */
  1018. case XML_SCHEMA_TYPE_ANY:
  1019. return(BAD_CAST "wildcard (any)");
  1020. case XML_SCHEMA_EXTRA_QNAMEREF:
  1021. return(BAD_CAST "[helper component] QName reference");
  1022. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  1023. return(BAD_CAST "[helper component] attribute use prohibition");
  1024. default:
  1025. return(BAD_CAST "Not a schema component");
  1026. }
  1027. }
  1028. /**
  1029. * xmlSchemaGetComponentTypeStr:
  1030. * @type: the type of the schema item
  1031. *
  1032. * Returns the component name of a schema item.
  1033. */
  1034. static const xmlChar *
  1035. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
  1036. {
  1037. switch (item->type) {
  1038. case XML_SCHEMA_TYPE_BASIC:
  1039. if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
  1040. return(BAD_CAST "complex type definition");
  1041. else
  1042. return(BAD_CAST "simple type definition");
  1043. default:
  1044. return(xmlSchemaItemTypeToStr(item->type));
  1045. }
  1046. }
  1047. /**
  1048. * xmlSchemaGetComponentNode:
  1049. * @item: a schema component
  1050. *
  1051. * Returns node associated with the schema component.
  1052. * NOTE that such a node need not be available; plus, a component's
  1053. * node need not to reflect the component directly, since there is no
  1054. * one-to-one relationship between the XML Schema representation and
  1055. * the component representation.
  1056. */
  1057. static xmlNodePtr
  1058. xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
  1059. {
  1060. switch (item->type) {
  1061. case XML_SCHEMA_TYPE_ELEMENT:
  1062. return (((xmlSchemaElementPtr) item)->node);
  1063. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1064. return (((xmlSchemaAttributePtr) item)->node);
  1065. case XML_SCHEMA_TYPE_COMPLEX:
  1066. case XML_SCHEMA_TYPE_SIMPLE:
  1067. return (((xmlSchemaTypePtr) item)->node);
  1068. case XML_SCHEMA_TYPE_ANY:
  1069. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1070. return (((xmlSchemaWildcardPtr) item)->node);
  1071. case XML_SCHEMA_TYPE_PARTICLE:
  1072. return (((xmlSchemaParticlePtr) item)->node);
  1073. case XML_SCHEMA_TYPE_SEQUENCE:
  1074. case XML_SCHEMA_TYPE_CHOICE:
  1075. case XML_SCHEMA_TYPE_ALL:
  1076. return (((xmlSchemaModelGroupPtr) item)->node);
  1077. case XML_SCHEMA_TYPE_GROUP:
  1078. return (((xmlSchemaModelGroupDefPtr) item)->node);
  1079. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1080. return (((xmlSchemaAttributeGroupPtr) item)->node);
  1081. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1082. case XML_SCHEMA_TYPE_IDC_KEY:
  1083. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1084. return (((xmlSchemaIDCPtr) item)->node);
  1085. case XML_SCHEMA_EXTRA_QNAMEREF:
  1086. return(((xmlSchemaQNameRefPtr) item)->node);
  1087. /* TODO: What to do with NOTATIONs?
  1088. case XML_SCHEMA_TYPE_NOTATION:
  1089. return (((xmlSchemaNotationPtr) item)->node);
  1090. */
  1091. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1092. return (((xmlSchemaAttributeUsePtr) item)->node);
  1093. default:
  1094. return (NULL);
  1095. }
  1096. }
  1097. #if 0
  1098. /**
  1099. * xmlSchemaGetNextComponent:
  1100. * @item: a schema component
  1101. *
  1102. * Returns the next sibling of the schema component.
  1103. */
  1104. static xmlSchemaBasicItemPtr
  1105. xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
  1106. {
  1107. switch (item->type) {
  1108. case XML_SCHEMA_TYPE_ELEMENT:
  1109. return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
  1110. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1111. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
  1112. case XML_SCHEMA_TYPE_COMPLEX:
  1113. case XML_SCHEMA_TYPE_SIMPLE:
  1114. return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
  1115. case XML_SCHEMA_TYPE_ANY:
  1116. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1117. return (NULL);
  1118. case XML_SCHEMA_TYPE_PARTICLE:
  1119. return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
  1120. case XML_SCHEMA_TYPE_SEQUENCE:
  1121. case XML_SCHEMA_TYPE_CHOICE:
  1122. case XML_SCHEMA_TYPE_ALL:
  1123. return (NULL);
  1124. case XML_SCHEMA_TYPE_GROUP:
  1125. return (NULL);
  1126. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1127. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
  1128. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1129. case XML_SCHEMA_TYPE_IDC_KEY:
  1130. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1131. return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
  1132. default:
  1133. return (NULL);
  1134. }
  1135. }
  1136. #endif
  1137. /**
  1138. * xmlSchemaFormatQName:
  1139. * @buf: the string buffer
  1140. * @namespaceName: the namespace name
  1141. * @localName: the local name
  1142. *
  1143. * Returns the given QName in the format "{namespaceName}localName" or
  1144. * just "localName" if @namespaceName is NULL.
  1145. *
  1146. * Returns the localName if @namespaceName is NULL, a formatted
  1147. * string otherwise.
  1148. */
  1149. static const xmlChar*
  1150. xmlSchemaFormatQName(xmlChar **buf,
  1151. const xmlChar *namespaceName,
  1152. const xmlChar *localName)
  1153. {
  1154. FREE_AND_NULL(*buf)
  1155. if (namespaceName != NULL) {
  1156. *buf = xmlStrdup(BAD_CAST "{");
  1157. *buf = xmlStrcat(*buf, namespaceName);
  1158. *buf = xmlStrcat(*buf, BAD_CAST "}");
  1159. }
  1160. if (localName != NULL) {
  1161. if (namespaceName == NULL)
  1162. return(localName);
  1163. *buf = xmlStrcat(*buf, localName);
  1164. } else {
  1165. *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
  1166. }
  1167. return ((const xmlChar *) *buf);
  1168. }
  1169. static const xmlChar*
  1170. xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
  1171. {
  1172. if (ns != NULL)
  1173. return (xmlSchemaFormatQName(buf, ns->href, localName));
  1174. else
  1175. return (xmlSchemaFormatQName(buf, NULL, localName));
  1176. }
  1177. static const xmlChar *
  1178. xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
  1179. {
  1180. if (item == NULL) {
  1181. return (NULL);
  1182. }
  1183. switch (item->type) {
  1184. case XML_SCHEMA_TYPE_ELEMENT:
  1185. return (((xmlSchemaElementPtr) item)->name);
  1186. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1187. return (((xmlSchemaAttributePtr) item)->name);
  1188. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1189. return (((xmlSchemaAttributeGroupPtr) item)->name);
  1190. case XML_SCHEMA_TYPE_BASIC:
  1191. case XML_SCHEMA_TYPE_SIMPLE:
  1192. case XML_SCHEMA_TYPE_COMPLEX:
  1193. return (((xmlSchemaTypePtr) item)->name);
  1194. case XML_SCHEMA_TYPE_GROUP:
  1195. return (((xmlSchemaModelGroupDefPtr) item)->name);
  1196. case XML_SCHEMA_TYPE_IDC_KEY:
  1197. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1198. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1199. return (((xmlSchemaIDCPtr) item)->name);
  1200. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1201. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1202. return(xmlSchemaGetComponentName(
  1203. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1204. } else
  1205. return(NULL);
  1206. case XML_SCHEMA_EXTRA_QNAMEREF:
  1207. return (((xmlSchemaQNameRefPtr) item)->name);
  1208. case XML_SCHEMA_TYPE_NOTATION:
  1209. return (((xmlSchemaNotationPtr) item)->name);
  1210. default:
  1211. /*
  1212. * Other components cannot have names.
  1213. */
  1214. break;
  1215. }
  1216. return (NULL);
  1217. }
  1218. #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
  1219. #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
  1220. /*
  1221. static const xmlChar *
  1222. xmlSchemaGetQNameRefName(void *ref)
  1223. {
  1224. return(((xmlSchemaQNameRefPtr) ref)->name);
  1225. }
  1226. static const xmlChar *
  1227. xmlSchemaGetQNameRefTargetNs(void *ref)
  1228. {
  1229. return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
  1230. }
  1231. */
  1232. static const xmlChar *
  1233. xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
  1234. {
  1235. if (item == NULL) {
  1236. return (NULL);
  1237. }
  1238. switch (item->type) {
  1239. case XML_SCHEMA_TYPE_ELEMENT:
  1240. return (((xmlSchemaElementPtr) item)->targetNamespace);
  1241. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1242. return (((xmlSchemaAttributePtr) item)->targetNamespace);
  1243. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1244. return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
  1245. case XML_SCHEMA_TYPE_BASIC:
  1246. return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
  1247. case XML_SCHEMA_TYPE_SIMPLE:
  1248. case XML_SCHEMA_TYPE_COMPLEX:
  1249. return (((xmlSchemaTypePtr) item)->targetNamespace);
  1250. case XML_SCHEMA_TYPE_GROUP:
  1251. return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
  1252. case XML_SCHEMA_TYPE_IDC_KEY:
  1253. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1254. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1255. return (((xmlSchemaIDCPtr) item)->targetNamespace);
  1256. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1257. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1258. return(xmlSchemaGetComponentTargetNs(
  1259. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1260. }
  1261. /* TODO: Will returning NULL break something? */
  1262. break;
  1263. case XML_SCHEMA_EXTRA_QNAMEREF:
  1264. return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
  1265. case XML_SCHEMA_TYPE_NOTATION:
  1266. return (((xmlSchemaNotationPtr) item)->targetNamespace);
  1267. default:
  1268. /*
  1269. * Other components cannot have names.
  1270. */
  1271. break;
  1272. }
  1273. return (NULL);
  1274. }
  1275. static const xmlChar*
  1276. xmlSchemaGetComponentQName(xmlChar **buf,
  1277. void *item)
  1278. {
  1279. return (xmlSchemaFormatQName(buf,
  1280. xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
  1281. xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
  1282. }
  1283. static const xmlChar*
  1284. xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
  1285. {
  1286. xmlChar *str = NULL;
  1287. *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
  1288. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1289. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
  1290. (xmlSchemaBasicItemPtr) item));
  1291. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1292. FREE_AND_NULL(str);
  1293. return(*buf);
  1294. }
  1295. static const xmlChar*
  1296. xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
  1297. {
  1298. return(xmlSchemaGetComponentDesignation(buf, idc));
  1299. }
  1300. /**
  1301. * xmlSchemaWildcardPCToString:
  1302. * @pc: the type of processContents
  1303. *
  1304. * Returns a string representation of the type of
  1305. * processContents.
  1306. */
  1307. static const xmlChar *
  1308. xmlSchemaWildcardPCToString(int pc)
  1309. {
  1310. switch (pc) {
  1311. case XML_SCHEMAS_ANY_SKIP:
  1312. return (BAD_CAST "skip");
  1313. case XML_SCHEMAS_ANY_LAX:
  1314. return (BAD_CAST "lax");
  1315. case XML_SCHEMAS_ANY_STRICT:
  1316. return (BAD_CAST "strict");
  1317. default:
  1318. return (BAD_CAST "invalid process contents");
  1319. }
  1320. }
  1321. /**
  1322. * xmlSchemaGetCanonValueWhtspExt:
  1323. * @val: the precomputed value
  1324. * @retValue: the returned value
  1325. * @ws: the whitespace type of the value
  1326. * @for_hash: non-zero if this is supposed to generate a string for hashing
  1327. *
  1328. * Get a the canonical representation of the value.
  1329. * The caller has to free the returned retValue.
  1330. *
  1331. * Returns 0 if the value could be built and -1 in case of
  1332. * API errors or if the value type is not supported yet.
  1333. */
  1334. static int
  1335. xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
  1336. xmlSchemaWhitespaceValueType ws,
  1337. xmlChar **retValue,
  1338. int for_hash)
  1339. {
  1340. int list;
  1341. xmlSchemaValType valType;
  1342. const xmlChar *value, *value2 = NULL;
  1343. if ((retValue == NULL) || (val == NULL))
  1344. return (-1);
  1345. list = xmlSchemaValueGetNext(val) ? 1 : 0;
  1346. *retValue = NULL;
  1347. do {
  1348. value = NULL;
  1349. valType = xmlSchemaGetValType(val);
  1350. switch (valType) {
  1351. case XML_SCHEMAS_STRING:
  1352. case XML_SCHEMAS_NORMSTRING:
  1353. case XML_SCHEMAS_ANYSIMPLETYPE:
  1354. value = xmlSchemaValueGetAsString(val);
  1355. if (value != NULL) {
  1356. if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
  1357. value2 = xmlSchemaCollapseString(value);
  1358. else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
  1359. value2 = xmlSchemaWhiteSpaceReplace(value);
  1360. if (value2 != NULL)
  1361. value = value2;
  1362. }
  1363. break;
  1364. default:
  1365. if (xmlSchemaGetCanonValue(val, &value2) == -1) {
  1366. if (value2 != NULL)
  1367. xmlFree((xmlChar *) value2);
  1368. goto internal_error;
  1369. }
  1370. if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
  1371. /* We can mostly use the canonical value for hashing,
  1372. except in the case of decimal. There the canonical
  1373. representation requires a trailing '.0' even for
  1374. non-fractional numbers, but for the derived integer
  1375. types it forbids any decimal point. Nevertheless they
  1376. compare equal if the value is equal. We need to generate
  1377. the same hash value for this to work, and it's easiest
  1378. to just cut off the useless '.0' suffix for the
  1379. decimal type. */
  1380. int len = xmlStrlen(value2);
  1381. if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
  1382. ((xmlChar*)value2)[len-2] = 0;
  1383. }
  1384. value = value2;
  1385. }
  1386. if (*retValue == NULL)
  1387. if (value == NULL) {
  1388. if (! list)
  1389. *retValue = xmlStrdup(BAD_CAST "");
  1390. } else
  1391. *retValue = xmlStrdup(value);
  1392. else if (value != NULL) {
  1393. /* List. */
  1394. *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
  1395. *retValue = xmlStrcat((xmlChar *) *retValue, value);
  1396. }
  1397. FREE_AND_NULL(value2)
  1398. val = xmlSchemaValueGetNext(val);
  1399. } while (val != NULL);
  1400. return (0);
  1401. internal_error:
  1402. if (*retValue != NULL)
  1403. xmlFree((xmlChar *) (*retValue));
  1404. if (value2 != NULL)
  1405. xmlFree((xmlChar *) value2);
  1406. return (-1);
  1407. }
  1408. static int
  1409. xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
  1410. xmlSchemaWhitespaceValueType ws,
  1411. xmlChar **retValue)
  1412. {
  1413. return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
  1414. }
  1415. static int
  1416. xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
  1417. xmlChar **retValue)
  1418. {
  1419. return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
  1420. retValue, 1);
  1421. }
  1422. /**
  1423. * xmlSchemaFormatItemForReport:
  1424. * @buf: the string buffer
  1425. * @itemDes: the designation of the item
  1426. * @itemName: the name of the item
  1427. * @item: the item as an object
  1428. * @itemNode: the node of the item
  1429. * @local: the local name
  1430. * @parsing: if the function is used during the parse
  1431. *
  1432. * Returns a representation of the given item used
  1433. * for error reports.
  1434. *
  1435. * The following order is used to build the resulting
  1436. * designation if the arguments are not NULL:
  1437. * 1a. If itemDes not NULL -> itemDes
  1438. * 1b. If (itemDes not NULL) and (itemName not NULL)
  1439. * -> itemDes + itemName
  1440. * 2. If the preceding was NULL and (item not NULL) -> item
  1441. * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
  1442. *
  1443. * If the itemNode is an attribute node, the name of the attribute
  1444. * will be appended to the result.
  1445. *
  1446. * Returns the formatted string and sets @buf to the resulting value.
  1447. */
  1448. static xmlChar*
  1449. xmlSchemaFormatItemForReport(xmlChar **buf,
  1450. const xmlChar *itemDes,
  1451. xmlSchemaBasicItemPtr item,
  1452. xmlNodePtr itemNode)
  1453. {
  1454. xmlChar *str = NULL;
  1455. int named = 1;
  1456. if (*buf != NULL) {
  1457. xmlFree(*buf);
  1458. *buf = NULL;
  1459. }
  1460. if (itemDes != NULL) {
  1461. *buf = xmlStrdup(itemDes);
  1462. } else if (item != NULL) {
  1463. switch (item->type) {
  1464. case XML_SCHEMA_TYPE_BASIC: {
  1465. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1466. if (WXS_IS_ATOMIC(type))
  1467. *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
  1468. else if (WXS_IS_LIST(type))
  1469. *buf = xmlStrdup(BAD_CAST "list type 'xs:");
  1470. else if (WXS_IS_UNION(type))
  1471. *buf = xmlStrdup(BAD_CAST "union type 'xs:");
  1472. else
  1473. *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
  1474. *buf = xmlStrcat(*buf, type->name);
  1475. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1476. }
  1477. break;
  1478. case XML_SCHEMA_TYPE_SIMPLE: {
  1479. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1480. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1481. *buf = xmlStrdup(BAD_CAST"");
  1482. } else {
  1483. *buf = xmlStrdup(BAD_CAST "local ");
  1484. }
  1485. if (WXS_IS_ATOMIC(type))
  1486. *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
  1487. else if (WXS_IS_LIST(type))
  1488. *buf = xmlStrcat(*buf, BAD_CAST "list type");
  1489. else if (WXS_IS_UNION(type))
  1490. *buf = xmlStrcat(*buf, BAD_CAST "union type");
  1491. else
  1492. *buf = xmlStrcat(*buf, BAD_CAST "simple type");
  1493. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1494. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1495. *buf = xmlStrcat(*buf, type->name);
  1496. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1497. }
  1498. }
  1499. break;
  1500. case XML_SCHEMA_TYPE_COMPLEX: {
  1501. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1502. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
  1503. *buf = xmlStrdup(BAD_CAST "");
  1504. else
  1505. *buf = xmlStrdup(BAD_CAST "local ");
  1506. *buf = xmlStrcat(*buf, BAD_CAST "complex type");
  1507. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1508. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1509. *buf = xmlStrcat(*buf, type->name);
  1510. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1511. }
  1512. }
  1513. break;
  1514. case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
  1515. xmlSchemaAttributeUsePtr ause;
  1516. ause = WXS_ATTR_USE_CAST item;
  1517. *buf = xmlStrdup(BAD_CAST "attribute use ");
  1518. if (WXS_ATTRUSE_DECL(ause) != NULL) {
  1519. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1520. *buf = xmlStrcat(*buf,
  1521. xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
  1522. FREE_AND_NULL(str)
  1523. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1524. } else {
  1525. *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
  1526. }
  1527. }
  1528. break;
  1529. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  1530. xmlSchemaAttributePtr attr;
  1531. attr = (xmlSchemaAttributePtr) item;
  1532. *buf = xmlStrdup(BAD_CAST "attribute decl.");
  1533. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1534. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1535. attr->targetNamespace, attr->name));
  1536. FREE_AND_NULL(str)
  1537. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1538. }
  1539. break;
  1540. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1541. xmlSchemaGetComponentDesignation(buf, item);
  1542. break;
  1543. case XML_SCHEMA_TYPE_ELEMENT: {
  1544. xmlSchemaElementPtr elem;
  1545. elem = (xmlSchemaElementPtr) item;
  1546. *buf = xmlStrdup(BAD_CAST "element decl.");
  1547. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1548. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1549. elem->targetNamespace, elem->name));
  1550. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1551. }
  1552. break;
  1553. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1554. case XML_SCHEMA_TYPE_IDC_KEY:
  1555. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1556. if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
  1557. *buf = xmlStrdup(BAD_CAST "unique '");
  1558. else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
  1559. *buf = xmlStrdup(BAD_CAST "key '");
  1560. else
  1561. *buf = xmlStrdup(BAD_CAST "keyRef '");
  1562. *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
  1563. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1564. break;
  1565. case XML_SCHEMA_TYPE_ANY:
  1566. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1567. *buf = xmlStrdup(xmlSchemaWildcardPCToString(
  1568. ((xmlSchemaWildcardPtr) item)->processContents));
  1569. *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
  1570. break;
  1571. case XML_SCHEMA_FACET_MININCLUSIVE:
  1572. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  1573. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  1574. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  1575. case XML_SCHEMA_FACET_TOTALDIGITS:
  1576. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  1577. case XML_SCHEMA_FACET_PATTERN:
  1578. case XML_SCHEMA_FACET_ENUMERATION:
  1579. case XML_SCHEMA_FACET_WHITESPACE:
  1580. case XML_SCHEMA_FACET_LENGTH:
  1581. case XML_SCHEMA_FACET_MAXLENGTH:
  1582. case XML_SCHEMA_FACET_MINLENGTH:
  1583. *buf = xmlStrdup(BAD_CAST "facet '");
  1584. *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
  1585. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1586. break;
  1587. case XML_SCHEMA_TYPE_GROUP: {
  1588. *buf = xmlStrdup(BAD_CAST "model group def.");
  1589. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1590. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1591. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1592. FREE_AND_NULL(str)
  1593. }
  1594. break;
  1595. case XML_SCHEMA_TYPE_SEQUENCE:
  1596. case XML_SCHEMA_TYPE_CHOICE:
  1597. case XML_SCHEMA_TYPE_ALL:
  1598. case XML_SCHEMA_TYPE_PARTICLE:
  1599. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1600. break;
  1601. case XML_SCHEMA_TYPE_NOTATION: {
  1602. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1603. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1604. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1605. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1606. FREE_AND_NULL(str);
  1607. }
  1608. /* Falls through. */
  1609. default:
  1610. named = 0;
  1611. }
  1612. } else
  1613. named = 0;
  1614. if ((named == 0) && (itemNode != NULL)) {
  1615. xmlNodePtr elem;
  1616. if (itemNode->type == XML_ATTRIBUTE_NODE)
  1617. elem = itemNode->parent;
  1618. else
  1619. elem = itemNode;
  1620. *buf = xmlStrdup(BAD_CAST "Element '");
  1621. if (elem->ns != NULL) {
  1622. *buf = xmlStrcat(*buf,
  1623. xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
  1624. FREE_AND_NULL(str)
  1625. } else
  1626. *buf = xmlStrcat(*buf, elem->name);
  1627. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1628. }
  1629. if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
  1630. *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
  1631. if (itemNode->ns != NULL) {
  1632. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1633. itemNode->ns->href, itemNode->name));
  1634. FREE_AND_NULL(str)
  1635. } else
  1636. *buf = xmlStrcat(*buf, itemNode->name);
  1637. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1638. }
  1639. FREE_AND_NULL(str)
  1640. return (xmlEscapeFormatString(buf));
  1641. }
  1642. /**
  1643. * xmlSchemaFormatFacetEnumSet:
  1644. * @buf: the string buffer
  1645. * @type: the type holding the enumeration facets
  1646. *
  1647. * Builds a string consisting of all enumeration elements.
  1648. *
  1649. * Returns a string of all enumeration elements.
  1650. */
  1651. static const xmlChar *
  1652. xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
  1653. xmlChar **buf, xmlSchemaTypePtr type)
  1654. {
  1655. xmlSchemaFacetPtr facet;
  1656. xmlSchemaWhitespaceValueType ws;
  1657. xmlChar *value = NULL;
  1658. int res, found = 0;
  1659. if (*buf != NULL)
  1660. xmlFree(*buf);
  1661. *buf = NULL;
  1662. do {
  1663. /*
  1664. * Use the whitespace type of the base type.
  1665. */
  1666. ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
  1667. for (facet = type->facets; facet != NULL; facet = facet->next) {
  1668. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  1669. continue;
  1670. found = 1;
  1671. res = xmlSchemaGetCanonValueWhtspExt(facet->val,
  1672. ws, &value);
  1673. if (res == -1) {
  1674. xmlSchemaInternalErr(actxt,
  1675. "xmlSchemaFormatFacetEnumSet",
  1676. "compute the canonical lexical representation");
  1677. if (*buf != NULL)
  1678. xmlFree(*buf);
  1679. *buf = NULL;
  1680. return (NULL);
  1681. }
  1682. if (*buf == NULL)
  1683. *buf = xmlStrdup(BAD_CAST "'");
  1684. else
  1685. *buf = xmlStrcat(*buf, BAD_CAST ", '");
  1686. *buf = xmlStrcat(*buf, BAD_CAST value);
  1687. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1688. if (value != NULL) {
  1689. xmlFree((xmlChar *)value);
  1690. value = NULL;
  1691. }
  1692. }
  1693. /*
  1694. * The enumeration facet of a type restricts the enumeration
  1695. * facet of the ancestor type; i.e., such restricted enumerations
  1696. * do not belong to the set of the given type. Thus we break
  1697. * on the first found enumeration.
  1698. */
  1699. if (found)
  1700. break;
  1701. type = type->baseType;
  1702. } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
  1703. return ((const xmlChar *) *buf);
  1704. }
  1705. /************************************************************************
  1706. * *
  1707. * Error functions *
  1708. * *
  1709. ************************************************************************/
  1710. #if 0
  1711. static void
  1712. xmlSchemaErrMemory(const char *msg)
  1713. {
  1714. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1715. msg);
  1716. }
  1717. #endif
  1718. static void
  1719. xmlSchemaPSimpleErr(const char *msg)
  1720. {
  1721. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1722. msg);
  1723. }
  1724. /**
  1725. * xmlSchemaPErrMemory:
  1726. * @node: a context node
  1727. * @extra: extra information
  1728. *
  1729. * Handle an out of memory condition
  1730. */
  1731. static void
  1732. xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
  1733. const char *extra, xmlNodePtr node)
  1734. {
  1735. if (ctxt != NULL)
  1736. ctxt->nberrors++;
  1737. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
  1738. extra);
  1739. }
  1740. /**
  1741. * xmlSchemaPErr:
  1742. * @ctxt: the parsing context
  1743. * @node: the context node
  1744. * @error: the error code
  1745. * @msg: the error message
  1746. * @str1: extra data
  1747. * @str2: extra data
  1748. *
  1749. * Handle a parser error
  1750. */
  1751. static void LIBXML_ATTR_FORMAT(4,0)
  1752. xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1753. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1754. {
  1755. xmlGenericErrorFunc channel = NULL;
  1756. xmlStructuredErrorFunc schannel = NULL;
  1757. void *data = NULL;
  1758. if (ctxt != NULL) {
  1759. ctxt->nberrors++;
  1760. ctxt->err = error;
  1761. channel = ctxt->error;
  1762. data = ctxt->errCtxt;
  1763. schannel = ctxt->serror;
  1764. }
  1765. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1766. error, XML_ERR_ERROR, NULL, 0,
  1767. (const char *) str1, (const char *) str2, NULL, 0, 0,
  1768. msg, str1, str2);
  1769. }
  1770. /**
  1771. * xmlSchemaPErr2:
  1772. * @ctxt: the parsing context
  1773. * @node: the context node
  1774. * @node: the current child
  1775. * @error: the error code
  1776. * @msg: the error message
  1777. * @str1: extra data
  1778. * @str2: extra data
  1779. *
  1780. * Handle a parser error
  1781. */
  1782. static void LIBXML_ATTR_FORMAT(5,0)
  1783. xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  1784. xmlNodePtr child, int error,
  1785. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1786. {
  1787. if (child != NULL)
  1788. xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
  1789. else
  1790. xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
  1791. }
  1792. /**
  1793. * xmlSchemaPErrExt:
  1794. * @ctxt: the parsing context
  1795. * @node: the context node
  1796. * @error: the error code
  1797. * @strData1: extra data
  1798. * @strData2: extra data
  1799. * @strData3: extra data
  1800. * @msg: the message
  1801. * @str1: extra parameter for the message display
  1802. * @str2: extra parameter for the message display
  1803. * @str3: extra parameter for the message display
  1804. * @str4: extra parameter for the message display
  1805. * @str5: extra parameter for the message display
  1806. *
  1807. * Handle a parser error
  1808. */
  1809. static void LIBXML_ATTR_FORMAT(7,0)
  1810. xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1811. const xmlChar * strData1, const xmlChar * strData2,
  1812. const xmlChar * strData3, const char *msg, const xmlChar * str1,
  1813. const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
  1814. const xmlChar * str5)
  1815. {
  1816. xmlGenericErrorFunc channel = NULL;
  1817. xmlStructuredErrorFunc schannel = NULL;
  1818. void *data = NULL;
  1819. if (ctxt != NULL) {
  1820. ctxt->nberrors++;
  1821. ctxt->err = error;
  1822. channel = ctxt->error;
  1823. data = ctxt->errCtxt;
  1824. schannel = ctxt->serror;
  1825. }
  1826. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1827. error, XML_ERR_ERROR, NULL, 0,
  1828. (const char *) strData1, (const char *) strData2,
  1829. (const char *) strData3, 0, 0, msg, str1, str2,
  1830. str3, str4, str5);
  1831. }
  1832. /************************************************************************
  1833. * *
  1834. * Allround error functions *
  1835. * *
  1836. ************************************************************************/
  1837. /**
  1838. * xmlSchemaVTypeErrMemory:
  1839. * @node: a context node
  1840. * @extra: extra information
  1841. *
  1842. * Handle an out of memory condition
  1843. */
  1844. static void
  1845. xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
  1846. const char *extra, xmlNodePtr node)
  1847. {
  1848. if (ctxt != NULL) {
  1849. ctxt->nberrors++;
  1850. ctxt->err = XML_SCHEMAV_INTERNAL;
  1851. }
  1852. __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
  1853. extra);
  1854. }
  1855. static void LIBXML_ATTR_FORMAT(2,0)
  1856. xmlSchemaPSimpleInternalErr(xmlNodePtr node,
  1857. const char *msg, const xmlChar *str)
  1858. {
  1859. __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
  1860. msg, (const char *) str);
  1861. }
  1862. #define WXS_ERROR_TYPE_ERROR 1
  1863. #define WXS_ERROR_TYPE_WARNING 2
  1864. /**
  1865. * xmlSchemaErr4Line:
  1866. * @ctxt: the validation context
  1867. * @errorLevel: the error level
  1868. * @error: the error code
  1869. * @node: the context node
  1870. * @line: the line number
  1871. * @msg: the error message
  1872. * @str1: extra data
  1873. * @str2: extra data
  1874. * @str3: extra data
  1875. * @str4: extra data
  1876. *
  1877. * Handle a validation error
  1878. */
  1879. static void LIBXML_ATTR_FORMAT(6,0)
  1880. xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
  1881. xmlErrorLevel errorLevel,
  1882. int error, xmlNodePtr node, int line, const char *msg,
  1883. const xmlChar *str1, const xmlChar *str2,
  1884. const xmlChar *str3, const xmlChar *str4)
  1885. {
  1886. xmlStructuredErrorFunc schannel = NULL;
  1887. xmlGenericErrorFunc channel = NULL;
  1888. void *data = NULL;
  1889. if (ctxt != NULL) {
  1890. if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1891. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
  1892. const char *file = NULL;
  1893. int col = 0;
  1894. if (errorLevel != XML_ERR_WARNING) {
  1895. vctxt->nberrors++;
  1896. vctxt->err = error;
  1897. channel = vctxt->error;
  1898. } else {
  1899. channel = vctxt->warning;
  1900. }
  1901. schannel = vctxt->serror;
  1902. data = vctxt->errCtxt;
  1903. /*
  1904. * Error node. If we specify a line number, then
  1905. * do not channel any node to the error function.
  1906. */
  1907. if (line == 0) {
  1908. if ((node == NULL) &&
  1909. (vctxt->depth >= 0) &&
  1910. (vctxt->inode != NULL)) {
  1911. node = vctxt->inode->node;
  1912. }
  1913. /*
  1914. * Get filename and line if no node-tree.
  1915. */
  1916. if ((node == NULL) &&
  1917. (vctxt->parserCtxt != NULL) &&
  1918. (vctxt->parserCtxt->input != NULL)) {
  1919. file = vctxt->parserCtxt->input->filename;
  1920. if (vctxt->inode != NULL) {
  1921. line = vctxt->inode->nodeLine;
  1922. col = 0;
  1923. } else {
  1924. /* This is inaccurate. */
  1925. line = vctxt->parserCtxt->input->line;
  1926. col = vctxt->parserCtxt->input->col;
  1927. }
  1928. }
  1929. } else {
  1930. /*
  1931. * Override the given node's (if any) position
  1932. * and channel only the given line number.
  1933. */
  1934. node = NULL;
  1935. /*
  1936. * Get filename.
  1937. */
  1938. if (vctxt->doc != NULL)
  1939. file = (const char *) vctxt->doc->URL;
  1940. else if ((vctxt->parserCtxt != NULL) &&
  1941. (vctxt->parserCtxt->input != NULL))
  1942. file = vctxt->parserCtxt->input->filename;
  1943. }
  1944. if (vctxt->locFunc != NULL) {
  1945. if ((file == NULL) || (line == 0)) {
  1946. unsigned long l;
  1947. const char *f;
  1948. vctxt->locFunc(vctxt->locCtxt, &f, &l);
  1949. if (file == NULL)
  1950. file = f;
  1951. if (line == 0)
  1952. line = (int) l;
  1953. }
  1954. }
  1955. if ((file == NULL) && (vctxt->filename != NULL))
  1956. file = vctxt->filename;
  1957. __xmlRaiseError(schannel, channel, data, ctxt,
  1958. node, XML_FROM_SCHEMASV,
  1959. error, errorLevel, file, line,
  1960. (const char *) str1, (const char *) str2,
  1961. (const char *) str3, 0, col, msg, str1, str2, str3, str4);
  1962. } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
  1963. xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
  1964. if (errorLevel != XML_ERR_WARNING) {
  1965. pctxt->nberrors++;
  1966. pctxt->err = error;
  1967. channel = pctxt->error;
  1968. } else {
  1969. channel = pctxt->warning;
  1970. }
  1971. schannel = pctxt->serror;
  1972. data = pctxt->errCtxt;
  1973. __xmlRaiseError(schannel, channel, data, ctxt,
  1974. node, XML_FROM_SCHEMASP, error,
  1975. errorLevel, NULL, 0,
  1976. (const char *) str1, (const char *) str2,
  1977. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1978. } else {
  1979. TODO
  1980. }
  1981. }
  1982. }
  1983. /**
  1984. * xmlSchemaErr3:
  1985. * @ctxt: the validation context
  1986. * @node: the context node
  1987. * @error: the error code
  1988. * @msg: the error message
  1989. * @str1: extra data
  1990. * @str2: extra data
  1991. * @str3: extra data
  1992. *
  1993. * Handle a validation error
  1994. */
  1995. static void LIBXML_ATTR_FORMAT(4,0)
  1996. xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
  1997. int error, xmlNodePtr node, const char *msg,
  1998. const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
  1999. {
  2000. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  2001. msg, str1, str2, str3, NULL);
  2002. }
  2003. static void LIBXML_ATTR_FORMAT(4,0)
  2004. xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
  2005. int error, xmlNodePtr node, const char *msg,
  2006. const xmlChar *str1, const xmlChar *str2,
  2007. const xmlChar *str3, const xmlChar *str4)
  2008. {
  2009. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  2010. msg, str1, str2, str3, str4);
  2011. }
  2012. static void LIBXML_ATTR_FORMAT(4,0)
  2013. xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
  2014. int error, xmlNodePtr node, const char *msg,
  2015. const xmlChar *str1, const xmlChar *str2)
  2016. {
  2017. xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
  2018. }
  2019. static xmlChar *
  2020. xmlSchemaFormatNodeForError(xmlChar ** msg,
  2021. xmlSchemaAbstractCtxtPtr actxt,
  2022. xmlNodePtr node)
  2023. {
  2024. xmlChar *str = NULL;
  2025. *msg = NULL;
  2026. if ((node != NULL) &&
  2027. (node->type != XML_ELEMENT_NODE) &&
  2028. (node->type != XML_ATTRIBUTE_NODE))
  2029. {
  2030. /*
  2031. * Don't try to format other nodes than element and
  2032. * attribute nodes.
  2033. * Play safe and return an empty string.
  2034. */
  2035. *msg = xmlStrdup(BAD_CAST "");
  2036. return(*msg);
  2037. }
  2038. if (node != NULL) {
  2039. /*
  2040. * Work on tree nodes.
  2041. */
  2042. if (node->type == XML_ATTRIBUTE_NODE) {
  2043. xmlNodePtr elem = node->parent;
  2044. *msg = xmlStrdup(BAD_CAST "Element '");
  2045. if (elem->ns != NULL)
  2046. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2047. elem->ns->href, elem->name));
  2048. else
  2049. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2050. NULL, elem->name));
  2051. FREE_AND_NULL(str);
  2052. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2053. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2054. } else {
  2055. *msg = xmlStrdup(BAD_CAST "Element '");
  2056. }
  2057. if (node->ns != NULL)
  2058. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2059. node->ns->href, node->name));
  2060. else
  2061. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2062. NULL, node->name));
  2063. FREE_AND_NULL(str);
  2064. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2065. } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  2066. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
  2067. /*
  2068. * Work on node infos.
  2069. */
  2070. if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
  2071. xmlSchemaNodeInfoPtr ielem =
  2072. vctxt->elemInfos[vctxt->depth];
  2073. *msg = xmlStrdup(BAD_CAST "Element '");
  2074. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2075. ielem->nsName, ielem->localName));
  2076. FREE_AND_NULL(str);
  2077. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2078. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2079. } else {
  2080. *msg = xmlStrdup(BAD_CAST "Element '");
  2081. }
  2082. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2083. vctxt->inode->nsName, vctxt->inode->localName));
  2084. FREE_AND_NULL(str);
  2085. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2086. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  2087. /*
  2088. * Hmm, no node while parsing?
  2089. * Return an empty string, in case NULL will break something.
  2090. */
  2091. *msg = xmlStrdup(BAD_CAST "");
  2092. } else {
  2093. TODO
  2094. return (NULL);
  2095. }
  2096. /*
  2097. * xmlSchemaFormatItemForReport() also returns an escaped format
  2098. * string, so do this before calling it below (in the future).
  2099. */
  2100. xmlEscapeFormatString(msg);
  2101. /*
  2102. * VAL TODO: The output of the given schema component is currently
  2103. * disabled.
  2104. */
  2105. #if 0
  2106. if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
  2107. *msg = xmlStrcat(*msg, BAD_CAST " [");
  2108. *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
  2109. NULL, type, NULL, 0));
  2110. FREE_AND_NULL(str)
  2111. *msg = xmlStrcat(*msg, BAD_CAST "]");
  2112. }
  2113. #endif
  2114. return (*msg);
  2115. }
  2116. static void LIBXML_ATTR_FORMAT(3,0)
  2117. xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
  2118. const char *funcName,
  2119. const char *message,
  2120. const xmlChar *str1,
  2121. const xmlChar *str2)
  2122. {
  2123. xmlChar *msg = NULL;
  2124. if (actxt == NULL)
  2125. return;
  2126. msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
  2127. msg = xmlStrcat(msg, BAD_CAST message);
  2128. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2129. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
  2130. xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
  2131. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2132. else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
  2133. xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
  2134. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2135. FREE_AND_NULL(msg)
  2136. }
  2137. static void LIBXML_ATTR_FORMAT(3,0)
  2138. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  2139. const char *funcName,
  2140. const char *message)
  2141. {
  2142. xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
  2143. }
  2144. #if 0
  2145. static void LIBXML_ATTR_FORMAT(3,0)
  2146. xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
  2147. const char *funcName,
  2148. const char *message,
  2149. const xmlChar *str1,
  2150. const xmlChar *str2)
  2151. {
  2152. xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
  2153. str1, str2);
  2154. }
  2155. #endif
  2156. static void LIBXML_ATTR_FORMAT(5,0)
  2157. xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
  2158. xmlParserErrors error,
  2159. xmlNodePtr node,
  2160. xmlSchemaBasicItemPtr item,
  2161. const char *message,
  2162. const xmlChar *str1, const xmlChar *str2,
  2163. const xmlChar *str3, const xmlChar *str4)
  2164. {
  2165. xmlChar *msg = NULL;
  2166. if ((node == NULL) && (item != NULL) &&
  2167. (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
  2168. node = WXS_ITEM_NODE(item);
  2169. xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
  2170. msg = xmlStrcat(msg, BAD_CAST ": ");
  2171. } else
  2172. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2173. msg = xmlStrcat(msg, (const xmlChar *) message);
  2174. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2175. xmlSchemaErr4(actxt, error, node,
  2176. (const char *) msg, str1, str2, str3, str4);
  2177. FREE_AND_NULL(msg)
  2178. }
  2179. static void LIBXML_ATTR_FORMAT(5,0)
  2180. xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
  2181. xmlParserErrors error,
  2182. xmlNodePtr node,
  2183. xmlSchemaBasicItemPtr item,
  2184. const char *message,
  2185. const xmlChar *str1,
  2186. const xmlChar *str2)
  2187. {
  2188. xmlSchemaCustomErr4(actxt, error, node, item,
  2189. message, str1, str2, NULL, NULL);
  2190. }
  2191. static void LIBXML_ATTR_FORMAT(5,0)
  2192. xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
  2193. xmlParserErrors error,
  2194. xmlNodePtr node,
  2195. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2196. const char *message,
  2197. const xmlChar *str1,
  2198. const xmlChar *str2,
  2199. const xmlChar *str3)
  2200. {
  2201. xmlChar *msg = NULL;
  2202. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2203. msg = xmlStrcat(msg, (const xmlChar *) message);
  2204. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2205. /* URGENT TODO: Set the error code to something sane. */
  2206. xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
  2207. (const char *) msg, str1, str2, str3, NULL);
  2208. FREE_AND_NULL(msg)
  2209. }
  2210. static void LIBXML_ATTR_FORMAT(5,0)
  2211. xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
  2212. xmlParserErrors error,
  2213. xmlSchemaPSVIIDCNodePtr idcNode,
  2214. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2215. const char *message,
  2216. const xmlChar *str1,
  2217. const xmlChar *str2)
  2218. {
  2219. xmlChar *msg = NULL, *qname = NULL;
  2220. msg = xmlStrdup(BAD_CAST "Element '%s': ");
  2221. msg = xmlStrcat(msg, (const xmlChar *) message);
  2222. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2223. xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
  2224. error, NULL, idcNode->nodeLine, (const char *) msg,
  2225. xmlSchemaFormatQName(&qname,
  2226. vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
  2227. vctxt->nodeQNames->items[idcNode->nodeQNameID]),
  2228. str1, str2, NULL);
  2229. FREE_AND_NULL(qname);
  2230. FREE_AND_NULL(msg);
  2231. }
  2232. static int
  2233. xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
  2234. xmlNodePtr node)
  2235. {
  2236. if (node != NULL)
  2237. return (node->type);
  2238. if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
  2239. (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
  2240. return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
  2241. return (-1);
  2242. }
  2243. static int
  2244. xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
  2245. {
  2246. switch (item->type) {
  2247. case XML_SCHEMA_TYPE_COMPLEX:
  2248. case XML_SCHEMA_TYPE_SIMPLE:
  2249. if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
  2250. return(1);
  2251. break;
  2252. case XML_SCHEMA_TYPE_GROUP:
  2253. return (1);
  2254. case XML_SCHEMA_TYPE_ELEMENT:
  2255. if ( ((xmlSchemaElementPtr) item)->flags &
  2256. XML_SCHEMAS_ELEM_GLOBAL)
  2257. return(1);
  2258. break;
  2259. case XML_SCHEMA_TYPE_ATTRIBUTE:
  2260. if ( ((xmlSchemaAttributePtr) item)->flags &
  2261. XML_SCHEMAS_ATTR_GLOBAL)
  2262. return(1);
  2263. break;
  2264. /* Note that attribute groups are always global. */
  2265. default:
  2266. return(1);
  2267. }
  2268. return (0);
  2269. }
  2270. static void
  2271. xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2272. xmlParserErrors error,
  2273. xmlNodePtr node,
  2274. const xmlChar *value,
  2275. xmlSchemaTypePtr type,
  2276. int displayValue)
  2277. {
  2278. xmlChar *msg = NULL;
  2279. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2280. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2281. XML_ATTRIBUTE_NODE))
  2282. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2283. else
  2284. msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
  2285. "value of ");
  2286. if (! xmlSchemaIsGlobalItem(type))
  2287. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2288. else
  2289. msg = xmlStrcat(msg, BAD_CAST "the ");
  2290. if (WXS_IS_ATOMIC(type))
  2291. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2292. else if (WXS_IS_LIST(type))
  2293. msg = xmlStrcat(msg, BAD_CAST "list type");
  2294. else if (WXS_IS_UNION(type))
  2295. msg = xmlStrcat(msg, BAD_CAST "union type");
  2296. if (xmlSchemaIsGlobalItem(type)) {
  2297. xmlChar *str = NULL;
  2298. msg = xmlStrcat(msg, BAD_CAST " '");
  2299. if (type->builtInType != 0) {
  2300. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2301. str = xmlStrdup(type->name);
  2302. } else {
  2303. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2304. if (!str)
  2305. str = xmlStrdup(qName);
  2306. }
  2307. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2308. msg = xmlStrcat(msg, BAD_CAST "'");
  2309. FREE_AND_NULL(str);
  2310. }
  2311. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2312. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2313. XML_ATTRIBUTE_NODE))
  2314. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2315. else
  2316. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2317. FREE_AND_NULL(msg)
  2318. }
  2319. static const xmlChar *
  2320. xmlSchemaFormatErrorNodeQName(xmlChar ** str,
  2321. xmlSchemaNodeInfoPtr ni,
  2322. xmlNodePtr node)
  2323. {
  2324. if (node != NULL) {
  2325. if (node->ns != NULL)
  2326. return (xmlSchemaFormatQName(str, node->ns->href, node->name));
  2327. else
  2328. return (xmlSchemaFormatQName(str, NULL, node->name));
  2329. } else if (ni != NULL)
  2330. return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
  2331. return (NULL);
  2332. }
  2333. static void
  2334. xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
  2335. xmlParserErrors error,
  2336. xmlSchemaAttrInfoPtr ni,
  2337. xmlNodePtr node)
  2338. {
  2339. xmlChar *msg = NULL, *str = NULL;
  2340. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2341. msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
  2342. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2343. xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
  2344. NULL);
  2345. FREE_AND_NULL(str)
  2346. FREE_AND_NULL(msg)
  2347. }
  2348. static void LIBXML_ATTR_FORMAT(5,0)
  2349. xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2350. xmlParserErrors error,
  2351. xmlNodePtr node,
  2352. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2353. const char *message,
  2354. int nbval,
  2355. int nbneg,
  2356. xmlChar **values)
  2357. {
  2358. xmlChar *str = NULL, *msg = NULL;
  2359. xmlChar *localName, *nsName;
  2360. const xmlChar *cur, *end;
  2361. int i;
  2362. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2363. msg = xmlStrcat(msg, (const xmlChar *) message);
  2364. msg = xmlStrcat(msg, BAD_CAST ".");
  2365. /*
  2366. * Note that is does not make sense to report that we have a
  2367. * wildcard here, since the wildcard might be unfolded into
  2368. * multiple transitions.
  2369. */
  2370. if (nbval + nbneg > 0) {
  2371. if (nbval + nbneg > 1) {
  2372. str = xmlStrdup(BAD_CAST " Expected is one of ( ");
  2373. } else
  2374. str = xmlStrdup(BAD_CAST " Expected is ( ");
  2375. nsName = NULL;
  2376. for (i = 0; i < nbval + nbneg; i++) {
  2377. cur = values[i];
  2378. if (cur == NULL)
  2379. continue;
  2380. if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
  2381. (cur[3] == ' ')) {
  2382. cur += 4;
  2383. str = xmlStrcat(str, BAD_CAST "##other");
  2384. }
  2385. /*
  2386. * Get the local name.
  2387. */
  2388. localName = NULL;
  2389. end = cur;
  2390. if (*end == '*') {
  2391. localName = xmlStrdup(BAD_CAST "*");
  2392. end++;
  2393. } else {
  2394. while ((*end != 0) && (*end != '|'))
  2395. end++;
  2396. localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
  2397. }
  2398. if (*end != 0) {
  2399. end++;
  2400. /*
  2401. * Skip "*|*" if they come with negated expressions, since
  2402. * they represent the same negated wildcard.
  2403. */
  2404. if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
  2405. /*
  2406. * Get the namespace name.
  2407. */
  2408. cur = end;
  2409. if (*end == '*') {
  2410. nsName = xmlStrdup(BAD_CAST "{*}");
  2411. } else {
  2412. while (*end != 0)
  2413. end++;
  2414. if (i >= nbval)
  2415. nsName = xmlStrdup(BAD_CAST "{##other:");
  2416. else
  2417. nsName = xmlStrdup(BAD_CAST "{");
  2418. nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
  2419. nsName = xmlStrcat(nsName, BAD_CAST "}");
  2420. }
  2421. str = xmlStrcat(str, BAD_CAST nsName);
  2422. FREE_AND_NULL(nsName)
  2423. } else {
  2424. FREE_AND_NULL(localName);
  2425. continue;
  2426. }
  2427. }
  2428. str = xmlStrcat(str, BAD_CAST localName);
  2429. FREE_AND_NULL(localName);
  2430. if (i < nbval + nbneg -1)
  2431. str = xmlStrcat(str, BAD_CAST ", ");
  2432. }
  2433. str = xmlStrcat(str, BAD_CAST " ).\n");
  2434. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2435. FREE_AND_NULL(str)
  2436. } else
  2437. msg = xmlStrcat(msg, BAD_CAST "\n");
  2438. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2439. xmlFree(msg);
  2440. }
  2441. static void LIBXML_ATTR_FORMAT(8,0)
  2442. xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
  2443. xmlParserErrors error,
  2444. xmlNodePtr node,
  2445. const xmlChar *value,
  2446. unsigned long length,
  2447. xmlSchemaTypePtr type,
  2448. xmlSchemaFacetPtr facet,
  2449. const char *message,
  2450. const xmlChar *str1,
  2451. const xmlChar *str2)
  2452. {
  2453. xmlChar *str = NULL, *msg = NULL;
  2454. xmlSchemaTypeType facetType;
  2455. int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
  2456. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2457. if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
  2458. facetType = XML_SCHEMA_FACET_ENUMERATION;
  2459. /*
  2460. * If enumerations are validated, one must not expect the
  2461. * facet to be given.
  2462. */
  2463. } else
  2464. facetType = facet->type;
  2465. msg = xmlStrcat(msg, BAD_CAST "[");
  2466. msg = xmlStrcat(msg, BAD_CAST "facet '");
  2467. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
  2468. msg = xmlStrcat(msg, BAD_CAST "'] ");
  2469. if (message == NULL) {
  2470. /*
  2471. * Use a default message.
  2472. */
  2473. if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
  2474. (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
  2475. (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
  2476. char len[25], actLen[25];
  2477. /* FIXME, TODO: What is the max expected string length of the
  2478. * this value?
  2479. */
  2480. if (nodeType == XML_ATTRIBUTE_NODE)
  2481. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
  2482. else
  2483. msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
  2484. snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
  2485. snprintf(actLen, 24, "%lu", length);
  2486. if (facetType == XML_SCHEMA_FACET_LENGTH)
  2487. msg = xmlStrcat(msg,
  2488. BAD_CAST "this differs from the allowed length of '%s'.\n");
  2489. else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
  2490. msg = xmlStrcat(msg,
  2491. BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
  2492. else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
  2493. msg = xmlStrcat(msg,
  2494. BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
  2495. if (nodeType == XML_ATTRIBUTE_NODE)
  2496. xmlSchemaErr3(actxt, error, node, (const char *) msg,
  2497. value, (const xmlChar *) actLen, (const xmlChar *) len);
  2498. else
  2499. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2500. (const xmlChar *) actLen, (const xmlChar *) len);
  2501. } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
  2502. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
  2503. "of the set {%s}.\n");
  2504. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2505. xmlSchemaFormatFacetEnumSet(actxt, &str, type));
  2506. } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
  2507. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
  2508. "by the pattern '%s'.\n");
  2509. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2510. facet->value);
  2511. } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
  2512. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
  2513. "minimum value allowed ('%s').\n");
  2514. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2515. facet->value);
  2516. } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
  2517. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
  2518. "maximum value allowed ('%s').\n");
  2519. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2520. facet->value);
  2521. } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
  2522. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
  2523. "'%s'.\n");
  2524. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2525. facet->value);
  2526. } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
  2527. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
  2528. "'%s'.\n");
  2529. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2530. facet->value);
  2531. } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
  2532. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
  2533. "digits than are allowed ('%s').\n");
  2534. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2535. facet->value);
  2536. } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
  2537. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
  2538. "digits than are allowed ('%s').\n");
  2539. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2540. facet->value);
  2541. } else if (nodeType == XML_ATTRIBUTE_NODE) {
  2542. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
  2543. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2544. } else {
  2545. msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
  2546. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2547. }
  2548. } else {
  2549. msg = xmlStrcat(msg, (const xmlChar *) message);
  2550. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2551. xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
  2552. }
  2553. FREE_AND_NULL(str)
  2554. xmlFree(msg);
  2555. }
  2556. #define VERROR(err, type, msg) \
  2557. xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
  2558. #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
  2559. #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
  2560. #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
  2561. #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
  2562. /**
  2563. * xmlSchemaPMissingAttrErr:
  2564. * @ctxt: the schema validation context
  2565. * @ownerItem: the owner as a schema object
  2566. * @ownerElem: the owner as an element node
  2567. * @node: the parent element node of the missing attribute node
  2568. * @type: the corresponding type of the attribute node
  2569. *
  2570. * Reports an illegal attribute.
  2571. */
  2572. static void
  2573. xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2574. xmlParserErrors error,
  2575. xmlSchemaBasicItemPtr ownerItem,
  2576. xmlNodePtr ownerElem,
  2577. const char *name,
  2578. const char *message)
  2579. {
  2580. xmlChar *des = NULL;
  2581. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2582. if (message != NULL)
  2583. xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
  2584. else
  2585. xmlSchemaPErr(ctxt, ownerElem, error,
  2586. "%s: The attribute '%s' is required but missing.\n",
  2587. BAD_CAST des, BAD_CAST name);
  2588. FREE_AND_NULL(des);
  2589. }
  2590. /**
  2591. * xmlSchemaPResCompAttrErr:
  2592. * @ctxt: the schema validation context
  2593. * @error: the error code
  2594. * @ownerItem: the owner as a schema object
  2595. * @ownerElem: the owner as an element node
  2596. * @name: the name of the attribute holding the QName
  2597. * @refName: the referenced local name
  2598. * @refURI: the referenced namespace URI
  2599. * @message: optional message
  2600. *
  2601. * Used to report QName attribute values that failed to resolve
  2602. * to schema components.
  2603. */
  2604. static void
  2605. xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2606. xmlParserErrors error,
  2607. xmlSchemaBasicItemPtr ownerItem,
  2608. xmlNodePtr ownerElem,
  2609. const char *name,
  2610. const xmlChar *refName,
  2611. const xmlChar *refURI,
  2612. xmlSchemaTypeType refType,
  2613. const char *refTypeStr)
  2614. {
  2615. xmlChar *des = NULL, *strA = NULL;
  2616. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2617. if (refTypeStr == NULL)
  2618. refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
  2619. xmlSchemaPErrExt(ctxt, ownerElem, error,
  2620. NULL, NULL, NULL,
  2621. "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
  2622. "%s.\n", BAD_CAST des, BAD_CAST name,
  2623. xmlSchemaFormatQName(&strA, refURI, refName),
  2624. BAD_CAST refTypeStr, NULL);
  2625. FREE_AND_NULL(des)
  2626. FREE_AND_NULL(strA)
  2627. }
  2628. /**
  2629. * xmlSchemaPCustomAttrErr:
  2630. * @ctxt: the schema parser context
  2631. * @error: the error code
  2632. * @ownerDes: the designation of the owner
  2633. * @ownerItem: the owner as a schema object
  2634. * @attr: the illegal attribute node
  2635. *
  2636. * Reports an illegal attribute during the parse.
  2637. */
  2638. static void
  2639. xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2640. xmlParserErrors error,
  2641. xmlChar **ownerDes,
  2642. xmlSchemaBasicItemPtr ownerItem,
  2643. xmlAttrPtr attr,
  2644. const char *msg)
  2645. {
  2646. xmlChar *des = NULL;
  2647. if (ownerDes == NULL)
  2648. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
  2649. else if (*ownerDes == NULL) {
  2650. xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
  2651. des = *ownerDes;
  2652. } else
  2653. des = *ownerDes;
  2654. if (attr == NULL) {
  2655. xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
  2656. "%s, attribute '%s': %s.\n",
  2657. BAD_CAST des, (const xmlChar *) "Unknown",
  2658. (const xmlChar *) msg, NULL, NULL);
  2659. } else {
  2660. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2661. "%s, attribute '%s': %s.\n",
  2662. BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
  2663. }
  2664. if (ownerDes == NULL)
  2665. FREE_AND_NULL(des);
  2666. }
  2667. /**
  2668. * xmlSchemaPIllegalAttrErr:
  2669. * @ctxt: the schema parser context
  2670. * @error: the error code
  2671. * @ownerItem: the attribute's owner item
  2672. * @attr: the illegal attribute node
  2673. *
  2674. * Reports an illegal attribute during the parse.
  2675. */
  2676. static void
  2677. xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2678. xmlParserErrors error,
  2679. xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
  2680. xmlAttrPtr attr)
  2681. {
  2682. xmlChar *strA = NULL, *strB = NULL;
  2683. xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
  2684. xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
  2685. "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
  2686. xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
  2687. NULL, NULL);
  2688. FREE_AND_NULL(strA);
  2689. FREE_AND_NULL(strB);
  2690. }
  2691. /**
  2692. * xmlSchemaPCustomErr:
  2693. * @ctxt: the schema parser context
  2694. * @error: the error code
  2695. * @itemDes: the designation of the schema item
  2696. * @item: the schema item
  2697. * @itemElem: the node of the schema item
  2698. * @message: the error message
  2699. * @str1: an optional param for the error message
  2700. * @str2: an optional param for the error message
  2701. * @str3: an optional param for the error message
  2702. *
  2703. * Reports an error during parsing.
  2704. */
  2705. static void LIBXML_ATTR_FORMAT(5,0)
  2706. xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
  2707. xmlParserErrors error,
  2708. xmlSchemaBasicItemPtr item,
  2709. xmlNodePtr itemElem,
  2710. const char *message,
  2711. const xmlChar *str1,
  2712. const xmlChar *str2,
  2713. const xmlChar *str3)
  2714. {
  2715. xmlChar *des = NULL, *msg = NULL;
  2716. xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
  2717. msg = xmlStrdup(BAD_CAST "%s: ");
  2718. msg = xmlStrcat(msg, (const xmlChar *) message);
  2719. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2720. if ((itemElem == NULL) && (item != NULL))
  2721. itemElem = WXS_ITEM_NODE(item);
  2722. xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
  2723. (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
  2724. FREE_AND_NULL(des);
  2725. FREE_AND_NULL(msg);
  2726. }
  2727. /**
  2728. * xmlSchemaPCustomErr:
  2729. * @ctxt: the schema parser context
  2730. * @error: the error code
  2731. * @itemDes: the designation of the schema item
  2732. * @item: the schema item
  2733. * @itemElem: the node of the schema item
  2734. * @message: the error message
  2735. * @str1: the optional param for the error message
  2736. *
  2737. * Reports an error during parsing.
  2738. */
  2739. static void LIBXML_ATTR_FORMAT(5,0)
  2740. xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
  2741. xmlParserErrors error,
  2742. xmlSchemaBasicItemPtr item,
  2743. xmlNodePtr itemElem,
  2744. const char *message,
  2745. const xmlChar *str1)
  2746. {
  2747. xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
  2748. str1, NULL, NULL);
  2749. }
  2750. /**
  2751. * xmlSchemaPAttrUseErr:
  2752. * @ctxt: the schema parser context
  2753. * @error: the error code
  2754. * @itemDes: the designation of the schema type
  2755. * @item: the schema type
  2756. * @itemElem: the node of the schema type
  2757. * @attr: the invalid schema attribute
  2758. * @message: the error message
  2759. * @str1: the optional param for the error message
  2760. *
  2761. * Reports an attribute use error during parsing.
  2762. */
  2763. static void LIBXML_ATTR_FORMAT(6,0)
  2764. xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
  2765. xmlParserErrors error,
  2766. xmlNodePtr node,
  2767. xmlSchemaBasicItemPtr ownerItem,
  2768. const xmlSchemaAttributeUsePtr attruse,
  2769. const char *message,
  2770. const xmlChar *str1, const xmlChar *str2,
  2771. const xmlChar *str3,const xmlChar *str4)
  2772. {
  2773. xmlChar *str = NULL, *msg = NULL;
  2774. xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
  2775. msg = xmlStrcat(msg, BAD_CAST ", ");
  2776. msg = xmlStrcat(msg,
  2777. BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
  2778. WXS_BASIC_CAST attruse, NULL));
  2779. FREE_AND_NULL(str);
  2780. msg = xmlStrcat(msg, BAD_CAST ": ");
  2781. msg = xmlStrcat(msg, (const xmlChar *) message);
  2782. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2783. xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
  2784. (const char *) msg, str1, str2, str3, str4);
  2785. xmlFree(msg);
  2786. }
  2787. /**
  2788. * xmlSchemaPIllegalFacetAtomicErr:
  2789. * @ctxt: the schema parser context
  2790. * @error: the error code
  2791. * @type: the schema type
  2792. * @baseType: the base type of type
  2793. * @facet: the illegal facet
  2794. *
  2795. * Reports an illegal facet for atomic simple types.
  2796. */
  2797. static void
  2798. xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
  2799. xmlParserErrors error,
  2800. xmlSchemaTypePtr type,
  2801. xmlSchemaTypePtr baseType,
  2802. xmlSchemaFacetPtr facet)
  2803. {
  2804. xmlChar *des = NULL, *strT = NULL;
  2805. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
  2806. xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
  2807. "%s: The facet '%s' is not allowed on types derived from the "
  2808. "type %s.\n",
  2809. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
  2810. xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
  2811. NULL, NULL);
  2812. FREE_AND_NULL(des);
  2813. FREE_AND_NULL(strT);
  2814. }
  2815. /**
  2816. * xmlSchemaPIllegalFacetListUnionErr:
  2817. * @ctxt: the schema parser context
  2818. * @error: the error code
  2819. * @itemDes: the designation of the schema item involved
  2820. * @item: the schema item involved
  2821. * @facet: the illegal facet
  2822. *
  2823. * Reports an illegal facet for <list> and <union>.
  2824. */
  2825. static void
  2826. xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
  2827. xmlParserErrors error,
  2828. xmlSchemaTypePtr type,
  2829. xmlSchemaFacetPtr facet)
  2830. {
  2831. xmlChar *des = NULL;
  2832. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
  2833. type->node);
  2834. xmlSchemaPErr(ctxt, type->node, error,
  2835. "%s: The facet '%s' is not allowed.\n",
  2836. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
  2837. FREE_AND_NULL(des);
  2838. }
  2839. /**
  2840. * xmlSchemaPMutualExclAttrErr:
  2841. * @ctxt: the schema validation context
  2842. * @error: the error code
  2843. * @elemDes: the designation of the parent element node
  2844. * @attr: the bad attribute node
  2845. * @type: the corresponding type of the attribute node
  2846. *
  2847. * Reports an illegal attribute.
  2848. */
  2849. static void
  2850. xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2851. xmlParserErrors error,
  2852. xmlSchemaBasicItemPtr ownerItem,
  2853. xmlAttrPtr attr,
  2854. const char *name1,
  2855. const char *name2)
  2856. {
  2857. xmlChar *des = NULL;
  2858. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
  2859. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2860. "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
  2861. BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
  2862. FREE_AND_NULL(des);
  2863. }
  2864. /**
  2865. * xmlSchemaPSimpleTypeErr:
  2866. * @ctxt: the schema validation context
  2867. * @error: the error code
  2868. * @type: the type specifier
  2869. * @ownerItem: the schema object if existent
  2870. * @node: the validated node
  2871. * @value: the validated value
  2872. *
  2873. * Reports a simple type validation error.
  2874. * TODO: Should this report the value of an element as well?
  2875. */
  2876. static void LIBXML_ATTR_FORMAT(8,0)
  2877. xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  2878. xmlParserErrors error,
  2879. xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
  2880. xmlNodePtr node,
  2881. xmlSchemaTypePtr type,
  2882. const char *expected,
  2883. const xmlChar *value,
  2884. const char *message,
  2885. const xmlChar *str1,
  2886. const xmlChar *str2)
  2887. {
  2888. xmlChar *msg = NULL;
  2889. xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
  2890. if (message == NULL) {
  2891. /*
  2892. * Use default messages.
  2893. */
  2894. if (type != NULL) {
  2895. if (node->type == XML_ATTRIBUTE_NODE)
  2896. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2897. else
  2898. msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
  2899. "valid value of ");
  2900. if (! xmlSchemaIsGlobalItem(type))
  2901. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2902. else
  2903. msg = xmlStrcat(msg, BAD_CAST "the ");
  2904. if (WXS_IS_ATOMIC(type))
  2905. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2906. else if (WXS_IS_LIST(type))
  2907. msg = xmlStrcat(msg, BAD_CAST "list type");
  2908. else if (WXS_IS_UNION(type))
  2909. msg = xmlStrcat(msg, BAD_CAST "union type");
  2910. if (xmlSchemaIsGlobalItem(type)) {
  2911. xmlChar *str = NULL;
  2912. msg = xmlStrcat(msg, BAD_CAST " '");
  2913. if (type->builtInType != 0) {
  2914. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2915. str = xmlStrdup(type->name);
  2916. } else {
  2917. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2918. if (!str)
  2919. str = xmlStrdup(qName);
  2920. }
  2921. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2922. msg = xmlStrcat(msg, BAD_CAST "'.");
  2923. FREE_AND_NULL(str);
  2924. }
  2925. } else {
  2926. if (node->type == XML_ATTRIBUTE_NODE)
  2927. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
  2928. else
  2929. msg = xmlStrcat(msg, BAD_CAST "The character content is not "
  2930. "valid.");
  2931. }
  2932. if (expected) {
  2933. xmlChar *expectedEscaped = xmlCharStrdup(expected);
  2934. msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  2935. msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
  2936. FREE_AND_NULL(expectedEscaped);
  2937. msg = xmlStrcat(msg, BAD_CAST "'.\n");
  2938. } else
  2939. msg = xmlStrcat(msg, BAD_CAST "\n");
  2940. if (node->type == XML_ATTRIBUTE_NODE)
  2941. xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
  2942. else
  2943. xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
  2944. } else {
  2945. msg = xmlStrcat(msg, BAD_CAST message);
  2946. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2947. xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
  2948. (const char*) msg, str1, str2, NULL, NULL, NULL);
  2949. }
  2950. /* Cleanup. */
  2951. FREE_AND_NULL(msg)
  2952. }
  2953. /**
  2954. * xmlSchemaPContentErr:
  2955. * @ctxt: the schema parser context
  2956. * @error: the error code
  2957. * @ownerItem: the owner item of the holder of the content
  2958. * @ownerElem: the node of the holder of the content
  2959. * @child: the invalid child node
  2960. * @message: the optional error message
  2961. * @content: the optional string describing the correct content
  2962. *
  2963. * Reports an error concerning the content of a schema element.
  2964. */
  2965. static void
  2966. xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
  2967. xmlParserErrors error,
  2968. xmlSchemaBasicItemPtr ownerItem,
  2969. xmlNodePtr ownerElem,
  2970. xmlNodePtr child,
  2971. const char *message,
  2972. const char *content)
  2973. {
  2974. xmlChar *des = NULL;
  2975. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2976. if (message != NULL)
  2977. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2978. "%s: %s.\n",
  2979. BAD_CAST des, BAD_CAST message);
  2980. else {
  2981. if (content != NULL) {
  2982. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2983. "%s: The content is not valid. Expected is %s.\n",
  2984. BAD_CAST des, BAD_CAST content);
  2985. } else {
  2986. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2987. "%s: The content is not valid.\n",
  2988. BAD_CAST des, NULL);
  2989. }
  2990. }
  2991. FREE_AND_NULL(des)
  2992. }
  2993. /************************************************************************
  2994. * *
  2995. * Streamable error functions *
  2996. * *
  2997. ************************************************************************/
  2998. /************************************************************************
  2999. * *
  3000. * Validation helper functions *
  3001. * *
  3002. ************************************************************************/
  3003. /************************************************************************
  3004. * *
  3005. * Allocation functions *
  3006. * *
  3007. ************************************************************************/
  3008. /**
  3009. * xmlSchemaNewSchemaForParserCtxt:
  3010. * @ctxt: a schema validation context
  3011. *
  3012. * Allocate a new Schema structure.
  3013. *
  3014. * Returns the newly allocated structure or NULL in case or error
  3015. */
  3016. static xmlSchemaPtr
  3017. xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
  3018. {
  3019. xmlSchemaPtr ret;
  3020. ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
  3021. if (ret == NULL) {
  3022. xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
  3023. return (NULL);
  3024. }
  3025. memset(ret, 0, sizeof(xmlSchema));
  3026. ret->dict = ctxt->dict;
  3027. xmlDictReference(ret->dict);
  3028. return (ret);
  3029. }
  3030. /**
  3031. * xmlSchemaNewFacet:
  3032. *
  3033. * Allocate a new Facet structure.
  3034. *
  3035. * Returns the newly allocated structure or NULL in case or error
  3036. */
  3037. xmlSchemaFacetPtr
  3038. xmlSchemaNewFacet(void)
  3039. {
  3040. xmlSchemaFacetPtr ret;
  3041. ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
  3042. if (ret == NULL) {
  3043. return (NULL);
  3044. }
  3045. memset(ret, 0, sizeof(xmlSchemaFacet));
  3046. return (ret);
  3047. }
  3048. /**
  3049. * xmlSchemaNewAnnot:
  3050. * @ctxt: a schema validation context
  3051. * @node: a node
  3052. *
  3053. * Allocate a new annotation structure.
  3054. *
  3055. * Returns the newly allocated structure or NULL in case or error
  3056. */
  3057. static xmlSchemaAnnotPtr
  3058. xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  3059. {
  3060. xmlSchemaAnnotPtr ret;
  3061. ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
  3062. if (ret == NULL) {
  3063. xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
  3064. return (NULL);
  3065. }
  3066. memset(ret, 0, sizeof(xmlSchemaAnnot));
  3067. ret->content = node;
  3068. return (ret);
  3069. }
  3070. static xmlSchemaItemListPtr
  3071. xmlSchemaItemListCreate(void)
  3072. {
  3073. xmlSchemaItemListPtr ret;
  3074. ret = xmlMalloc(sizeof(xmlSchemaItemList));
  3075. if (ret == NULL) {
  3076. xmlSchemaPErrMemory(NULL,
  3077. "allocating an item list structure", NULL);
  3078. return (NULL);
  3079. }
  3080. memset(ret, 0, sizeof(xmlSchemaItemList));
  3081. return (ret);
  3082. }
  3083. static void
  3084. xmlSchemaItemListClear(xmlSchemaItemListPtr list)
  3085. {
  3086. if (list->items != NULL) {
  3087. xmlFree(list->items);
  3088. list->items = NULL;
  3089. }
  3090. list->nbItems = 0;
  3091. list->sizeItems = 0;
  3092. }
  3093. static int
  3094. xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
  3095. {
  3096. if (list->sizeItems <= list->nbItems) {
  3097. void **tmp;
  3098. size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
  3099. tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
  3100. if (tmp == NULL) {
  3101. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3102. return(-1);
  3103. }
  3104. list->items = tmp;
  3105. list->sizeItems = newSize;
  3106. }
  3107. list->items[list->nbItems++] = item;
  3108. return(0);
  3109. }
  3110. static int
  3111. xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
  3112. int initialSize,
  3113. void *item)
  3114. {
  3115. if (list->items == NULL) {
  3116. if (initialSize <= 0)
  3117. initialSize = 1;
  3118. list->items = (void **) xmlMalloc(
  3119. initialSize * sizeof(void *));
  3120. if (list->items == NULL) {
  3121. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3122. return(-1);
  3123. }
  3124. list->sizeItems = initialSize;
  3125. } else if (list->sizeItems <= list->nbItems) {
  3126. void **tmp;
  3127. list->sizeItems *= 2;
  3128. tmp = (void **) xmlRealloc(list->items,
  3129. list->sizeItems * sizeof(void *));
  3130. if (tmp == NULL) {
  3131. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3132. list->sizeItems /= 2;
  3133. return(-1);
  3134. }
  3135. list->items = tmp;
  3136. }
  3137. list->items[list->nbItems++] = item;
  3138. return(0);
  3139. }
  3140. static int
  3141. xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
  3142. {
  3143. if (list->sizeItems <= list->nbItems) {
  3144. void **tmp;
  3145. size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
  3146. tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
  3147. if (tmp == NULL) {
  3148. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3149. return(-1);
  3150. }
  3151. list->items = tmp;
  3152. list->sizeItems = newSize;
  3153. }
  3154. /*
  3155. * Just append if the index is greater/equal than the item count.
  3156. */
  3157. if (idx >= list->nbItems) {
  3158. list->items[list->nbItems++] = item;
  3159. } else {
  3160. int i;
  3161. for (i = list->nbItems; i > idx; i--)
  3162. list->items[i] = list->items[i-1];
  3163. list->items[idx] = item;
  3164. list->nbItems++;
  3165. }
  3166. return(0);
  3167. }
  3168. #if 0 /* enable if ever needed */
  3169. static int
  3170. xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
  3171. int initialSize,
  3172. void *item,
  3173. int idx)
  3174. {
  3175. if (list->items == NULL) {
  3176. if (initialSize <= 0)
  3177. initialSize = 1;
  3178. list->items = (void **) xmlMalloc(
  3179. initialSize * sizeof(void *));
  3180. if (list->items == NULL) {
  3181. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3182. return(-1);
  3183. }
  3184. list->sizeItems = initialSize;
  3185. } else if (list->sizeItems <= list->nbItems) {
  3186. list->sizeItems *= 2;
  3187. list->items = (void **) xmlRealloc(list->items,
  3188. list->sizeItems * sizeof(void *));
  3189. if (list->items == NULL) {
  3190. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3191. list->sizeItems = 0;
  3192. return(-1);
  3193. }
  3194. }
  3195. /*
  3196. * Just append if the index is greater/equal than the item count.
  3197. */
  3198. if (idx >= list->nbItems) {
  3199. list->items[list->nbItems++] = item;
  3200. } else {
  3201. int i;
  3202. for (i = list->nbItems; i > idx; i--)
  3203. list->items[i] = list->items[i-1];
  3204. list->items[idx] = item;
  3205. list->nbItems++;
  3206. }
  3207. return(0);
  3208. }
  3209. #endif
  3210. static int
  3211. xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
  3212. {
  3213. int i;
  3214. if ((list->items == NULL) || (idx >= list->nbItems)) {
  3215. xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
  3216. "index error.\n");
  3217. return(-1);
  3218. }
  3219. if (list->nbItems == 1) {
  3220. /* TODO: Really free the list? */
  3221. xmlFree(list->items);
  3222. list->items = NULL;
  3223. list->nbItems = 0;
  3224. list->sizeItems = 0;
  3225. } else if (list->nbItems -1 == idx) {
  3226. list->nbItems--;
  3227. } else {
  3228. for (i = idx; i < list->nbItems -1; i++)
  3229. list->items[i] = list->items[i+1];
  3230. list->nbItems--;
  3231. }
  3232. return(0);
  3233. }
  3234. /**
  3235. * xmlSchemaItemListFree:
  3236. * @annot: a schema type structure
  3237. *
  3238. * Deallocate a annotation structure
  3239. */
  3240. static void
  3241. xmlSchemaItemListFree(xmlSchemaItemListPtr list)
  3242. {
  3243. if (list == NULL)
  3244. return;
  3245. if (list->items != NULL)
  3246. xmlFree(list->items);
  3247. xmlFree(list);
  3248. }
  3249. static void
  3250. xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
  3251. {
  3252. if (bucket == NULL)
  3253. return;
  3254. if (bucket->globals != NULL) {
  3255. xmlSchemaComponentListFree(bucket->globals);
  3256. xmlSchemaItemListFree(bucket->globals);
  3257. }
  3258. if (bucket->locals != NULL) {
  3259. xmlSchemaComponentListFree(bucket->locals);
  3260. xmlSchemaItemListFree(bucket->locals);
  3261. }
  3262. if (bucket->relations != NULL) {
  3263. xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
  3264. do {
  3265. prev = cur;
  3266. cur = cur->next;
  3267. xmlFree(prev);
  3268. } while (cur != NULL);
  3269. }
  3270. if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
  3271. xmlFreeDoc(bucket->doc);
  3272. }
  3273. if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
  3274. if (WXS_IMPBUCKET(bucket)->schema != NULL)
  3275. xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
  3276. }
  3277. xmlFree(bucket);
  3278. }
  3279. static void
  3280. xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
  3281. {
  3282. xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
  3283. }
  3284. static xmlSchemaBucketPtr
  3285. xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
  3286. int type, const xmlChar *targetNamespace)
  3287. {
  3288. xmlSchemaBucketPtr ret;
  3289. int size;
  3290. xmlSchemaPtr mainSchema;
  3291. if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
  3292. PERROR_INT("xmlSchemaBucketCreate",
  3293. "no main schema on constructor");
  3294. return(NULL);
  3295. }
  3296. mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
  3297. /* Create the schema bucket. */
  3298. if (WXS_IS_BUCKET_INCREDEF(type))
  3299. size = sizeof(xmlSchemaInclude);
  3300. else
  3301. size = sizeof(xmlSchemaImport);
  3302. ret = (xmlSchemaBucketPtr) xmlMalloc(size);
  3303. if (ret == NULL) {
  3304. xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
  3305. return(NULL);
  3306. }
  3307. memset(ret, 0, size);
  3308. ret->targetNamespace = targetNamespace;
  3309. ret->type = type;
  3310. ret->globals = xmlSchemaItemListCreate();
  3311. if (ret->globals == NULL) {
  3312. xmlSchemaBucketFree(ret);
  3313. return(NULL);
  3314. }
  3315. ret->locals = xmlSchemaItemListCreate();
  3316. if (ret->locals == NULL) {
  3317. xmlSchemaBucketFree(ret);
  3318. return(NULL);
  3319. }
  3320. /*
  3321. * The following will assure that only the first bucket is marked as
  3322. * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
  3323. * For each following import buckets an xmlSchema will be created.
  3324. * An xmlSchema will be created for every distinct targetNamespace.
  3325. * We assign the targetNamespace to the schemata here.
  3326. */
  3327. if (! WXS_HAS_BUCKETS(pctxt)) {
  3328. if (WXS_IS_BUCKET_INCREDEF(type)) {
  3329. PERROR_INT("xmlSchemaBucketCreate",
  3330. "first bucket but it's an include or redefine");
  3331. xmlSchemaBucketFree(ret);
  3332. return(NULL);
  3333. }
  3334. /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
  3335. ret->type = XML_SCHEMA_SCHEMA_MAIN;
  3336. /* Point to the *main* schema. */
  3337. WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
  3338. WXS_IMPBUCKET(ret)->schema = mainSchema;
  3339. /*
  3340. * Ensure that the main schema gets a targetNamespace.
  3341. */
  3342. mainSchema->targetNamespace = targetNamespace;
  3343. } else {
  3344. if (type == XML_SCHEMA_SCHEMA_MAIN) {
  3345. PERROR_INT("xmlSchemaBucketCreate",
  3346. "main bucket but it's not the first one");
  3347. xmlSchemaBucketFree(ret);
  3348. return(NULL);
  3349. } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
  3350. /*
  3351. * Create a schema for imports and assign the
  3352. * targetNamespace.
  3353. */
  3354. WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
  3355. if (WXS_IMPBUCKET(ret)->schema == NULL) {
  3356. xmlSchemaBucketFree(ret);
  3357. return(NULL);
  3358. }
  3359. WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
  3360. }
  3361. }
  3362. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  3363. int res;
  3364. /*
  3365. * Imports go into the "schemasImports" slot of the main *schema*.
  3366. * Note that we create an import entry for the main schema as well; i.e.,
  3367. * even if there's only one schema, we'll get an import.
  3368. */
  3369. if (mainSchema->schemasImports == NULL) {
  3370. mainSchema->schemasImports = xmlHashCreateDict(5,
  3371. WXS_CONSTRUCTOR(pctxt)->dict);
  3372. if (mainSchema->schemasImports == NULL) {
  3373. xmlSchemaBucketFree(ret);
  3374. return(NULL);
  3375. }
  3376. }
  3377. if (targetNamespace == NULL)
  3378. res = xmlHashAddEntry(mainSchema->schemasImports,
  3379. XML_SCHEMAS_NO_NAMESPACE, ret);
  3380. else
  3381. res = xmlHashAddEntry(mainSchema->schemasImports,
  3382. targetNamespace, ret);
  3383. if (res != 0) {
  3384. PERROR_INT("xmlSchemaBucketCreate",
  3385. "failed to add the schema bucket to the hash");
  3386. xmlSchemaBucketFree(ret);
  3387. return(NULL);
  3388. }
  3389. } else {
  3390. /* Set the @ownerImport of an include bucket. */
  3391. if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
  3392. WXS_INCBUCKET(ret)->ownerImport =
  3393. WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
  3394. else
  3395. WXS_INCBUCKET(ret)->ownerImport =
  3396. WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
  3397. /* Includes got into the "includes" slot of the *main* schema. */
  3398. if (mainSchema->includes == NULL) {
  3399. mainSchema->includes = xmlSchemaItemListCreate();
  3400. if (mainSchema->includes == NULL) {
  3401. xmlSchemaBucketFree(ret);
  3402. return(NULL);
  3403. }
  3404. }
  3405. if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
  3406. xmlSchemaBucketFree(ret);
  3407. return(NULL);
  3408. }
  3409. }
  3410. /*
  3411. * Add to list of all buckets; this is used for lookup
  3412. * during schema construction time only.
  3413. */
  3414. if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
  3415. return(NULL);
  3416. return(ret);
  3417. }
  3418. static int
  3419. xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
  3420. {
  3421. if (*list == NULL) {
  3422. *list = xmlSchemaItemListCreate();
  3423. if (*list == NULL)
  3424. return(-1);
  3425. }
  3426. return(xmlSchemaItemListAddSize(*list, initialSize, item));
  3427. }
  3428. /**
  3429. * xmlSchemaFreeAnnot:
  3430. * @annot: a schema type structure
  3431. *
  3432. * Deallocate a annotation structure
  3433. */
  3434. static void
  3435. xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
  3436. {
  3437. if (annot == NULL)
  3438. return;
  3439. if (annot->next == NULL) {
  3440. xmlFree(annot);
  3441. } else {
  3442. xmlSchemaAnnotPtr prev;
  3443. do {
  3444. prev = annot;
  3445. annot = annot->next;
  3446. xmlFree(prev);
  3447. } while (annot != NULL);
  3448. }
  3449. }
  3450. /**
  3451. * xmlSchemaFreeNotation:
  3452. * @schema: a schema notation structure
  3453. *
  3454. * Deallocate a Schema Notation structure.
  3455. */
  3456. static void
  3457. xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
  3458. {
  3459. if (nota == NULL)
  3460. return;
  3461. if (nota->annot != NULL)
  3462. xmlSchemaFreeAnnot(nota->annot);
  3463. xmlFree(nota);
  3464. }
  3465. /**
  3466. * xmlSchemaFreeAttribute:
  3467. * @attr: an attribute declaration
  3468. *
  3469. * Deallocates an attribute declaration structure.
  3470. */
  3471. static void
  3472. xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
  3473. {
  3474. if (attr == NULL)
  3475. return;
  3476. if (attr->annot != NULL)
  3477. xmlSchemaFreeAnnot(attr->annot);
  3478. if (attr->defVal != NULL)
  3479. xmlSchemaFreeValue(attr->defVal);
  3480. xmlFree(attr);
  3481. }
  3482. /**
  3483. * xmlSchemaFreeAttributeUse:
  3484. * @use: an attribute use
  3485. *
  3486. * Deallocates an attribute use structure.
  3487. */
  3488. static void
  3489. xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
  3490. {
  3491. if (use == NULL)
  3492. return;
  3493. if (use->annot != NULL)
  3494. xmlSchemaFreeAnnot(use->annot);
  3495. if (use->defVal != NULL)
  3496. xmlSchemaFreeValue(use->defVal);
  3497. xmlFree(use);
  3498. }
  3499. /**
  3500. * xmlSchemaFreeAttributeUseProhib:
  3501. * @prohib: an attribute use prohibition
  3502. *
  3503. * Deallocates an attribute use structure.
  3504. */
  3505. static void
  3506. xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
  3507. {
  3508. if (prohib == NULL)
  3509. return;
  3510. xmlFree(prohib);
  3511. }
  3512. /**
  3513. * xmlSchemaFreeWildcardNsSet:
  3514. * set: a schema wildcard namespace
  3515. *
  3516. * Deallocates a list of wildcard constraint structures.
  3517. */
  3518. static void
  3519. xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
  3520. {
  3521. xmlSchemaWildcardNsPtr next;
  3522. while (set != NULL) {
  3523. next = set->next;
  3524. xmlFree(set);
  3525. set = next;
  3526. }
  3527. }
  3528. /**
  3529. * xmlSchemaFreeWildcard:
  3530. * @wildcard: a wildcard structure
  3531. *
  3532. * Deallocates a wildcard structure.
  3533. */
  3534. void
  3535. xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
  3536. {
  3537. if (wildcard == NULL)
  3538. return;
  3539. if (wildcard->annot != NULL)
  3540. xmlSchemaFreeAnnot(wildcard->annot);
  3541. if (wildcard->nsSet != NULL)
  3542. xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
  3543. if (wildcard->negNsSet != NULL)
  3544. xmlFree(wildcard->negNsSet);
  3545. xmlFree(wildcard);
  3546. }
  3547. /**
  3548. * xmlSchemaFreeAttributeGroup:
  3549. * @schema: a schema attribute group structure
  3550. *
  3551. * Deallocate a Schema Attribute Group structure.
  3552. */
  3553. static void
  3554. xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
  3555. {
  3556. if (attrGr == NULL)
  3557. return;
  3558. if (attrGr->annot != NULL)
  3559. xmlSchemaFreeAnnot(attrGr->annot);
  3560. if (attrGr->attrUses != NULL)
  3561. xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
  3562. xmlFree(attrGr);
  3563. }
  3564. /**
  3565. * xmlSchemaFreeQNameRef:
  3566. * @item: a QName reference structure
  3567. *
  3568. * Deallocatea a QName reference structure.
  3569. */
  3570. static void
  3571. xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
  3572. {
  3573. xmlFree(item);
  3574. }
  3575. /**
  3576. * xmlSchemaFreeTypeLinkList:
  3577. * @alink: a type link
  3578. *
  3579. * Deallocate a list of types.
  3580. */
  3581. static void
  3582. xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
  3583. {
  3584. xmlSchemaTypeLinkPtr next;
  3585. while (link != NULL) {
  3586. next = link->next;
  3587. xmlFree(link);
  3588. link = next;
  3589. }
  3590. }
  3591. static void
  3592. xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
  3593. {
  3594. xmlSchemaIDCStateObjPtr next;
  3595. while (sto != NULL) {
  3596. next = sto->next;
  3597. if (sto->history != NULL)
  3598. xmlFree(sto->history);
  3599. if (sto->xpathCtxt != NULL)
  3600. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  3601. xmlFree(sto);
  3602. sto = next;
  3603. }
  3604. }
  3605. /**
  3606. * xmlSchemaFreeIDC:
  3607. * @idc: a identity-constraint definition
  3608. *
  3609. * Deallocates an identity-constraint definition.
  3610. */
  3611. static void
  3612. xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
  3613. {
  3614. xmlSchemaIDCSelectPtr cur, prev;
  3615. if (idcDef == NULL)
  3616. return;
  3617. if (idcDef->annot != NULL)
  3618. xmlSchemaFreeAnnot(idcDef->annot);
  3619. /* Selector */
  3620. if (idcDef->selector != NULL) {
  3621. if (idcDef->selector->xpathComp != NULL)
  3622. xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
  3623. xmlFree(idcDef->selector);
  3624. }
  3625. /* Fields */
  3626. if (idcDef->fields != NULL) {
  3627. cur = idcDef->fields;
  3628. do {
  3629. prev = cur;
  3630. cur = cur->next;
  3631. if (prev->xpathComp != NULL)
  3632. xmlFreePattern((xmlPatternPtr) prev->xpathComp);
  3633. xmlFree(prev);
  3634. } while (cur != NULL);
  3635. }
  3636. xmlFree(idcDef);
  3637. }
  3638. /**
  3639. * xmlSchemaFreeElement:
  3640. * @schema: a schema element structure
  3641. *
  3642. * Deallocate a Schema Element structure.
  3643. */
  3644. static void
  3645. xmlSchemaFreeElement(xmlSchemaElementPtr elem)
  3646. {
  3647. if (elem == NULL)
  3648. return;
  3649. if (elem->annot != NULL)
  3650. xmlSchemaFreeAnnot(elem->annot);
  3651. if (elem->contModel != NULL)
  3652. xmlRegFreeRegexp(elem->contModel);
  3653. if (elem->defVal != NULL)
  3654. xmlSchemaFreeValue(elem->defVal);
  3655. xmlFree(elem);
  3656. }
  3657. /**
  3658. * xmlSchemaFreeFacet:
  3659. * @facet: a schema facet structure
  3660. *
  3661. * Deallocate a Schema Facet structure.
  3662. */
  3663. void
  3664. xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
  3665. {
  3666. if (facet == NULL)
  3667. return;
  3668. if (facet->val != NULL)
  3669. xmlSchemaFreeValue(facet->val);
  3670. if (facet->regexp != NULL)
  3671. xmlRegFreeRegexp(facet->regexp);
  3672. if (facet->annot != NULL)
  3673. xmlSchemaFreeAnnot(facet->annot);
  3674. xmlFree(facet);
  3675. }
  3676. /**
  3677. * xmlSchemaFreeType:
  3678. * @type: a schema type structure
  3679. *
  3680. * Deallocate a Schema Type structure.
  3681. */
  3682. void
  3683. xmlSchemaFreeType(xmlSchemaTypePtr type)
  3684. {
  3685. if (type == NULL)
  3686. return;
  3687. if (type->annot != NULL)
  3688. xmlSchemaFreeAnnot(type->annot);
  3689. if (type->facets != NULL) {
  3690. xmlSchemaFacetPtr facet, next;
  3691. facet = type->facets;
  3692. while (facet != NULL) {
  3693. next = facet->next;
  3694. xmlSchemaFreeFacet(facet);
  3695. facet = next;
  3696. }
  3697. }
  3698. if (type->attrUses != NULL)
  3699. xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
  3700. if (type->memberTypes != NULL)
  3701. xmlSchemaFreeTypeLinkList(type->memberTypes);
  3702. if (type->facetSet != NULL) {
  3703. xmlSchemaFacetLinkPtr next, link;
  3704. link = type->facetSet;
  3705. do {
  3706. next = link->next;
  3707. xmlFree(link);
  3708. link = next;
  3709. } while (link != NULL);
  3710. }
  3711. if (type->contModel != NULL)
  3712. xmlRegFreeRegexp(type->contModel);
  3713. xmlFree(type);
  3714. }
  3715. /**
  3716. * xmlSchemaFreeModelGroupDef:
  3717. * @item: a schema model group definition
  3718. *
  3719. * Deallocates a schema model group definition.
  3720. */
  3721. static void
  3722. xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
  3723. {
  3724. if (item->annot != NULL)
  3725. xmlSchemaFreeAnnot(item->annot);
  3726. xmlFree(item);
  3727. }
  3728. /**
  3729. * xmlSchemaFreeModelGroup:
  3730. * @item: a schema model group
  3731. *
  3732. * Deallocates a schema model group structure.
  3733. */
  3734. static void
  3735. xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
  3736. {
  3737. if (item->annot != NULL)
  3738. xmlSchemaFreeAnnot(item->annot);
  3739. xmlFree(item);
  3740. }
  3741. static void
  3742. xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
  3743. {
  3744. if ((list == NULL) || (list->nbItems == 0))
  3745. return;
  3746. {
  3747. xmlSchemaTreeItemPtr item;
  3748. xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
  3749. int i;
  3750. for (i = 0; i < list->nbItems; i++) {
  3751. item = items[i];
  3752. if (item == NULL)
  3753. continue;
  3754. switch (item->type) {
  3755. case XML_SCHEMA_TYPE_SIMPLE:
  3756. case XML_SCHEMA_TYPE_COMPLEX:
  3757. xmlSchemaFreeType((xmlSchemaTypePtr) item);
  3758. break;
  3759. case XML_SCHEMA_TYPE_ATTRIBUTE:
  3760. xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
  3761. break;
  3762. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  3763. xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
  3764. break;
  3765. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  3766. xmlSchemaFreeAttributeUseProhib(
  3767. (xmlSchemaAttributeUseProhibPtr) item);
  3768. break;
  3769. case XML_SCHEMA_TYPE_ELEMENT:
  3770. xmlSchemaFreeElement((xmlSchemaElementPtr) item);
  3771. break;
  3772. case XML_SCHEMA_TYPE_PARTICLE:
  3773. if (item->annot != NULL)
  3774. xmlSchemaFreeAnnot(item->annot);
  3775. xmlFree(item);
  3776. break;
  3777. case XML_SCHEMA_TYPE_SEQUENCE:
  3778. case XML_SCHEMA_TYPE_CHOICE:
  3779. case XML_SCHEMA_TYPE_ALL:
  3780. xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
  3781. break;
  3782. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  3783. xmlSchemaFreeAttributeGroup(
  3784. (xmlSchemaAttributeGroupPtr) item);
  3785. break;
  3786. case XML_SCHEMA_TYPE_GROUP:
  3787. xmlSchemaFreeModelGroupDef(
  3788. (xmlSchemaModelGroupDefPtr) item);
  3789. break;
  3790. case XML_SCHEMA_TYPE_ANY:
  3791. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  3792. xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
  3793. break;
  3794. case XML_SCHEMA_TYPE_IDC_KEY:
  3795. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  3796. case XML_SCHEMA_TYPE_IDC_KEYREF:
  3797. xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
  3798. break;
  3799. case XML_SCHEMA_TYPE_NOTATION:
  3800. xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
  3801. break;
  3802. case XML_SCHEMA_EXTRA_QNAMEREF:
  3803. xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
  3804. break;
  3805. default: {
  3806. /* TODO: This should never be hit. */
  3807. xmlSchemaPSimpleInternalErr(NULL,
  3808. "Internal error: xmlSchemaComponentListFree, "
  3809. "unexpected component type '%s'\n",
  3810. (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
  3811. }
  3812. break;
  3813. }
  3814. }
  3815. list->nbItems = 0;
  3816. }
  3817. }
  3818. /**
  3819. * xmlSchemaFree:
  3820. * @schema: a schema structure
  3821. *
  3822. * Deallocate a Schema structure.
  3823. */
  3824. void
  3825. xmlSchemaFree(xmlSchemaPtr schema)
  3826. {
  3827. if (schema == NULL)
  3828. return;
  3829. /* @volatiles is not used anymore :-/ */
  3830. if (schema->volatiles != NULL)
  3831. TODO
  3832. /*
  3833. * Note that those slots are not responsible for freeing
  3834. * schema components anymore; this will now be done by
  3835. * the schema buckets.
  3836. */
  3837. if (schema->notaDecl != NULL)
  3838. xmlHashFree(schema->notaDecl, NULL);
  3839. if (schema->attrDecl != NULL)
  3840. xmlHashFree(schema->attrDecl, NULL);
  3841. if (schema->attrgrpDecl != NULL)
  3842. xmlHashFree(schema->attrgrpDecl, NULL);
  3843. if (schema->elemDecl != NULL)
  3844. xmlHashFree(schema->elemDecl, NULL);
  3845. if (schema->typeDecl != NULL)
  3846. xmlHashFree(schema->typeDecl, NULL);
  3847. if (schema->groupDecl != NULL)
  3848. xmlHashFree(schema->groupDecl, NULL);
  3849. if (schema->idcDef != NULL)
  3850. xmlHashFree(schema->idcDef, NULL);
  3851. if (schema->schemasImports != NULL)
  3852. xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
  3853. if (schema->includes != NULL) {
  3854. xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
  3855. int i;
  3856. for (i = 0; i < list->nbItems; i++) {
  3857. xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
  3858. }
  3859. xmlSchemaItemListFree(list);
  3860. }
  3861. if (schema->annot != NULL)
  3862. xmlSchemaFreeAnnot(schema->annot);
  3863. /* Never free the doc here, since this will be done by the buckets. */
  3864. xmlDictFree(schema->dict);
  3865. xmlFree(schema);
  3866. }
  3867. /************************************************************************
  3868. * *
  3869. * Debug functions *
  3870. * *
  3871. ************************************************************************/
  3872. #ifdef LIBXML_OUTPUT_ENABLED
  3873. static void
  3874. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
  3875. /**
  3876. * xmlSchemaElementDump:
  3877. * @elem: an element
  3878. * @output: the file output
  3879. *
  3880. * Dump the element
  3881. */
  3882. static void
  3883. xmlSchemaElementDump(void *payload, void *data,
  3884. const xmlChar * name ATTRIBUTE_UNUSED,
  3885. const xmlChar * namespace ATTRIBUTE_UNUSED,
  3886. const xmlChar * context ATTRIBUTE_UNUSED)
  3887. {
  3888. xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
  3889. FILE *output = (FILE *) data;
  3890. if (elem == NULL)
  3891. return;
  3892. fprintf(output, "Element");
  3893. if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
  3894. fprintf(output, " (global)");
  3895. fprintf(output, ": '%s' ", elem->name);
  3896. if (namespace != NULL)
  3897. fprintf(output, "ns '%s'", namespace);
  3898. fprintf(output, "\n");
  3899. #if 0
  3900. if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
  3901. fprintf(output, " min %d ", elem->minOccurs);
  3902. if (elem->maxOccurs >= UNBOUNDED)
  3903. fprintf(output, "max: unbounded\n");
  3904. else if (elem->maxOccurs != 1)
  3905. fprintf(output, "max: %d\n", elem->maxOccurs);
  3906. else
  3907. fprintf(output, "\n");
  3908. }
  3909. #endif
  3910. /*
  3911. * Misc other properties.
  3912. */
  3913. if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
  3914. (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
  3915. (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
  3916. (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
  3917. fprintf(output, " props: ");
  3918. if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
  3919. fprintf(output, "[fixed] ");
  3920. if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
  3921. fprintf(output, "[default] ");
  3922. if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  3923. fprintf(output, "[abstract] ");
  3924. if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
  3925. fprintf(output, "[nillable] ");
  3926. fprintf(output, "\n");
  3927. }
  3928. /*
  3929. * Default/fixed value.
  3930. */
  3931. if (elem->value != NULL)
  3932. fprintf(output, " value: '%s'\n", elem->value);
  3933. /*
  3934. * Type.
  3935. */
  3936. if (elem->namedType != NULL) {
  3937. fprintf(output, " type: '%s' ", elem->namedType);
  3938. if (elem->namedTypeNs != NULL)
  3939. fprintf(output, "ns '%s'\n", elem->namedTypeNs);
  3940. else
  3941. fprintf(output, "\n");
  3942. } else if (elem->subtypes != NULL) {
  3943. /*
  3944. * Dump local types.
  3945. */
  3946. xmlSchemaTypeDump(elem->subtypes, output);
  3947. }
  3948. /*
  3949. * Substitution group.
  3950. */
  3951. if (elem->substGroup != NULL) {
  3952. fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
  3953. if (elem->substGroupNs != NULL)
  3954. fprintf(output, "ns '%s'\n", elem->substGroupNs);
  3955. else
  3956. fprintf(output, "\n");
  3957. }
  3958. }
  3959. /**
  3960. * xmlSchemaAnnotDump:
  3961. * @output: the file output
  3962. * @annot: a annotation
  3963. *
  3964. * Dump the annotation
  3965. */
  3966. static void
  3967. xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
  3968. {
  3969. xmlChar *content;
  3970. if (annot == NULL)
  3971. return;
  3972. content = xmlNodeGetContent(annot->content);
  3973. if (content != NULL) {
  3974. fprintf(output, " Annot: %s\n", content);
  3975. xmlFree(content);
  3976. } else
  3977. fprintf(output, " Annot: empty\n");
  3978. }
  3979. /**
  3980. * xmlSchemaContentModelDump:
  3981. * @particle: the schema particle
  3982. * @output: the file output
  3983. * @depth: the depth used for indentation
  3984. *
  3985. * Dump a SchemaType structure
  3986. */
  3987. static void
  3988. xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
  3989. {
  3990. xmlChar *str = NULL;
  3991. xmlSchemaTreeItemPtr term;
  3992. char shift[100];
  3993. int i;
  3994. if (particle == NULL)
  3995. return;
  3996. for (i = 0;((i < depth) && (i < 25));i++)
  3997. shift[2 * i] = shift[2 * i + 1] = ' ';
  3998. shift[2 * i] = shift[2 * i + 1] = 0;
  3999. fprintf(output, "%s", shift);
  4000. if (particle->children == NULL) {
  4001. fprintf(output, "MISSING particle term\n");
  4002. return;
  4003. }
  4004. term = particle->children;
  4005. if (term == NULL) {
  4006. fprintf(output, "(NULL)");
  4007. } else {
  4008. switch (term->type) {
  4009. case XML_SCHEMA_TYPE_ELEMENT:
  4010. fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
  4011. ((xmlSchemaElementPtr)term)->targetNamespace,
  4012. ((xmlSchemaElementPtr)term)->name));
  4013. FREE_AND_NULL(str);
  4014. break;
  4015. case XML_SCHEMA_TYPE_SEQUENCE:
  4016. fprintf(output, "SEQUENCE");
  4017. break;
  4018. case XML_SCHEMA_TYPE_CHOICE:
  4019. fprintf(output, "CHOICE");
  4020. break;
  4021. case XML_SCHEMA_TYPE_ALL:
  4022. fprintf(output, "ALL");
  4023. break;
  4024. case XML_SCHEMA_TYPE_ANY:
  4025. fprintf(output, "ANY");
  4026. break;
  4027. default:
  4028. fprintf(output, "UNKNOWN\n");
  4029. return;
  4030. }
  4031. }
  4032. if (particle->minOccurs != 1)
  4033. fprintf(output, " min: %d", particle->minOccurs);
  4034. if (particle->maxOccurs >= UNBOUNDED)
  4035. fprintf(output, " max: unbounded");
  4036. else if (particle->maxOccurs != 1)
  4037. fprintf(output, " max: %d", particle->maxOccurs);
  4038. fprintf(output, "\n");
  4039. if (term &&
  4040. ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  4041. (term->type == XML_SCHEMA_TYPE_CHOICE) ||
  4042. (term->type == XML_SCHEMA_TYPE_ALL)) &&
  4043. (term->children != NULL)) {
  4044. xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
  4045. output, depth +1);
  4046. }
  4047. if (particle->next != NULL)
  4048. xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
  4049. output, depth);
  4050. }
  4051. /**
  4052. * xmlSchemaAttrUsesDump:
  4053. * @uses: attribute uses list
  4054. * @output: the file output
  4055. *
  4056. * Dumps a list of attribute use components.
  4057. */
  4058. static void
  4059. xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
  4060. {
  4061. xmlSchemaAttributeUsePtr use;
  4062. xmlSchemaAttributeUseProhibPtr prohib;
  4063. xmlSchemaQNameRefPtr ref;
  4064. const xmlChar *name, *tns;
  4065. xmlChar *str = NULL;
  4066. int i;
  4067. if ((uses == NULL) || (uses->nbItems == 0))
  4068. return;
  4069. fprintf(output, " attributes:\n");
  4070. for (i = 0; i < uses->nbItems; i++) {
  4071. use = uses->items[i];
  4072. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  4073. fprintf(output, " [prohibition] ");
  4074. prohib = (xmlSchemaAttributeUseProhibPtr) use;
  4075. name = prohib->name;
  4076. tns = prohib->targetNamespace;
  4077. } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
  4078. fprintf(output, " [reference] ");
  4079. ref = (xmlSchemaQNameRefPtr) use;
  4080. name = ref->name;
  4081. tns = ref->targetNamespace;
  4082. } else {
  4083. fprintf(output, " [use] ");
  4084. name = WXS_ATTRUSE_DECL_NAME(use);
  4085. tns = WXS_ATTRUSE_DECL_TNS(use);
  4086. }
  4087. fprintf(output, "'%s'\n",
  4088. (const char *) xmlSchemaFormatQName(&str, tns, name));
  4089. FREE_AND_NULL(str);
  4090. }
  4091. }
  4092. /**
  4093. * xmlSchemaTypeDump:
  4094. * @output: the file output
  4095. * @type: a type structure
  4096. *
  4097. * Dump a SchemaType structure
  4098. */
  4099. static void
  4100. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
  4101. {
  4102. if (type == NULL) {
  4103. fprintf(output, "Type: NULL\n");
  4104. return;
  4105. }
  4106. fprintf(output, "Type: ");
  4107. if (type->name != NULL)
  4108. fprintf(output, "'%s' ", type->name);
  4109. else
  4110. fprintf(output, "(no name) ");
  4111. if (type->targetNamespace != NULL)
  4112. fprintf(output, "ns '%s' ", type->targetNamespace);
  4113. switch (type->type) {
  4114. case XML_SCHEMA_TYPE_BASIC:
  4115. fprintf(output, "[basic] ");
  4116. break;
  4117. case XML_SCHEMA_TYPE_SIMPLE:
  4118. fprintf(output, "[simple] ");
  4119. break;
  4120. case XML_SCHEMA_TYPE_COMPLEX:
  4121. fprintf(output, "[complex] ");
  4122. break;
  4123. case XML_SCHEMA_TYPE_SEQUENCE:
  4124. fprintf(output, "[sequence] ");
  4125. break;
  4126. case XML_SCHEMA_TYPE_CHOICE:
  4127. fprintf(output, "[choice] ");
  4128. break;
  4129. case XML_SCHEMA_TYPE_ALL:
  4130. fprintf(output, "[all] ");
  4131. break;
  4132. case XML_SCHEMA_TYPE_UR:
  4133. fprintf(output, "[ur] ");
  4134. break;
  4135. case XML_SCHEMA_TYPE_RESTRICTION:
  4136. fprintf(output, "[restriction] ");
  4137. break;
  4138. case XML_SCHEMA_TYPE_EXTENSION:
  4139. fprintf(output, "[extension] ");
  4140. break;
  4141. default:
  4142. fprintf(output, "[unknown type %d] ", type->type);
  4143. break;
  4144. }
  4145. fprintf(output, "content: ");
  4146. switch (type->contentType) {
  4147. case XML_SCHEMA_CONTENT_UNKNOWN:
  4148. fprintf(output, "[unknown] ");
  4149. break;
  4150. case XML_SCHEMA_CONTENT_EMPTY:
  4151. fprintf(output, "[empty] ");
  4152. break;
  4153. case XML_SCHEMA_CONTENT_ELEMENTS:
  4154. fprintf(output, "[element] ");
  4155. break;
  4156. case XML_SCHEMA_CONTENT_MIXED:
  4157. fprintf(output, "[mixed] ");
  4158. break;
  4159. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  4160. /* not used. */
  4161. break;
  4162. case XML_SCHEMA_CONTENT_BASIC:
  4163. fprintf(output, "[basic] ");
  4164. break;
  4165. case XML_SCHEMA_CONTENT_SIMPLE:
  4166. fprintf(output, "[simple] ");
  4167. break;
  4168. case XML_SCHEMA_CONTENT_ANY:
  4169. fprintf(output, "[any] ");
  4170. break;
  4171. }
  4172. fprintf(output, "\n");
  4173. if (type->base != NULL) {
  4174. fprintf(output, " base type: '%s'", type->base);
  4175. if (type->baseNs != NULL)
  4176. fprintf(output, " ns '%s'\n", type->baseNs);
  4177. else
  4178. fprintf(output, "\n");
  4179. }
  4180. if (type->attrUses != NULL)
  4181. xmlSchemaAttrUsesDump(type->attrUses, output);
  4182. if (type->annot != NULL)
  4183. xmlSchemaAnnotDump(output, type->annot);
  4184. #ifdef DUMP_CONTENT_MODEL
  4185. if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
  4186. (type->subtypes != NULL)) {
  4187. xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
  4188. output, 1);
  4189. }
  4190. #endif
  4191. }
  4192. static void
  4193. xmlSchemaTypeDumpEntry(void *type, void *output,
  4194. const xmlChar *name ATTRIBUTE_UNUSED)
  4195. {
  4196. xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
  4197. }
  4198. /**
  4199. * xmlSchemaDump:
  4200. * @output: the file output
  4201. * @schema: a schema structure
  4202. *
  4203. * Dump a Schema structure.
  4204. */
  4205. void
  4206. xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
  4207. {
  4208. if (output == NULL)
  4209. return;
  4210. if (schema == NULL) {
  4211. fprintf(output, "Schemas: NULL\n");
  4212. return;
  4213. }
  4214. fprintf(output, "Schemas: ");
  4215. if (schema->name != NULL)
  4216. fprintf(output, "%s, ", schema->name);
  4217. else
  4218. fprintf(output, "no name, ");
  4219. if (schema->targetNamespace != NULL)
  4220. fprintf(output, "%s", (const char *) schema->targetNamespace);
  4221. else
  4222. fprintf(output, "no target namespace");
  4223. fprintf(output, "\n");
  4224. if (schema->annot != NULL)
  4225. xmlSchemaAnnotDump(output, schema->annot);
  4226. xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
  4227. xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
  4228. }
  4229. #endif /* LIBXML_OUTPUT_ENABLED */
  4230. /************************************************************************
  4231. * *
  4232. * Utilities *
  4233. * *
  4234. ************************************************************************/
  4235. /**
  4236. * xmlSchemaGetPropNode:
  4237. * @node: the element node
  4238. * @name: the name of the attribute
  4239. *
  4240. * Seeks an attribute with a name of @name in
  4241. * no namespace.
  4242. *
  4243. * Returns the attribute or NULL if not present.
  4244. */
  4245. static xmlAttrPtr
  4246. xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
  4247. {
  4248. xmlAttrPtr prop;
  4249. if ((node == NULL) || (name == NULL))
  4250. return(NULL);
  4251. prop = node->properties;
  4252. while (prop != NULL) {
  4253. if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
  4254. return(prop);
  4255. prop = prop->next;
  4256. }
  4257. return (NULL);
  4258. }
  4259. /**
  4260. * xmlSchemaGetPropNodeNs:
  4261. * @node: the element node
  4262. * @uri: the uri
  4263. * @name: the name of the attribute
  4264. *
  4265. * Seeks an attribute with a local name of @name and
  4266. * a namespace URI of @uri.
  4267. *
  4268. * Returns the attribute or NULL if not present.
  4269. */
  4270. static xmlAttrPtr
  4271. xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
  4272. {
  4273. xmlAttrPtr prop;
  4274. if ((node == NULL) || (name == NULL))
  4275. return(NULL);
  4276. prop = node->properties;
  4277. while (prop != NULL) {
  4278. if ((prop->ns != NULL) &&
  4279. xmlStrEqual(prop->name, BAD_CAST name) &&
  4280. xmlStrEqual(prop->ns->href, BAD_CAST uri))
  4281. return(prop);
  4282. prop = prop->next;
  4283. }
  4284. return (NULL);
  4285. }
  4286. static const xmlChar *
  4287. xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  4288. {
  4289. xmlChar *val;
  4290. const xmlChar *ret;
  4291. val = xmlNodeGetContent(node);
  4292. if (val == NULL)
  4293. val = xmlStrdup((xmlChar *)"");
  4294. ret = xmlDictLookup(ctxt->dict, val, -1);
  4295. xmlFree(val);
  4296. if (ret == NULL)
  4297. xmlSchemaPErrMemory(ctxt, "getting node content", node);
  4298. return(ret);
  4299. }
  4300. static const xmlChar *
  4301. xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
  4302. {
  4303. return((const xmlChar*) xmlNodeGetContent(node));
  4304. }
  4305. /**
  4306. * xmlSchemaGetProp:
  4307. * @ctxt: the parser context
  4308. * @node: the node
  4309. * @name: the property name
  4310. *
  4311. * Read a attribute value and internalize the string
  4312. *
  4313. * Returns the string or NULL if not present.
  4314. */
  4315. static const xmlChar *
  4316. xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  4317. const char *name)
  4318. {
  4319. xmlChar *val;
  4320. const xmlChar *ret;
  4321. val = xmlGetNoNsProp(node, BAD_CAST name);
  4322. if (val == NULL)
  4323. return(NULL);
  4324. ret = xmlDictLookup(ctxt->dict, val, -1);
  4325. xmlFree(val);
  4326. return(ret);
  4327. }
  4328. /************************************************************************
  4329. * *
  4330. * Parsing functions *
  4331. * *
  4332. ************************************************************************/
  4333. #define WXS_FIND_GLOBAL_ITEM(slot) \
  4334. if (xmlStrEqual(nsName, schema->targetNamespace)) { \
  4335. ret = xmlHashLookup(schema->slot, name); \
  4336. if (ret != NULL) goto exit; \
  4337. } \
  4338. if (xmlHashSize(schema->schemasImports) > 1) { \
  4339. xmlSchemaImportPtr import; \
  4340. if (nsName == NULL) \
  4341. import = xmlHashLookup(schema->schemasImports, \
  4342. XML_SCHEMAS_NO_NAMESPACE); \
  4343. else \
  4344. import = xmlHashLookup(schema->schemasImports, nsName); \
  4345. if (import == NULL) \
  4346. goto exit; \
  4347. ret = xmlHashLookup(import->schema->slot, name); \
  4348. }
  4349. /**
  4350. * xmlSchemaGetElem:
  4351. * @schema: the schema context
  4352. * @name: the element name
  4353. * @ns: the element namespace
  4354. *
  4355. * Lookup a global element declaration in the schema.
  4356. *
  4357. * Returns the element declaration or NULL if not found.
  4358. */
  4359. static xmlSchemaElementPtr
  4360. xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
  4361. const xmlChar * nsName)
  4362. {
  4363. xmlSchemaElementPtr ret = NULL;
  4364. if ((name == NULL) || (schema == NULL))
  4365. return(NULL);
  4366. if (schema != NULL) {
  4367. WXS_FIND_GLOBAL_ITEM(elemDecl)
  4368. }
  4369. exit:
  4370. return (ret);
  4371. }
  4372. /**
  4373. * xmlSchemaGetType:
  4374. * @schema: the main schema
  4375. * @name: the type's name
  4376. * nsName: the type's namespace
  4377. *
  4378. * Lookup a type in the schemas or the predefined types
  4379. *
  4380. * Returns the group definition or NULL if not found.
  4381. */
  4382. static xmlSchemaTypePtr
  4383. xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
  4384. const xmlChar * nsName)
  4385. {
  4386. xmlSchemaTypePtr ret = NULL;
  4387. if (name == NULL)
  4388. return (NULL);
  4389. /* First try the built-in types. */
  4390. if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
  4391. ret = xmlSchemaGetPredefinedType(name, nsName);
  4392. if (ret != NULL)
  4393. goto exit;
  4394. /*
  4395. * Note that we try the parsed schemas as well here
  4396. * since one might have parsed the S4S, which contain more
  4397. * than the built-in types.
  4398. * TODO: Can we optimize this?
  4399. */
  4400. }
  4401. if (schema != NULL) {
  4402. WXS_FIND_GLOBAL_ITEM(typeDecl)
  4403. }
  4404. exit:
  4405. return (ret);
  4406. }
  4407. /**
  4408. * xmlSchemaGetAttributeDecl:
  4409. * @schema: the context of the schema
  4410. * @name: the name of the attribute
  4411. * @ns: the target namespace of the attribute
  4412. *
  4413. * Lookup a an attribute in the schema or imported schemas
  4414. *
  4415. * Returns the attribute declaration or NULL if not found.
  4416. */
  4417. static xmlSchemaAttributePtr
  4418. xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
  4419. const xmlChar * nsName)
  4420. {
  4421. xmlSchemaAttributePtr ret = NULL;
  4422. if ((name == NULL) || (schema == NULL))
  4423. return (NULL);
  4424. if (schema != NULL) {
  4425. WXS_FIND_GLOBAL_ITEM(attrDecl)
  4426. }
  4427. exit:
  4428. return (ret);
  4429. }
  4430. /**
  4431. * xmlSchemaGetAttributeGroup:
  4432. * @schema: the context of the schema
  4433. * @name: the name of the attribute group
  4434. * @ns: the target namespace of the attribute group
  4435. *
  4436. * Lookup a an attribute group in the schema or imported schemas
  4437. *
  4438. * Returns the attribute group definition or NULL if not found.
  4439. */
  4440. static xmlSchemaAttributeGroupPtr
  4441. xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
  4442. const xmlChar * nsName)
  4443. {
  4444. xmlSchemaAttributeGroupPtr ret = NULL;
  4445. if ((name == NULL) || (schema == NULL))
  4446. return (NULL);
  4447. if (schema != NULL) {
  4448. WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
  4449. }
  4450. exit:
  4451. /* TODO:
  4452. if ((ret != NULL) && (ret->redef != NULL)) {
  4453. * Return the last redefinition. *
  4454. ret = ret->redef;
  4455. }
  4456. */
  4457. return (ret);
  4458. }
  4459. /**
  4460. * xmlSchemaGetGroup:
  4461. * @schema: the context of the schema
  4462. * @name: the name of the group
  4463. * @ns: the target namespace of the group
  4464. *
  4465. * Lookup a group in the schema or imported schemas
  4466. *
  4467. * Returns the group definition or NULL if not found.
  4468. */
  4469. static xmlSchemaModelGroupDefPtr
  4470. xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
  4471. const xmlChar * nsName)
  4472. {
  4473. xmlSchemaModelGroupDefPtr ret = NULL;
  4474. if ((name == NULL) || (schema == NULL))
  4475. return (NULL);
  4476. if (schema != NULL) {
  4477. WXS_FIND_GLOBAL_ITEM(groupDecl)
  4478. }
  4479. exit:
  4480. return (ret);
  4481. }
  4482. static xmlSchemaNotationPtr
  4483. xmlSchemaGetNotation(xmlSchemaPtr schema,
  4484. const xmlChar *name,
  4485. const xmlChar *nsName)
  4486. {
  4487. xmlSchemaNotationPtr ret = NULL;
  4488. if ((name == NULL) || (schema == NULL))
  4489. return (NULL);
  4490. if (schema != NULL) {
  4491. WXS_FIND_GLOBAL_ITEM(notaDecl)
  4492. }
  4493. exit:
  4494. return (ret);
  4495. }
  4496. static xmlSchemaIDCPtr
  4497. xmlSchemaGetIDC(xmlSchemaPtr schema,
  4498. const xmlChar *name,
  4499. const xmlChar *nsName)
  4500. {
  4501. xmlSchemaIDCPtr ret = NULL;
  4502. if ((name == NULL) || (schema == NULL))
  4503. return (NULL);
  4504. if (schema != NULL) {
  4505. WXS_FIND_GLOBAL_ITEM(idcDef)
  4506. }
  4507. exit:
  4508. return (ret);
  4509. }
  4510. /**
  4511. * xmlSchemaGetNamedComponent:
  4512. * @schema: the schema
  4513. * @name: the name of the group
  4514. * @ns: the target namespace of the group
  4515. *
  4516. * Lookup a group in the schema or imported schemas
  4517. *
  4518. * Returns the group definition or NULL if not found.
  4519. */
  4520. static xmlSchemaBasicItemPtr
  4521. xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
  4522. xmlSchemaTypeType itemType,
  4523. const xmlChar *name,
  4524. const xmlChar *targetNs)
  4525. {
  4526. switch (itemType) {
  4527. case XML_SCHEMA_TYPE_GROUP:
  4528. return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
  4529. name, targetNs));
  4530. case XML_SCHEMA_TYPE_ELEMENT:
  4531. return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
  4532. name, targetNs));
  4533. default:
  4534. TODO
  4535. return (NULL);
  4536. }
  4537. }
  4538. /************************************************************************
  4539. * *
  4540. * Parsing functions *
  4541. * *
  4542. ************************************************************************/
  4543. #define IS_BLANK_NODE(n) \
  4544. (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
  4545. /**
  4546. * xmlSchemaIsBlank:
  4547. * @str: a string
  4548. * @len: the length of the string or -1
  4549. *
  4550. * Check if a string is ignorable
  4551. *
  4552. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  4553. */
  4554. static int
  4555. xmlSchemaIsBlank(xmlChar * str, int len)
  4556. {
  4557. if (str == NULL)
  4558. return (1);
  4559. if (len < 0) {
  4560. while (*str != 0) {
  4561. if (!(IS_BLANK_CH(*str)))
  4562. return (0);
  4563. str++;
  4564. }
  4565. } else while ((*str != 0) && (len != 0)) {
  4566. if (!(IS_BLANK_CH(*str)))
  4567. return (0);
  4568. str++;
  4569. len--;
  4570. }
  4571. return (1);
  4572. }
  4573. #define WXS_COMP_NAME(c, t) ((t) (c))->name
  4574. #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
  4575. /*
  4576. * xmlSchemaFindRedefCompInGraph:
  4577. * ATTENTION TODO: This uses pointer comp. for strings.
  4578. */
  4579. static xmlSchemaBasicItemPtr
  4580. xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
  4581. xmlSchemaTypeType type,
  4582. const xmlChar *name,
  4583. const xmlChar *nsName)
  4584. {
  4585. xmlSchemaBasicItemPtr ret;
  4586. int i;
  4587. if ((bucket == NULL) || (name == NULL))
  4588. return(NULL);
  4589. if ((bucket->globals == NULL) ||
  4590. (bucket->globals->nbItems == 0))
  4591. goto subschemas;
  4592. /*
  4593. * Search in global components.
  4594. */
  4595. for (i = 0; i < bucket->globals->nbItems; i++) {
  4596. ret = bucket->globals->items[i];
  4597. if (ret->type == type) {
  4598. switch (type) {
  4599. case XML_SCHEMA_TYPE_COMPLEX:
  4600. case XML_SCHEMA_TYPE_SIMPLE:
  4601. if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
  4602. (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
  4603. nsName))
  4604. {
  4605. return(ret);
  4606. }
  4607. break;
  4608. case XML_SCHEMA_TYPE_GROUP:
  4609. if ((WXS_COMP_NAME(ret,
  4610. xmlSchemaModelGroupDefPtr) == name) &&
  4611. (WXS_COMP_TNS(ret,
  4612. xmlSchemaModelGroupDefPtr) == nsName))
  4613. {
  4614. return(ret);
  4615. }
  4616. break;
  4617. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  4618. if ((WXS_COMP_NAME(ret,
  4619. xmlSchemaAttributeGroupPtr) == name) &&
  4620. (WXS_COMP_TNS(ret,
  4621. xmlSchemaAttributeGroupPtr) == nsName))
  4622. {
  4623. return(ret);
  4624. }
  4625. break;
  4626. default:
  4627. /* Should not be hit. */
  4628. return(NULL);
  4629. }
  4630. }
  4631. }
  4632. subschemas:
  4633. /*
  4634. * Process imported/included schemas.
  4635. */
  4636. if (bucket->relations != NULL) {
  4637. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  4638. /*
  4639. * TODO: Marking the bucket will not avoid multiple searches
  4640. * in the same schema, but avoids at least circularity.
  4641. */
  4642. bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
  4643. do {
  4644. if ((rel->bucket != NULL) &&
  4645. ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
  4646. ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
  4647. type, name, nsName);
  4648. if (ret != NULL)
  4649. return(ret);
  4650. }
  4651. rel = rel->next;
  4652. } while (rel != NULL);
  4653. bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
  4654. }
  4655. return(NULL);
  4656. }
  4657. /**
  4658. * xmlSchemaAddNotation:
  4659. * @ctxt: a schema parser context
  4660. * @schema: the schema being built
  4661. * @name: the item name
  4662. *
  4663. * Add an XML schema annotation declaration
  4664. * *WARNING* this interface is highly subject to change
  4665. *
  4666. * Returns the new structure or NULL in case of error
  4667. */
  4668. static xmlSchemaNotationPtr
  4669. xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4670. const xmlChar *name, const xmlChar *nsName,
  4671. xmlNodePtr node ATTRIBUTE_UNUSED)
  4672. {
  4673. xmlSchemaNotationPtr ret = NULL;
  4674. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  4675. return (NULL);
  4676. ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
  4677. if (ret == NULL) {
  4678. xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
  4679. return (NULL);
  4680. }
  4681. memset(ret, 0, sizeof(xmlSchemaNotation));
  4682. ret->type = XML_SCHEMA_TYPE_NOTATION;
  4683. ret->name = name;
  4684. ret->targetNamespace = nsName;
  4685. /* TODO: do we need the node to be set?
  4686. * ret->node = node;*/
  4687. WXS_ADD_GLOBAL(ctxt, ret);
  4688. return (ret);
  4689. }
  4690. /**
  4691. * xmlSchemaAddAttribute:
  4692. * @ctxt: a schema parser context
  4693. * @schema: the schema being built
  4694. * @name: the item name
  4695. * @namespace: the namespace
  4696. *
  4697. * Add an XML schema Attribute declaration
  4698. * *WARNING* this interface is highly subject to change
  4699. *
  4700. * Returns the new structure or NULL in case of error
  4701. */
  4702. static xmlSchemaAttributePtr
  4703. xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4704. const xmlChar * name, const xmlChar * nsName,
  4705. xmlNodePtr node, int topLevel)
  4706. {
  4707. xmlSchemaAttributePtr ret = NULL;
  4708. if ((ctxt == NULL) || (schema == NULL))
  4709. return (NULL);
  4710. ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
  4711. if (ret == NULL) {
  4712. xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
  4713. return (NULL);
  4714. }
  4715. memset(ret, 0, sizeof(xmlSchemaAttribute));
  4716. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
  4717. ret->node = node;
  4718. ret->name = name;
  4719. ret->targetNamespace = nsName;
  4720. if (topLevel)
  4721. WXS_ADD_GLOBAL(ctxt, ret);
  4722. else
  4723. WXS_ADD_LOCAL(ctxt, ret);
  4724. WXS_ADD_PENDING(ctxt, ret);
  4725. return (ret);
  4726. }
  4727. /**
  4728. * xmlSchemaAddAttributeUse:
  4729. * @ctxt: a schema parser context
  4730. * @schema: the schema being built
  4731. * @name: the item name
  4732. * @namespace: the namespace
  4733. *
  4734. * Add an XML schema Attribute declaration
  4735. * *WARNING* this interface is highly subject to change
  4736. *
  4737. * Returns the new structure or NULL in case of error
  4738. */
  4739. static xmlSchemaAttributeUsePtr
  4740. xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
  4741. xmlNodePtr node)
  4742. {
  4743. xmlSchemaAttributeUsePtr ret = NULL;
  4744. if (pctxt == NULL)
  4745. return (NULL);
  4746. ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
  4747. if (ret == NULL) {
  4748. xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
  4749. return (NULL);
  4750. }
  4751. memset(ret, 0, sizeof(xmlSchemaAttributeUse));
  4752. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
  4753. ret->node = node;
  4754. WXS_ADD_LOCAL(pctxt, ret);
  4755. return (ret);
  4756. }
  4757. /*
  4758. * xmlSchemaAddRedef:
  4759. *
  4760. * Adds a redefinition information. This is used at a later stage to:
  4761. * resolve references to the redefined components and to check constraints.
  4762. */
  4763. static xmlSchemaRedefPtr
  4764. xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
  4765. xmlSchemaBucketPtr targetBucket,
  4766. void *item,
  4767. const xmlChar *refName,
  4768. const xmlChar *refTargetNs)
  4769. {
  4770. xmlSchemaRedefPtr ret;
  4771. ret = (xmlSchemaRedefPtr)
  4772. xmlMalloc(sizeof(xmlSchemaRedef));
  4773. if (ret == NULL) {
  4774. xmlSchemaPErrMemory(pctxt,
  4775. "allocating redefinition info", NULL);
  4776. return (NULL);
  4777. }
  4778. memset(ret, 0, sizeof(xmlSchemaRedef));
  4779. ret->item = item;
  4780. ret->targetBucket = targetBucket;
  4781. ret->refName = refName;
  4782. ret->refTargetNs = refTargetNs;
  4783. if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
  4784. WXS_CONSTRUCTOR(pctxt)->redefs = ret;
  4785. else
  4786. WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
  4787. WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
  4788. return (ret);
  4789. }
  4790. /**
  4791. * xmlSchemaAddAttributeGroupDefinition:
  4792. * @ctxt: a schema parser context
  4793. * @schema: the schema being built
  4794. * @name: the item name
  4795. * @nsName: the target namespace
  4796. * @node: the corresponding node
  4797. *
  4798. * Add an XML schema Attribute Group definition.
  4799. *
  4800. * Returns the new structure or NULL in case of error
  4801. */
  4802. static xmlSchemaAttributeGroupPtr
  4803. xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  4804. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  4805. const xmlChar *name,
  4806. const xmlChar *nsName,
  4807. xmlNodePtr node)
  4808. {
  4809. xmlSchemaAttributeGroupPtr ret = NULL;
  4810. if ((pctxt == NULL) || (name == NULL))
  4811. return (NULL);
  4812. ret = (xmlSchemaAttributeGroupPtr)
  4813. xmlMalloc(sizeof(xmlSchemaAttributeGroup));
  4814. if (ret == NULL) {
  4815. xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
  4816. return (NULL);
  4817. }
  4818. memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
  4819. ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
  4820. ret->name = name;
  4821. ret->targetNamespace = nsName;
  4822. ret->node = node;
  4823. /* TODO: Remove the flag. */
  4824. ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
  4825. if (pctxt->isRedefine) {
  4826. pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
  4827. ret, name, nsName);
  4828. if (pctxt->redef == NULL) {
  4829. xmlFree(ret);
  4830. return(NULL);
  4831. }
  4832. pctxt->redefCounter = 0;
  4833. }
  4834. WXS_ADD_GLOBAL(pctxt, ret);
  4835. WXS_ADD_PENDING(pctxt, ret);
  4836. return (ret);
  4837. }
  4838. /**
  4839. * xmlSchemaAddElement:
  4840. * @ctxt: a schema parser context
  4841. * @schema: the schema being built
  4842. * @name: the type name
  4843. * @namespace: the type namespace
  4844. *
  4845. * Add an XML schema Element declaration
  4846. * *WARNING* this interface is highly subject to change
  4847. *
  4848. * Returns the new structure or NULL in case of error
  4849. */
  4850. static xmlSchemaElementPtr
  4851. xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
  4852. const xmlChar * name, const xmlChar * nsName,
  4853. xmlNodePtr node, int topLevel)
  4854. {
  4855. xmlSchemaElementPtr ret = NULL;
  4856. if ((ctxt == NULL) || (name == NULL))
  4857. return (NULL);
  4858. ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
  4859. if (ret == NULL) {
  4860. xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
  4861. return (NULL);
  4862. }
  4863. memset(ret, 0, sizeof(xmlSchemaElement));
  4864. ret->type = XML_SCHEMA_TYPE_ELEMENT;
  4865. ret->name = name;
  4866. ret->targetNamespace = nsName;
  4867. ret->node = node;
  4868. if (topLevel)
  4869. WXS_ADD_GLOBAL(ctxt, ret);
  4870. else
  4871. WXS_ADD_LOCAL(ctxt, ret);
  4872. WXS_ADD_PENDING(ctxt, ret);
  4873. return (ret);
  4874. }
  4875. /**
  4876. * xmlSchemaAddType:
  4877. * @ctxt: a schema parser context
  4878. * @schema: the schema being built
  4879. * @name: the item name
  4880. * @namespace: the namespace
  4881. *
  4882. * Add an XML schema item
  4883. * *WARNING* this interface is highly subject to change
  4884. *
  4885. * Returns the new structure or NULL in case of error
  4886. */
  4887. static xmlSchemaTypePtr
  4888. xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4889. xmlSchemaTypeType type,
  4890. const xmlChar * name, const xmlChar * nsName,
  4891. xmlNodePtr node, int topLevel)
  4892. {
  4893. xmlSchemaTypePtr ret = NULL;
  4894. if ((ctxt == NULL) || (schema == NULL))
  4895. return (NULL);
  4896. ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
  4897. if (ret == NULL) {
  4898. xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
  4899. return (NULL);
  4900. }
  4901. memset(ret, 0, sizeof(xmlSchemaType));
  4902. ret->type = type;
  4903. ret->name = name;
  4904. ret->targetNamespace = nsName;
  4905. ret->node = node;
  4906. if (topLevel) {
  4907. if (ctxt->isRedefine) {
  4908. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  4909. ret, name, nsName);
  4910. if (ctxt->redef == NULL) {
  4911. xmlFree(ret);
  4912. return(NULL);
  4913. }
  4914. ctxt->redefCounter = 0;
  4915. }
  4916. WXS_ADD_GLOBAL(ctxt, ret);
  4917. } else
  4918. WXS_ADD_LOCAL(ctxt, ret);
  4919. WXS_ADD_PENDING(ctxt, ret);
  4920. return (ret);
  4921. }
  4922. static xmlSchemaQNameRefPtr
  4923. xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
  4924. xmlSchemaTypeType refType,
  4925. const xmlChar *refName,
  4926. const xmlChar *refNs)
  4927. {
  4928. xmlSchemaQNameRefPtr ret;
  4929. ret = (xmlSchemaQNameRefPtr)
  4930. xmlMalloc(sizeof(xmlSchemaQNameRef));
  4931. if (ret == NULL) {
  4932. xmlSchemaPErrMemory(pctxt,
  4933. "allocating QName reference item", NULL);
  4934. return (NULL);
  4935. }
  4936. ret->node = NULL;
  4937. ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
  4938. ret->name = refName;
  4939. ret->targetNamespace = refNs;
  4940. ret->item = NULL;
  4941. ret->itemType = refType;
  4942. /*
  4943. * Store the reference item in the schema.
  4944. */
  4945. WXS_ADD_LOCAL(pctxt, ret);
  4946. return (ret);
  4947. }
  4948. static xmlSchemaAttributeUseProhibPtr
  4949. xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
  4950. {
  4951. xmlSchemaAttributeUseProhibPtr ret;
  4952. ret = (xmlSchemaAttributeUseProhibPtr)
  4953. xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
  4954. if (ret == NULL) {
  4955. xmlSchemaPErrMemory(pctxt,
  4956. "allocating attribute use prohibition", NULL);
  4957. return (NULL);
  4958. }
  4959. memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
  4960. ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
  4961. WXS_ADD_LOCAL(pctxt, ret);
  4962. return (ret);
  4963. }
  4964. /**
  4965. * xmlSchemaAddModelGroup:
  4966. * @ctxt: a schema parser context
  4967. * @schema: the schema being built
  4968. * @type: the "compositor" type of the model group
  4969. * @node: the node in the schema doc
  4970. *
  4971. * Adds a schema model group
  4972. * *WARNING* this interface is highly subject to change
  4973. *
  4974. * Returns the new structure or NULL in case of error
  4975. */
  4976. static xmlSchemaModelGroupPtr
  4977. xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
  4978. xmlSchemaPtr schema,
  4979. xmlSchemaTypeType type,
  4980. xmlNodePtr node)
  4981. {
  4982. xmlSchemaModelGroupPtr ret = NULL;
  4983. if ((ctxt == NULL) || (schema == NULL))
  4984. return (NULL);
  4985. ret = (xmlSchemaModelGroupPtr)
  4986. xmlMalloc(sizeof(xmlSchemaModelGroup));
  4987. if (ret == NULL) {
  4988. xmlSchemaPErrMemory(ctxt, "allocating model group component",
  4989. NULL);
  4990. return (NULL);
  4991. }
  4992. memset(ret, 0, sizeof(xmlSchemaModelGroup));
  4993. ret->type = type;
  4994. ret->node = node;
  4995. WXS_ADD_LOCAL(ctxt, ret);
  4996. if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
  4997. (type == XML_SCHEMA_TYPE_CHOICE))
  4998. WXS_ADD_PENDING(ctxt, ret);
  4999. return (ret);
  5000. }
  5001. /**
  5002. * xmlSchemaAddParticle:
  5003. * @ctxt: a schema parser context
  5004. * @schema: the schema being built
  5005. * @node: the corresponding node in the schema doc
  5006. * @min: the minOccurs
  5007. * @max: the maxOccurs
  5008. *
  5009. * Adds an XML schema particle component.
  5010. * *WARNING* this interface is highly subject to change
  5011. *
  5012. * Returns the new structure or NULL in case of error
  5013. */
  5014. static xmlSchemaParticlePtr
  5015. xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
  5016. xmlNodePtr node, int min, int max)
  5017. {
  5018. xmlSchemaParticlePtr ret = NULL;
  5019. if (ctxt == NULL)
  5020. return (NULL);
  5021. ret = (xmlSchemaParticlePtr)
  5022. xmlMalloc(sizeof(xmlSchemaParticle));
  5023. if (ret == NULL) {
  5024. xmlSchemaPErrMemory(ctxt, "allocating particle component",
  5025. NULL);
  5026. return (NULL);
  5027. }
  5028. ret->type = XML_SCHEMA_TYPE_PARTICLE;
  5029. ret->annot = NULL;
  5030. ret->node = node;
  5031. ret->minOccurs = min;
  5032. ret->maxOccurs = max;
  5033. ret->next = NULL;
  5034. ret->children = NULL;
  5035. WXS_ADD_LOCAL(ctxt, ret);
  5036. /*
  5037. * Note that addition to pending components will be done locally
  5038. * to the specific parsing function, since the most particles
  5039. * need not to be fixed up (i.e. the reference to be resolved).
  5040. * REMOVED: WXS_ADD_PENDING(ctxt, ret);
  5041. */
  5042. return (ret);
  5043. }
  5044. /**
  5045. * xmlSchemaAddModelGroupDefinition:
  5046. * @ctxt: a schema validation context
  5047. * @schema: the schema being built
  5048. * @name: the group name
  5049. *
  5050. * Add an XML schema Group definition
  5051. *
  5052. * Returns the new structure or NULL in case of error
  5053. */
  5054. static xmlSchemaModelGroupDefPtr
  5055. xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  5056. xmlSchemaPtr schema,
  5057. const xmlChar *name,
  5058. const xmlChar *nsName,
  5059. xmlNodePtr node)
  5060. {
  5061. xmlSchemaModelGroupDefPtr ret = NULL;
  5062. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5063. return (NULL);
  5064. ret = (xmlSchemaModelGroupDefPtr)
  5065. xmlMalloc(sizeof(xmlSchemaModelGroupDef));
  5066. if (ret == NULL) {
  5067. xmlSchemaPErrMemory(ctxt, "adding group", NULL);
  5068. return (NULL);
  5069. }
  5070. memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
  5071. ret->name = name;
  5072. ret->type = XML_SCHEMA_TYPE_GROUP;
  5073. ret->node = node;
  5074. ret->targetNamespace = nsName;
  5075. if (ctxt->isRedefine) {
  5076. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5077. ret, name, nsName);
  5078. if (ctxt->redef == NULL) {
  5079. xmlFree(ret);
  5080. return(NULL);
  5081. }
  5082. ctxt->redefCounter = 0;
  5083. }
  5084. WXS_ADD_GLOBAL(ctxt, ret);
  5085. WXS_ADD_PENDING(ctxt, ret);
  5086. return (ret);
  5087. }
  5088. /**
  5089. * xmlSchemaNewWildcardNs:
  5090. * @ctxt: a schema validation context
  5091. *
  5092. * Creates a new wildcard namespace constraint.
  5093. *
  5094. * Returns the new structure or NULL in case of error
  5095. */
  5096. static xmlSchemaWildcardNsPtr
  5097. xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
  5098. {
  5099. xmlSchemaWildcardNsPtr ret;
  5100. ret = (xmlSchemaWildcardNsPtr)
  5101. xmlMalloc(sizeof(xmlSchemaWildcardNs));
  5102. if (ret == NULL) {
  5103. xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
  5104. return (NULL);
  5105. }
  5106. ret->value = NULL;
  5107. ret->next = NULL;
  5108. return (ret);
  5109. }
  5110. static xmlSchemaIDCPtr
  5111. xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5112. const xmlChar *name, const xmlChar *nsName,
  5113. int category, xmlNodePtr node)
  5114. {
  5115. xmlSchemaIDCPtr ret = NULL;
  5116. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5117. return (NULL);
  5118. ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
  5119. if (ret == NULL) {
  5120. xmlSchemaPErrMemory(ctxt,
  5121. "allocating an identity-constraint definition", NULL);
  5122. return (NULL);
  5123. }
  5124. memset(ret, 0, sizeof(xmlSchemaIDC));
  5125. /* The target namespace of the parent element declaration. */
  5126. ret->targetNamespace = nsName;
  5127. ret->name = name;
  5128. ret->type = category;
  5129. ret->node = node;
  5130. WXS_ADD_GLOBAL(ctxt, ret);
  5131. /*
  5132. * Only keyrefs need to be fixup up.
  5133. */
  5134. if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
  5135. WXS_ADD_PENDING(ctxt, ret);
  5136. return (ret);
  5137. }
  5138. /**
  5139. * xmlSchemaAddWildcard:
  5140. * @ctxt: a schema validation context
  5141. * @schema: a schema
  5142. *
  5143. * Adds a wildcard.
  5144. * It corresponds to a xsd:anyAttribute and xsd:any.
  5145. *
  5146. * Returns the new structure or NULL in case of error
  5147. */
  5148. static xmlSchemaWildcardPtr
  5149. xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5150. xmlSchemaTypeType type, xmlNodePtr node)
  5151. {
  5152. xmlSchemaWildcardPtr ret = NULL;
  5153. if ((ctxt == NULL) || (schema == NULL))
  5154. return (NULL);
  5155. ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
  5156. if (ret == NULL) {
  5157. xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
  5158. return (NULL);
  5159. }
  5160. memset(ret, 0, sizeof(xmlSchemaWildcard));
  5161. ret->type = type;
  5162. ret->node = node;
  5163. WXS_ADD_LOCAL(ctxt, ret);
  5164. return (ret);
  5165. }
  5166. static void
  5167. xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
  5168. {
  5169. if (group == NULL)
  5170. return;
  5171. if (group->members != NULL)
  5172. xmlSchemaItemListFree(group->members);
  5173. xmlFree(group);
  5174. }
  5175. static void
  5176. xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
  5177. {
  5178. xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
  5179. }
  5180. static xmlSchemaSubstGroupPtr
  5181. xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
  5182. xmlSchemaElementPtr head)
  5183. {
  5184. xmlSchemaSubstGroupPtr ret;
  5185. /* Init subst group hash. */
  5186. if (WXS_SUBST_GROUPS(pctxt) == NULL) {
  5187. WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
  5188. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5189. return(NULL);
  5190. }
  5191. /* Create a new substitution group. */
  5192. ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
  5193. if (ret == NULL) {
  5194. xmlSchemaPErrMemory(NULL,
  5195. "allocating a substitution group container", NULL);
  5196. return(NULL);
  5197. }
  5198. memset(ret, 0, sizeof(xmlSchemaSubstGroup));
  5199. ret->head = head;
  5200. /* Create list of members. */
  5201. ret->members = xmlSchemaItemListCreate();
  5202. if (ret->members == NULL) {
  5203. xmlSchemaSubstGroupFree(ret);
  5204. return(NULL);
  5205. }
  5206. /* Add subst group to hash. */
  5207. if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
  5208. head->name, head->targetNamespace, ret) != 0) {
  5209. PERROR_INT("xmlSchemaSubstGroupAdd",
  5210. "failed to add a new substitution container");
  5211. xmlSchemaSubstGroupFree(ret);
  5212. return(NULL);
  5213. }
  5214. return(ret);
  5215. }
  5216. static xmlSchemaSubstGroupPtr
  5217. xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
  5218. xmlSchemaElementPtr head)
  5219. {
  5220. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5221. return(NULL);
  5222. return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
  5223. head->name, head->targetNamespace));
  5224. }
  5225. /**
  5226. * xmlSchemaAddElementSubstitutionMember:
  5227. * @pctxt: a schema parser context
  5228. * @head: the head of the substitution group
  5229. * @member: the new member of the substitution group
  5230. *
  5231. * Allocate a new annotation structure.
  5232. *
  5233. * Returns the newly allocated structure or NULL in case or error
  5234. */
  5235. static int
  5236. xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
  5237. xmlSchemaElementPtr head,
  5238. xmlSchemaElementPtr member)
  5239. {
  5240. xmlSchemaSubstGroupPtr substGroup = NULL;
  5241. if ((pctxt == NULL) || (head == NULL) || (member == NULL))
  5242. return (-1);
  5243. substGroup = xmlSchemaSubstGroupGet(pctxt, head);
  5244. if (substGroup == NULL)
  5245. substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
  5246. if (substGroup == NULL)
  5247. return(-1);
  5248. if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
  5249. return(-1);
  5250. return(0);
  5251. }
  5252. /************************************************************************
  5253. * *
  5254. * Utilities for parsing *
  5255. * *
  5256. ************************************************************************/
  5257. /**
  5258. * xmlSchemaPValAttrNodeQNameValue:
  5259. * @ctxt: a schema parser context
  5260. * @schema: the schema context
  5261. * @ownerItem: the parent as a schema object
  5262. * @value: the QName value
  5263. * @uri: the resulting namespace URI if found
  5264. * @local: the resulting local part if found, the attribute value otherwise
  5265. *
  5266. * Extracts the local name and the URI of a QName value and validates it.
  5267. * This one is intended to be used on attribute values that
  5268. * should resolve to schema components.
  5269. *
  5270. * Returns 0, in case the QName is valid, a positive error code
  5271. * if not valid and -1 if an internal error occurs.
  5272. */
  5273. static int
  5274. xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
  5275. xmlSchemaPtr schema,
  5276. xmlSchemaBasicItemPtr ownerItem,
  5277. xmlAttrPtr attr,
  5278. const xmlChar *value,
  5279. const xmlChar **uri,
  5280. const xmlChar **local)
  5281. {
  5282. const xmlChar *pref;
  5283. xmlNsPtr ns;
  5284. int len, ret;
  5285. *uri = NULL;
  5286. *local = NULL;
  5287. ret = xmlValidateQName(value, 1);
  5288. if (ret > 0) {
  5289. xmlSchemaPSimpleTypeErr(ctxt,
  5290. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5291. ownerItem, (xmlNodePtr) attr,
  5292. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  5293. NULL, value, NULL, NULL, NULL);
  5294. *local = value;
  5295. return (ctxt->err);
  5296. } else if (ret < 0)
  5297. return (-1);
  5298. if (!strchr((char *) value, ':')) {
  5299. ns = xmlSearchNs(attr->doc, attr->parent, NULL);
  5300. if (ns && ns->href && ns->href[0])
  5301. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5302. else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
  5303. /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
  5304. * parser context. */
  5305. /*
  5306. * This one takes care of included schemas with no
  5307. * target namespace.
  5308. */
  5309. *uri = ctxt->targetNamespace;
  5310. }
  5311. *local = xmlDictLookup(ctxt->dict, value, -1);
  5312. return (0);
  5313. }
  5314. /*
  5315. * At this point xmlSplitQName3 has to return a local name.
  5316. */
  5317. *local = xmlSplitQName3(value, &len);
  5318. *local = xmlDictLookup(ctxt->dict, *local, -1);
  5319. pref = xmlDictLookup(ctxt->dict, value, len);
  5320. ns = xmlSearchNs(attr->doc, attr->parent, pref);
  5321. if (ns == NULL) {
  5322. xmlSchemaPSimpleTypeErr(ctxt,
  5323. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5324. ownerItem, (xmlNodePtr) attr,
  5325. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
  5326. "The value '%s' of simple type 'xs:QName' has no "
  5327. "corresponding namespace declaration in scope", value, NULL);
  5328. return (ctxt->err);
  5329. } else {
  5330. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5331. }
  5332. return (0);
  5333. }
  5334. /**
  5335. * xmlSchemaPValAttrNodeQName:
  5336. * @ctxt: a schema parser context
  5337. * @schema: the schema context
  5338. * @ownerItem: the owner as a schema object
  5339. * @attr: the attribute node
  5340. * @uri: the resulting namespace URI if found
  5341. * @local: the resulting local part if found, the attribute value otherwise
  5342. *
  5343. * Extracts and validates the QName of an attribute value.
  5344. * This one is intended to be used on attribute values that
  5345. * should resolve to schema components.
  5346. *
  5347. * Returns 0, in case the QName is valid, a positive error code
  5348. * if not valid and -1 if an internal error occurs.
  5349. */
  5350. static int
  5351. xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
  5352. xmlSchemaPtr schema,
  5353. xmlSchemaBasicItemPtr ownerItem,
  5354. xmlAttrPtr attr,
  5355. const xmlChar **uri,
  5356. const xmlChar **local)
  5357. {
  5358. const xmlChar *value;
  5359. value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5360. return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  5361. ownerItem, attr, value, uri, local));
  5362. }
  5363. /**
  5364. * xmlSchemaPValAttrQName:
  5365. * @ctxt: a schema parser context
  5366. * @schema: the schema context
  5367. * @ownerItem: the owner as a schema object
  5368. * @ownerElem: the parent node of the attribute
  5369. * @name: the name of the attribute
  5370. * @uri: the resulting namespace URI if found
  5371. * @local: the resulting local part if found, the attribute value otherwise
  5372. *
  5373. * Extracts and validates the QName of an attribute value.
  5374. *
  5375. * Returns 0, in case the QName is valid, a positive error code
  5376. * if not valid and -1 if an internal error occurs.
  5377. */
  5378. static int
  5379. xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
  5380. xmlSchemaPtr schema,
  5381. xmlSchemaBasicItemPtr ownerItem,
  5382. xmlNodePtr ownerElem,
  5383. const char *name,
  5384. const xmlChar **uri,
  5385. const xmlChar **local)
  5386. {
  5387. xmlAttrPtr attr;
  5388. attr = xmlSchemaGetPropNode(ownerElem, name);
  5389. if (attr == NULL) {
  5390. *local = NULL;
  5391. *uri = NULL;
  5392. return (0);
  5393. }
  5394. return (xmlSchemaPValAttrNodeQName(ctxt, schema,
  5395. ownerItem, attr, uri, local));
  5396. }
  5397. /**
  5398. * xmlSchemaPValAttrID:
  5399. * @ctxt: a schema parser context
  5400. *
  5401. * Extracts and validates the ID of an attribute value.
  5402. *
  5403. * Returns 0, in case the ID is valid, a positive error code
  5404. * if not valid and -1 if an internal error occurs.
  5405. */
  5406. static int
  5407. xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
  5408. {
  5409. int ret;
  5410. const xmlChar *value;
  5411. if (attr == NULL)
  5412. return(0);
  5413. value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
  5414. ret = xmlValidateNCName(value, 1);
  5415. if (ret == 0) {
  5416. /*
  5417. * NOTE: the IDness might have already be declared in the DTD
  5418. */
  5419. if (attr->atype != XML_ATTRIBUTE_ID) {
  5420. xmlIDPtr res;
  5421. xmlChar *strip;
  5422. /*
  5423. * TODO: Use xmlSchemaStrip here; it's not exported at this
  5424. * moment.
  5425. */
  5426. strip = xmlSchemaCollapseString(value);
  5427. if (strip != NULL) {
  5428. xmlFree((xmlChar *) value);
  5429. value = strip;
  5430. }
  5431. res = xmlAddID(NULL, attr->doc, value, attr);
  5432. if (res == NULL) {
  5433. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5434. xmlSchemaPSimpleTypeErr(ctxt,
  5435. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5436. NULL, (xmlNodePtr) attr,
  5437. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5438. NULL, NULL, "Duplicate value '%s' of simple "
  5439. "type 'xs:ID'", value, NULL);
  5440. } else
  5441. attr->atype = XML_ATTRIBUTE_ID;
  5442. }
  5443. } else if (ret > 0) {
  5444. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5445. xmlSchemaPSimpleTypeErr(ctxt,
  5446. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5447. NULL, (xmlNodePtr) attr,
  5448. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5449. NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
  5450. "not a valid 'xs:NCName'",
  5451. value, NULL);
  5452. }
  5453. if (value != NULL)
  5454. xmlFree((xmlChar *)value);
  5455. return (ret);
  5456. }
  5457. static int
  5458. xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
  5459. xmlNodePtr ownerElem,
  5460. const xmlChar *name)
  5461. {
  5462. xmlAttrPtr attr;
  5463. attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
  5464. if (attr == NULL)
  5465. return(0);
  5466. return(xmlSchemaPValAttrNodeID(ctxt, attr));
  5467. }
  5468. /**
  5469. * xmlGetMaxOccurs:
  5470. * @ctxt: a schema validation context
  5471. * @node: a subtree containing XML Schema information
  5472. *
  5473. * Get the maxOccurs property
  5474. *
  5475. * Returns the default if not found, or the value
  5476. */
  5477. static int
  5478. xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5479. int min, int max, int def, const char *expected)
  5480. {
  5481. const xmlChar *val, *cur;
  5482. int ret = 0;
  5483. xmlAttrPtr attr;
  5484. attr = xmlSchemaGetPropNode(node, "maxOccurs");
  5485. if (attr == NULL)
  5486. return (def);
  5487. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5488. if (val == NULL)
  5489. return (def);
  5490. if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
  5491. if (max != UNBOUNDED) {
  5492. xmlSchemaPSimpleTypeErr(ctxt,
  5493. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5494. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5495. NULL, (xmlNodePtr) attr, NULL, expected,
  5496. val, NULL, NULL, NULL);
  5497. return (def);
  5498. } else
  5499. return (UNBOUNDED); /* encoding it with -1 might be another option */
  5500. }
  5501. cur = val;
  5502. while (IS_BLANK_CH(*cur))
  5503. cur++;
  5504. if (*cur == 0) {
  5505. xmlSchemaPSimpleTypeErr(ctxt,
  5506. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5507. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5508. NULL, (xmlNodePtr) attr, NULL, expected,
  5509. val, NULL, NULL, NULL);
  5510. return (def);
  5511. }
  5512. while ((*cur >= '0') && (*cur <= '9')) {
  5513. if (ret > INT_MAX / 10) {
  5514. ret = INT_MAX;
  5515. } else {
  5516. int digit = *cur - '0';
  5517. ret *= 10;
  5518. if (ret > INT_MAX - digit)
  5519. ret = INT_MAX;
  5520. else
  5521. ret += digit;
  5522. }
  5523. cur++;
  5524. }
  5525. while (IS_BLANK_CH(*cur))
  5526. cur++;
  5527. /*
  5528. * TODO: Restrict the maximal value to Integer.
  5529. */
  5530. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5531. xmlSchemaPSimpleTypeErr(ctxt,
  5532. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5533. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5534. NULL, (xmlNodePtr) attr, NULL, expected,
  5535. val, NULL, NULL, NULL);
  5536. return (def);
  5537. }
  5538. return (ret);
  5539. }
  5540. /**
  5541. * xmlGetMinOccurs:
  5542. * @ctxt: a schema validation context
  5543. * @node: a subtree containing XML Schema information
  5544. *
  5545. * Get the minOccurs property
  5546. *
  5547. * Returns the default if not found, or the value
  5548. */
  5549. static int
  5550. xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5551. int min, int max, int def, const char *expected)
  5552. {
  5553. const xmlChar *val, *cur;
  5554. int ret = 0;
  5555. xmlAttrPtr attr;
  5556. attr = xmlSchemaGetPropNode(node, "minOccurs");
  5557. if (attr == NULL)
  5558. return (def);
  5559. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5560. if (val == NULL)
  5561. return (def);
  5562. cur = val;
  5563. while (IS_BLANK_CH(*cur))
  5564. cur++;
  5565. if (*cur == 0) {
  5566. xmlSchemaPSimpleTypeErr(ctxt,
  5567. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5568. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5569. NULL, (xmlNodePtr) attr, NULL, expected,
  5570. val, NULL, NULL, NULL);
  5571. return (def);
  5572. }
  5573. while ((*cur >= '0') && (*cur <= '9')) {
  5574. if (ret > INT_MAX / 10) {
  5575. ret = INT_MAX;
  5576. } else {
  5577. int digit = *cur - '0';
  5578. ret *= 10;
  5579. if (ret > INT_MAX - digit)
  5580. ret = INT_MAX;
  5581. else
  5582. ret += digit;
  5583. }
  5584. cur++;
  5585. }
  5586. while (IS_BLANK_CH(*cur))
  5587. cur++;
  5588. /*
  5589. * TODO: Restrict the maximal value to Integer.
  5590. */
  5591. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5592. xmlSchemaPSimpleTypeErr(ctxt,
  5593. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5594. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5595. NULL, (xmlNodePtr) attr, NULL, expected,
  5596. val, NULL, NULL, NULL);
  5597. return (def);
  5598. }
  5599. return (ret);
  5600. }
  5601. /**
  5602. * xmlSchemaPGetBoolNodeValue:
  5603. * @ctxt: a schema validation context
  5604. * @ownerItem: the owner as a schema item
  5605. * @node: the node holding the value
  5606. *
  5607. * Converts a boolean string value into 1 or 0.
  5608. *
  5609. * Returns 0 or 1.
  5610. */
  5611. static int
  5612. xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
  5613. xmlSchemaBasicItemPtr ownerItem,
  5614. xmlNodePtr node)
  5615. {
  5616. xmlChar *value = NULL;
  5617. int res = 0;
  5618. value = xmlNodeGetContent(node);
  5619. /*
  5620. * 3.2.2.1 Lexical representation
  5621. * An instance of a datatype that is defined as `boolean`
  5622. * can have the following legal literals {true, false, 1, 0}.
  5623. */
  5624. if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
  5625. res = 1;
  5626. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
  5627. res = 0;
  5628. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
  5629. res = 1;
  5630. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
  5631. res = 0;
  5632. else {
  5633. xmlSchemaPSimpleTypeErr(ctxt,
  5634. XML_SCHEMAP_INVALID_BOOLEAN,
  5635. ownerItem, node,
  5636. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5637. NULL, BAD_CAST value,
  5638. NULL, NULL, NULL);
  5639. }
  5640. if (value != NULL)
  5641. xmlFree(value);
  5642. return (res);
  5643. }
  5644. /**
  5645. * xmlGetBooleanProp:
  5646. * @ctxt: a schema validation context
  5647. * @node: a subtree containing XML Schema information
  5648. * @name: the attribute name
  5649. * @def: the default value
  5650. *
  5651. * Evaluate if a boolean property is set
  5652. *
  5653. * Returns the default if not found, 0 if found to be false,
  5654. * 1 if found to be true
  5655. */
  5656. static int
  5657. xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
  5658. xmlNodePtr node,
  5659. const char *name, int def)
  5660. {
  5661. const xmlChar *val;
  5662. val = xmlSchemaGetProp(ctxt, node, name);
  5663. if (val == NULL)
  5664. return (def);
  5665. /*
  5666. * 3.2.2.1 Lexical representation
  5667. * An instance of a datatype that is defined as `boolean`
  5668. * can have the following legal literals {true, false, 1, 0}.
  5669. */
  5670. if (xmlStrEqual(val, BAD_CAST "true"))
  5671. def = 1;
  5672. else if (xmlStrEqual(val, BAD_CAST "false"))
  5673. def = 0;
  5674. else if (xmlStrEqual(val, BAD_CAST "1"))
  5675. def = 1;
  5676. else if (xmlStrEqual(val, BAD_CAST "0"))
  5677. def = 0;
  5678. else {
  5679. xmlSchemaPSimpleTypeErr(ctxt,
  5680. XML_SCHEMAP_INVALID_BOOLEAN,
  5681. NULL,
  5682. (xmlNodePtr) xmlSchemaGetPropNode(node, name),
  5683. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5684. NULL, val, NULL, NULL, NULL);
  5685. }
  5686. return (def);
  5687. }
  5688. /************************************************************************
  5689. * *
  5690. * Schema extraction from an Infoset *
  5691. * *
  5692. ************************************************************************/
  5693. static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
  5694. ctxt, xmlSchemaPtr schema,
  5695. xmlNodePtr node,
  5696. int topLevel);
  5697. static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
  5698. ctxt,
  5699. xmlSchemaPtr schema,
  5700. xmlNodePtr node,
  5701. int topLevel);
  5702. static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
  5703. ctxt,
  5704. xmlSchemaPtr schema,
  5705. xmlNodePtr node,
  5706. xmlSchemaTypeType parentType);
  5707. static xmlSchemaBasicItemPtr
  5708. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  5709. xmlSchemaPtr schema,
  5710. xmlNodePtr node,
  5711. xmlSchemaItemListPtr uses,
  5712. int parentType);
  5713. static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
  5714. xmlSchemaPtr schema,
  5715. xmlNodePtr node);
  5716. static xmlSchemaWildcardPtr
  5717. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  5718. xmlSchemaPtr schema, xmlNodePtr node);
  5719. /**
  5720. * xmlSchemaPValAttrNodeValue:
  5721. *
  5722. * @pctxt: a schema parser context
  5723. * @ownerItem: the schema object owner if existent
  5724. * @attr: the schema attribute node being validated
  5725. * @value: the value
  5726. * @type: the built-in type to be validated against
  5727. *
  5728. * Validates a value against the given built-in type.
  5729. * This one is intended to be used internally for validation
  5730. * of schema attribute values during parsing of the schema.
  5731. *
  5732. * Returns 0 if the value is valid, a positive error code
  5733. * number otherwise and -1 in case of an internal or API error.
  5734. */
  5735. static int
  5736. xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
  5737. xmlSchemaBasicItemPtr ownerItem,
  5738. xmlAttrPtr attr,
  5739. const xmlChar *value,
  5740. xmlSchemaTypePtr type)
  5741. {
  5742. int ret = 0;
  5743. /*
  5744. * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
  5745. * one is really meant to be used internally, so better not.
  5746. */
  5747. if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
  5748. return (-1);
  5749. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5750. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5751. "the given type is not a built-in type");
  5752. return (-1);
  5753. }
  5754. switch (type->builtInType) {
  5755. case XML_SCHEMAS_NCNAME:
  5756. case XML_SCHEMAS_QNAME:
  5757. case XML_SCHEMAS_ANYURI:
  5758. case XML_SCHEMAS_TOKEN:
  5759. case XML_SCHEMAS_LANGUAGE:
  5760. ret = xmlSchemaValPredefTypeNode(type, value, NULL,
  5761. (xmlNodePtr) attr);
  5762. break;
  5763. default: {
  5764. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5765. "validation using the given type is not supported while "
  5766. "parsing a schema");
  5767. return (-1);
  5768. }
  5769. }
  5770. /*
  5771. * TODO: Should we use the S4S error codes instead?
  5772. */
  5773. if (ret < 0) {
  5774. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5775. "failed to validate a schema attribute value");
  5776. return (-1);
  5777. } else if (ret > 0) {
  5778. if (WXS_IS_LIST(type))
  5779. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  5780. else
  5781. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  5782. xmlSchemaPSimpleTypeErr(pctxt,
  5783. ret, ownerItem, (xmlNodePtr) attr,
  5784. type, NULL, value, NULL, NULL, NULL);
  5785. }
  5786. return (ret);
  5787. }
  5788. /**
  5789. * xmlSchemaPValAttrNode:
  5790. *
  5791. * @ctxt: a schema parser context
  5792. * @ownerItem: the schema object owner if existent
  5793. * @attr: the schema attribute node being validated
  5794. * @type: the built-in type to be validated against
  5795. * @value: the resulting value if any
  5796. *
  5797. * Extracts and validates a value against the given built-in type.
  5798. * This one is intended to be used internally for validation
  5799. * of schema attribute values during parsing of the schema.
  5800. *
  5801. * Returns 0 if the value is valid, a positive error code
  5802. * number otherwise and -1 in case of an internal or API error.
  5803. */
  5804. static int
  5805. xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
  5806. xmlSchemaBasicItemPtr ownerItem,
  5807. xmlAttrPtr attr,
  5808. xmlSchemaTypePtr type,
  5809. const xmlChar **value)
  5810. {
  5811. const xmlChar *val;
  5812. if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
  5813. return (-1);
  5814. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5815. if (value != NULL)
  5816. *value = val;
  5817. return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
  5818. val, type));
  5819. }
  5820. /**
  5821. * xmlSchemaPValAttr:
  5822. *
  5823. * @ctxt: a schema parser context
  5824. * @node: the element node of the attribute
  5825. * @ownerItem: the schema object owner if existent
  5826. * @ownerElem: the owner element node
  5827. * @name: the name of the schema attribute node
  5828. * @type: the built-in type to be validated against
  5829. * @value: the resulting value if any
  5830. *
  5831. * Extracts and validates a value against the given built-in type.
  5832. * This one is intended to be used internally for validation
  5833. * of schema attribute values during parsing of the schema.
  5834. *
  5835. * Returns 0 if the value is valid, a positive error code
  5836. * number otherwise and -1 in case of an internal or API error.
  5837. */
  5838. static int
  5839. xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
  5840. xmlSchemaBasicItemPtr ownerItem,
  5841. xmlNodePtr ownerElem,
  5842. const char *name,
  5843. xmlSchemaTypePtr type,
  5844. const xmlChar **value)
  5845. {
  5846. xmlAttrPtr attr;
  5847. if ((ctxt == NULL) || (type == NULL)) {
  5848. if (value != NULL)
  5849. *value = NULL;
  5850. return (-1);
  5851. }
  5852. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5853. if (value != NULL)
  5854. *value = NULL;
  5855. xmlSchemaPErr(ctxt, ownerElem,
  5856. XML_SCHEMAP_INTERNAL,
  5857. "Internal error: xmlSchemaPValAttr, the given "
  5858. "type '%s' is not a built-in type.\n",
  5859. type->name, NULL);
  5860. return (-1);
  5861. }
  5862. attr = xmlSchemaGetPropNode(ownerElem, name);
  5863. if (attr == NULL) {
  5864. if (value != NULL)
  5865. *value = NULL;
  5866. return (0);
  5867. }
  5868. return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
  5869. type, value));
  5870. }
  5871. static int
  5872. xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
  5873. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  5874. xmlNodePtr node,
  5875. xmlAttrPtr attr,
  5876. const xmlChar *namespaceName)
  5877. {
  5878. /* TODO: Pointer comparison instead? */
  5879. if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
  5880. return (0);
  5881. if (xmlStrEqual(xmlSchemaNs, namespaceName))
  5882. return (0);
  5883. /*
  5884. * Check if the referenced namespace was <import>ed.
  5885. */
  5886. if (WXS_BUCKET(pctxt)->relations != NULL) {
  5887. xmlSchemaSchemaRelationPtr rel;
  5888. rel = WXS_BUCKET(pctxt)->relations;
  5889. do {
  5890. if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
  5891. xmlStrEqual(namespaceName, rel->importNamespace))
  5892. return (0);
  5893. rel = rel->next;
  5894. } while (rel != NULL);
  5895. }
  5896. /*
  5897. * No matching <import>ed namespace found.
  5898. */
  5899. {
  5900. xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
  5901. if (namespaceName == NULL)
  5902. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5903. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5904. "References from this schema to components in no "
  5905. "namespace are not allowed, since not indicated by an "
  5906. "import statement", NULL, NULL);
  5907. else
  5908. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5909. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5910. "References from this schema to components in the "
  5911. "namespace '%s' are not allowed, since not indicated by an "
  5912. "import statement", namespaceName, NULL);
  5913. }
  5914. return (XML_SCHEMAP_SRC_RESOLVE);
  5915. }
  5916. /**
  5917. * xmlSchemaParseLocalAttributes:
  5918. * @ctxt: a schema validation context
  5919. * @schema: the schema being built
  5920. * @node: a subtree containing XML Schema information
  5921. * @type: the hosting type where the attributes will be anchored
  5922. *
  5923. * Parses attribute uses and attribute declarations and
  5924. * attribute group references.
  5925. */
  5926. static int
  5927. xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5928. xmlNodePtr *child, xmlSchemaItemListPtr *list,
  5929. int parentType, int *hasRefs)
  5930. {
  5931. void *item;
  5932. while ((IS_SCHEMA((*child), "attribute")) ||
  5933. (IS_SCHEMA((*child), "attributeGroup"))) {
  5934. if (IS_SCHEMA((*child), "attribute")) {
  5935. item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
  5936. *list, parentType);
  5937. } else {
  5938. item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
  5939. if ((item != NULL) && (hasRefs != NULL))
  5940. *hasRefs = 1;
  5941. }
  5942. if (item != NULL) {
  5943. if (*list == NULL) {
  5944. /* TODO: Customize grow factor. */
  5945. *list = xmlSchemaItemListCreate();
  5946. if (*list == NULL)
  5947. return(-1);
  5948. }
  5949. if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
  5950. return(-1);
  5951. }
  5952. *child = (*child)->next;
  5953. }
  5954. return (0);
  5955. }
  5956. /**
  5957. * xmlSchemaParseAnnotation:
  5958. * @ctxt: a schema validation context
  5959. * @schema: the schema being built
  5960. * @node: a subtree containing XML Schema information
  5961. *
  5962. * parse a XML schema Attribute declaration
  5963. * *WARNING* this interface is highly subject to change
  5964. *
  5965. * Returns -1 in case of error, 0 if the declaration is improper and
  5966. * 1 in case of success.
  5967. */
  5968. static xmlSchemaAnnotPtr
  5969. xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
  5970. {
  5971. xmlSchemaAnnotPtr ret;
  5972. xmlNodePtr child = NULL;
  5973. xmlAttrPtr attr;
  5974. int barked = 0;
  5975. /*
  5976. * INFO: S4S completed.
  5977. */
  5978. /*
  5979. * id = ID
  5980. * {any attributes with non-schema namespace . . .}>
  5981. * Content: (appinfo | documentation)*
  5982. */
  5983. if ((ctxt == NULL) || (node == NULL))
  5984. return (NULL);
  5985. if (needed)
  5986. ret = xmlSchemaNewAnnot(ctxt, node);
  5987. else
  5988. ret = NULL;
  5989. attr = node->properties;
  5990. while (attr != NULL) {
  5991. if (((attr->ns == NULL) &&
  5992. (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
  5993. ((attr->ns != NULL) &&
  5994. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  5995. xmlSchemaPIllegalAttrErr(ctxt,
  5996. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  5997. }
  5998. attr = attr->next;
  5999. }
  6000. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6001. /*
  6002. * And now for the children...
  6003. */
  6004. child = node->children;
  6005. while (child != NULL) {
  6006. if (IS_SCHEMA(child, "appinfo")) {
  6007. /* TODO: make available the content of "appinfo". */
  6008. /*
  6009. * source = anyURI
  6010. * {any attributes with non-schema namespace . . .}>
  6011. * Content: ({any})*
  6012. */
  6013. attr = child->properties;
  6014. while (attr != NULL) {
  6015. if (((attr->ns == NULL) &&
  6016. (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
  6017. ((attr->ns != NULL) &&
  6018. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6019. xmlSchemaPIllegalAttrErr(ctxt,
  6020. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6021. }
  6022. attr = attr->next;
  6023. }
  6024. xmlSchemaPValAttr(ctxt, NULL, child, "source",
  6025. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  6026. child = child->next;
  6027. } else if (IS_SCHEMA(child, "documentation")) {
  6028. /* TODO: make available the content of "documentation". */
  6029. /*
  6030. * source = anyURI
  6031. * {any attributes with non-schema namespace . . .}>
  6032. * Content: ({any})*
  6033. */
  6034. attr = child->properties;
  6035. while (attr != NULL) {
  6036. if (attr->ns == NULL) {
  6037. if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
  6038. xmlSchemaPIllegalAttrErr(ctxt,
  6039. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6040. }
  6041. } else {
  6042. if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
  6043. (xmlStrEqual(attr->name, BAD_CAST "lang") &&
  6044. (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
  6045. xmlSchemaPIllegalAttrErr(ctxt,
  6046. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6047. }
  6048. }
  6049. attr = attr->next;
  6050. }
  6051. /*
  6052. * Attribute "xml:lang".
  6053. */
  6054. attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
  6055. if (attr != NULL)
  6056. xmlSchemaPValAttrNode(ctxt, NULL, attr,
  6057. xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
  6058. child = child->next;
  6059. } else {
  6060. if (!barked)
  6061. xmlSchemaPContentErr(ctxt,
  6062. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6063. NULL, node, child, NULL, "(appinfo | documentation)*");
  6064. barked = 1;
  6065. child = child->next;
  6066. }
  6067. }
  6068. return (ret);
  6069. }
  6070. /**
  6071. * xmlSchemaParseFacet:
  6072. * @ctxt: a schema validation context
  6073. * @schema: the schema being built
  6074. * @node: a subtree containing XML Schema information
  6075. *
  6076. * parse a XML schema Facet declaration
  6077. * *WARNING* this interface is highly subject to change
  6078. *
  6079. * Returns the new type structure or NULL in case of error
  6080. */
  6081. static xmlSchemaFacetPtr
  6082. xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6083. xmlNodePtr node)
  6084. {
  6085. xmlSchemaFacetPtr facet;
  6086. xmlNodePtr child = NULL;
  6087. const xmlChar *value;
  6088. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6089. return (NULL);
  6090. facet = xmlSchemaNewFacet();
  6091. if (facet == NULL) {
  6092. xmlSchemaPErrMemory(ctxt, "allocating facet", node);
  6093. return (NULL);
  6094. }
  6095. facet->node = node;
  6096. value = xmlSchemaGetProp(ctxt, node, "value");
  6097. if (value == NULL) {
  6098. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
  6099. "Facet %s has no value\n", node->name, NULL);
  6100. xmlSchemaFreeFacet(facet);
  6101. return (NULL);
  6102. }
  6103. if (IS_SCHEMA(node, "minInclusive")) {
  6104. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  6105. } else if (IS_SCHEMA(node, "minExclusive")) {
  6106. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  6107. } else if (IS_SCHEMA(node, "maxInclusive")) {
  6108. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  6109. } else if (IS_SCHEMA(node, "maxExclusive")) {
  6110. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  6111. } else if (IS_SCHEMA(node, "totalDigits")) {
  6112. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  6113. } else if (IS_SCHEMA(node, "fractionDigits")) {
  6114. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  6115. } else if (IS_SCHEMA(node, "pattern")) {
  6116. facet->type = XML_SCHEMA_FACET_PATTERN;
  6117. } else if (IS_SCHEMA(node, "enumeration")) {
  6118. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  6119. } else if (IS_SCHEMA(node, "whiteSpace")) {
  6120. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  6121. } else if (IS_SCHEMA(node, "length")) {
  6122. facet->type = XML_SCHEMA_FACET_LENGTH;
  6123. } else if (IS_SCHEMA(node, "maxLength")) {
  6124. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  6125. } else if (IS_SCHEMA(node, "minLength")) {
  6126. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  6127. } else {
  6128. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
  6129. "Unknown facet type %s\n", node->name, NULL);
  6130. xmlSchemaFreeFacet(facet);
  6131. return (NULL);
  6132. }
  6133. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6134. facet->value = value;
  6135. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  6136. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  6137. const xmlChar *fixed;
  6138. fixed = xmlSchemaGetProp(ctxt, node, "fixed");
  6139. if (fixed != NULL) {
  6140. if (xmlStrEqual(fixed, BAD_CAST "true"))
  6141. facet->fixed = 1;
  6142. }
  6143. }
  6144. child = node->children;
  6145. if (IS_SCHEMA(child, "annotation")) {
  6146. facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6147. child = child->next;
  6148. }
  6149. if (child != NULL) {
  6150. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
  6151. "Facet %s has unexpected child content\n",
  6152. node->name, NULL);
  6153. }
  6154. return (facet);
  6155. }
  6156. /**
  6157. * xmlSchemaParseWildcardNs:
  6158. * @ctxt: a schema parser context
  6159. * @wildc: the wildcard, already created
  6160. * @node: a subtree containing XML Schema information
  6161. *
  6162. * Parses the attribute "processContents" and "namespace"
  6163. * of a xsd:anyAttribute and xsd:any.
  6164. * *WARNING* this interface is highly subject to change
  6165. *
  6166. * Returns 0 if everything goes fine, a positive error code
  6167. * if something is not valid and -1 if an internal error occurs.
  6168. */
  6169. static int
  6170. xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
  6171. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  6172. xmlSchemaWildcardPtr wildc,
  6173. xmlNodePtr node)
  6174. {
  6175. const xmlChar *pc, *ns, *dictnsItem;
  6176. int ret = 0;
  6177. xmlChar *nsItem;
  6178. xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
  6179. xmlAttrPtr attr;
  6180. pc = xmlSchemaGetProp(ctxt, node, "processContents");
  6181. if ((pc == NULL)
  6182. || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
  6183. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6184. } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
  6185. wildc->processContents = XML_SCHEMAS_ANY_SKIP;
  6186. } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
  6187. wildc->processContents = XML_SCHEMAS_ANY_LAX;
  6188. } else {
  6189. xmlSchemaPSimpleTypeErr(ctxt,
  6190. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6191. NULL, node,
  6192. NULL, "(strict | skip | lax)", pc,
  6193. NULL, NULL, NULL);
  6194. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6195. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  6196. }
  6197. /*
  6198. * Build the namespace constraints.
  6199. */
  6200. attr = xmlSchemaGetPropNode(node, "namespace");
  6201. ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  6202. if (ns == NULL)
  6203. return (-1);
  6204. if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
  6205. wildc->any = 1;
  6206. else if (xmlStrEqual(ns, BAD_CAST "##other")) {
  6207. wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  6208. if (wildc->negNsSet == NULL) {
  6209. return (-1);
  6210. }
  6211. wildc->negNsSet->value = ctxt->targetNamespace;
  6212. } else {
  6213. const xmlChar *end, *cur;
  6214. cur = ns;
  6215. do {
  6216. while (IS_BLANK_CH(*cur))
  6217. cur++;
  6218. end = cur;
  6219. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  6220. end++;
  6221. if (end == cur)
  6222. break;
  6223. nsItem = xmlStrndup(cur, end - cur);
  6224. if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
  6225. (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
  6226. xmlSchemaPSimpleTypeErr(ctxt,
  6227. XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
  6228. NULL, (xmlNodePtr) attr,
  6229. NULL,
  6230. "((##any | ##other) | List of (xs:anyURI | "
  6231. "(##targetNamespace | ##local)))",
  6232. nsItem, NULL, NULL, NULL);
  6233. ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
  6234. } else {
  6235. if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
  6236. dictnsItem = ctxt->targetNamespace;
  6237. } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
  6238. dictnsItem = NULL;
  6239. } else {
  6240. /*
  6241. * Validate the item (anyURI).
  6242. */
  6243. xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
  6244. nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
  6245. dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
  6246. }
  6247. /*
  6248. * Avoid duplicate namespaces.
  6249. */
  6250. tmp = wildc->nsSet;
  6251. while (tmp != NULL) {
  6252. if (dictnsItem == tmp->value)
  6253. break;
  6254. tmp = tmp->next;
  6255. }
  6256. if (tmp == NULL) {
  6257. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  6258. if (tmp == NULL) {
  6259. xmlFree(nsItem);
  6260. return (-1);
  6261. }
  6262. tmp->value = dictnsItem;
  6263. tmp->next = NULL;
  6264. if (wildc->nsSet == NULL)
  6265. wildc->nsSet = tmp;
  6266. else if (lastNs != NULL)
  6267. lastNs->next = tmp;
  6268. lastNs = tmp;
  6269. }
  6270. }
  6271. xmlFree(nsItem);
  6272. cur = end;
  6273. } while (*cur != 0);
  6274. }
  6275. return (ret);
  6276. }
  6277. static int
  6278. xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
  6279. xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
  6280. xmlNodePtr node,
  6281. int minOccurs,
  6282. int maxOccurs) {
  6283. if ((maxOccurs == 0) && ( minOccurs == 0))
  6284. return (0);
  6285. if (maxOccurs != UNBOUNDED) {
  6286. /*
  6287. * TODO: Maybe we should better not create the particle,
  6288. * if min/max is invalid, since it could confuse the build of the
  6289. * content model.
  6290. */
  6291. /*
  6292. * 3.9.6 Schema Component Constraint: Particle Correct
  6293. *
  6294. */
  6295. if (maxOccurs < 1) {
  6296. /*
  6297. * 2.2 {max occurs} must be greater than or equal to 1.
  6298. */
  6299. xmlSchemaPCustomAttrErr(ctxt,
  6300. XML_SCHEMAP_P_PROPS_CORRECT_2_2,
  6301. NULL, NULL,
  6302. xmlSchemaGetPropNode(node, "maxOccurs"),
  6303. "The value must be greater than or equal to 1");
  6304. return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
  6305. } else if (minOccurs > maxOccurs) {
  6306. /*
  6307. * 2.1 {min occurs} must not be greater than {max occurs}.
  6308. */
  6309. xmlSchemaPCustomAttrErr(ctxt,
  6310. XML_SCHEMAP_P_PROPS_CORRECT_2_1,
  6311. NULL, NULL,
  6312. xmlSchemaGetPropNode(node, "minOccurs"),
  6313. "The value must not be greater than the value of 'maxOccurs'");
  6314. return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
  6315. }
  6316. }
  6317. return (0);
  6318. }
  6319. /**
  6320. * xmlSchemaParseAny:
  6321. * @ctxt: a schema validation context
  6322. * @schema: the schema being built
  6323. * @node: a subtree containing XML Schema information
  6324. *
  6325. * Parsea a XML schema <any> element. A particle and wildcard
  6326. * will be created (except if minOccurs==maxOccurs==0, in this case
  6327. * nothing will be created).
  6328. * *WARNING* this interface is highly subject to change
  6329. *
  6330. * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
  6331. */
  6332. static xmlSchemaParticlePtr
  6333. xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6334. xmlNodePtr node)
  6335. {
  6336. xmlSchemaParticlePtr particle;
  6337. xmlNodePtr child = NULL;
  6338. xmlSchemaWildcardPtr wild;
  6339. int min, max;
  6340. xmlAttrPtr attr;
  6341. xmlSchemaAnnotPtr annot = NULL;
  6342. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6343. return (NULL);
  6344. /*
  6345. * Check for illegal attributes.
  6346. */
  6347. attr = node->properties;
  6348. while (attr != NULL) {
  6349. if (attr->ns == NULL) {
  6350. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6351. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  6352. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  6353. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6354. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6355. xmlSchemaPIllegalAttrErr(ctxt,
  6356. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6357. }
  6358. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6359. xmlSchemaPIllegalAttrErr(ctxt,
  6360. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6361. }
  6362. attr = attr->next;
  6363. }
  6364. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6365. /*
  6366. * minOccurs/maxOccurs.
  6367. */
  6368. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  6369. "(xs:nonNegativeInteger | unbounded)");
  6370. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
  6371. "xs:nonNegativeInteger");
  6372. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  6373. /*
  6374. * Create & parse the wildcard.
  6375. */
  6376. wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
  6377. if (wild == NULL)
  6378. return (NULL);
  6379. xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
  6380. /*
  6381. * And now for the children...
  6382. */
  6383. child = node->children;
  6384. if (IS_SCHEMA(child, "annotation")) {
  6385. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6386. child = child->next;
  6387. }
  6388. if (child != NULL) {
  6389. xmlSchemaPContentErr(ctxt,
  6390. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6391. NULL, node, child,
  6392. NULL, "(annotation?)");
  6393. }
  6394. /*
  6395. * No component if minOccurs==maxOccurs==0.
  6396. */
  6397. if ((min == 0) && (max == 0)) {
  6398. /* Don't free the wildcard, since it's already on the list. */
  6399. return (NULL);
  6400. }
  6401. /*
  6402. * Create the particle.
  6403. */
  6404. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  6405. if (particle == NULL)
  6406. return (NULL);
  6407. particle->annot = annot;
  6408. particle->children = (xmlSchemaTreeItemPtr) wild;
  6409. return (particle);
  6410. }
  6411. /**
  6412. * xmlSchemaParseNotation:
  6413. * @ctxt: a schema validation context
  6414. * @schema: the schema being built
  6415. * @node: a subtree containing XML Schema information
  6416. *
  6417. * parse a XML schema Notation declaration
  6418. *
  6419. * Returns the new structure or NULL in case of error
  6420. */
  6421. static xmlSchemaNotationPtr
  6422. xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6423. xmlNodePtr node)
  6424. {
  6425. const xmlChar *name;
  6426. xmlSchemaNotationPtr ret;
  6427. xmlNodePtr child = NULL;
  6428. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6429. return (NULL);
  6430. name = xmlSchemaGetProp(ctxt, node, "name");
  6431. if (name == NULL) {
  6432. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
  6433. "Notation has no name\n", NULL, NULL);
  6434. return (NULL);
  6435. }
  6436. ret = xmlSchemaAddNotation(ctxt, schema, name,
  6437. ctxt->targetNamespace, node);
  6438. if (ret == NULL)
  6439. return (NULL);
  6440. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6441. child = node->children;
  6442. if (IS_SCHEMA(child, "annotation")) {
  6443. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6444. child = child->next;
  6445. }
  6446. if (child != NULL) {
  6447. xmlSchemaPContentErr(ctxt,
  6448. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6449. NULL, node, child,
  6450. NULL, "(annotation?)");
  6451. }
  6452. return (ret);
  6453. }
  6454. /**
  6455. * xmlSchemaParseAnyAttribute:
  6456. * @ctxt: a schema validation context
  6457. * @schema: the schema being built
  6458. * @node: a subtree containing XML Schema information
  6459. *
  6460. * parse a XML schema AnyAttribute declaration
  6461. * *WARNING* this interface is highly subject to change
  6462. *
  6463. * Returns a wildcard or NULL.
  6464. */
  6465. static xmlSchemaWildcardPtr
  6466. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  6467. xmlSchemaPtr schema, xmlNodePtr node)
  6468. {
  6469. xmlSchemaWildcardPtr ret;
  6470. xmlNodePtr child = NULL;
  6471. xmlAttrPtr attr;
  6472. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6473. return (NULL);
  6474. ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  6475. node);
  6476. if (ret == NULL) {
  6477. return (NULL);
  6478. }
  6479. /*
  6480. * Check for illegal attributes.
  6481. */
  6482. attr = node->properties;
  6483. while (attr != NULL) {
  6484. if (attr->ns == NULL) {
  6485. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6486. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6487. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6488. xmlSchemaPIllegalAttrErr(ctxt,
  6489. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6490. }
  6491. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6492. xmlSchemaPIllegalAttrErr(ctxt,
  6493. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6494. }
  6495. attr = attr->next;
  6496. }
  6497. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6498. /*
  6499. * Parse the namespace list.
  6500. */
  6501. if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
  6502. return (NULL);
  6503. /*
  6504. * And now for the children...
  6505. */
  6506. child = node->children;
  6507. if (IS_SCHEMA(child, "annotation")) {
  6508. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6509. child = child->next;
  6510. }
  6511. if (child != NULL) {
  6512. xmlSchemaPContentErr(ctxt,
  6513. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6514. NULL, node, child,
  6515. NULL, "(annotation?)");
  6516. }
  6517. return (ret);
  6518. }
  6519. /**
  6520. * xmlSchemaParseAttribute:
  6521. * @ctxt: a schema validation context
  6522. * @schema: the schema being built
  6523. * @node: a subtree containing XML Schema information
  6524. *
  6525. * parse a XML schema Attribute declaration
  6526. * *WARNING* this interface is highly subject to change
  6527. *
  6528. * Returns the attribute declaration.
  6529. */
  6530. static xmlSchemaBasicItemPtr
  6531. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6532. xmlSchemaPtr schema,
  6533. xmlNodePtr node,
  6534. xmlSchemaItemListPtr uses,
  6535. int parentType)
  6536. {
  6537. const xmlChar *attrValue, *name = NULL, *ns = NULL;
  6538. xmlSchemaAttributeUsePtr use = NULL;
  6539. xmlNodePtr child = NULL;
  6540. xmlAttrPtr attr;
  6541. const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
  6542. int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6543. int nberrors, hasForm = 0, defValueType = 0;
  6544. #define WXS_ATTR_DEF_VAL_DEFAULT 1
  6545. #define WXS_ATTR_DEF_VAL_FIXED 2
  6546. /*
  6547. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6548. */
  6549. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6550. return (NULL);
  6551. attr = xmlSchemaGetPropNode(node, "ref");
  6552. if (attr != NULL) {
  6553. if (xmlSchemaPValAttrNodeQName(pctxt, schema,
  6554. NULL, attr, &tmpNs, &tmpName) != 0) {
  6555. return (NULL);
  6556. }
  6557. if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
  6558. return(NULL);
  6559. isRef = 1;
  6560. }
  6561. nberrors = pctxt->nberrors;
  6562. /*
  6563. * Check for illegal attributes.
  6564. */
  6565. attr = node->properties;
  6566. while (attr != NULL) {
  6567. if (attr->ns == NULL) {
  6568. if (isRef) {
  6569. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6570. xmlSchemaPValAttrNodeID(pctxt, attr);
  6571. goto attr_next;
  6572. } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
  6573. goto attr_next;
  6574. }
  6575. } else {
  6576. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  6577. goto attr_next;
  6578. } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6579. xmlSchemaPValAttrNodeID(pctxt, attr);
  6580. goto attr_next;
  6581. } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
  6582. xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
  6583. attr, &tmpNs, &tmpName);
  6584. goto attr_next;
  6585. } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
  6586. /*
  6587. * Evaluate the target namespace
  6588. */
  6589. hasForm = 1;
  6590. attrValue = xmlSchemaGetNodeContent(pctxt,
  6591. (xmlNodePtr) attr);
  6592. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  6593. ns = pctxt->targetNamespace;
  6594. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
  6595. {
  6596. xmlSchemaPSimpleTypeErr(pctxt,
  6597. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6598. NULL, (xmlNodePtr) attr,
  6599. NULL, "(qualified | unqualified)",
  6600. attrValue, NULL, NULL, NULL);
  6601. }
  6602. goto attr_next;
  6603. }
  6604. }
  6605. if (xmlStrEqual(attr->name, BAD_CAST "use")) {
  6606. attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6607. /* TODO: Maybe we need to normalize the value beforehand. */
  6608. if (xmlStrEqual(attrValue, BAD_CAST "optional"))
  6609. occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6610. else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
  6611. occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
  6612. else if (xmlStrEqual(attrValue, BAD_CAST "required"))
  6613. occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
  6614. else {
  6615. xmlSchemaPSimpleTypeErr(pctxt,
  6616. XML_SCHEMAP_INVALID_ATTR_USE,
  6617. NULL, (xmlNodePtr) attr,
  6618. NULL, "(optional | prohibited | required)",
  6619. attrValue, NULL, NULL, NULL);
  6620. }
  6621. goto attr_next;
  6622. } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
  6623. /*
  6624. * 3.2.3 : 1
  6625. * default and fixed must not both be present.
  6626. */
  6627. if (defValue) {
  6628. xmlSchemaPMutualExclAttrErr(pctxt,
  6629. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6630. NULL, attr, "default", "fixed");
  6631. } else {
  6632. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6633. defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
  6634. }
  6635. goto attr_next;
  6636. } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
  6637. /*
  6638. * 3.2.3 : 1
  6639. * default and fixed must not both be present.
  6640. */
  6641. if (defValue) {
  6642. xmlSchemaPMutualExclAttrErr(pctxt,
  6643. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6644. NULL, attr, "default", "fixed");
  6645. } else {
  6646. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6647. defValueType = WXS_ATTR_DEF_VAL_FIXED;
  6648. }
  6649. goto attr_next;
  6650. }
  6651. } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
  6652. goto attr_next;
  6653. xmlSchemaPIllegalAttrErr(pctxt,
  6654. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6655. attr_next:
  6656. attr = attr->next;
  6657. }
  6658. /*
  6659. * 3.2.3 : 2
  6660. * If default and use are both present, use must have
  6661. * the actual value optional.
  6662. */
  6663. if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
  6664. (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
  6665. xmlSchemaPSimpleTypeErr(pctxt,
  6666. XML_SCHEMAP_SRC_ATTRIBUTE_2,
  6667. NULL, node, NULL,
  6668. "(optional | prohibited | required)", NULL,
  6669. "The value of the attribute 'use' must be 'optional' "
  6670. "if the attribute 'default' is present",
  6671. NULL, NULL);
  6672. }
  6673. /*
  6674. * We want correct attributes.
  6675. */
  6676. if (nberrors != pctxt->nberrors)
  6677. return(NULL);
  6678. if (! isRef) {
  6679. xmlSchemaAttributePtr attrDecl;
  6680. /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
  6681. if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
  6682. ns = pctxt->targetNamespace;
  6683. /*
  6684. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6685. * TODO: Move this to the component layer.
  6686. */
  6687. if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
  6688. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6689. XML_SCHEMAP_NO_XSI,
  6690. node, NULL,
  6691. "The target namespace must not match '%s'",
  6692. xmlSchemaInstanceNs, NULL);
  6693. }
  6694. attr = xmlSchemaGetPropNode(node, "name");
  6695. if (attr == NULL) {
  6696. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6697. NULL, node, "name", NULL);
  6698. return (NULL);
  6699. }
  6700. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6701. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  6702. return (NULL);
  6703. }
  6704. /*
  6705. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6706. * TODO: Move this to the component layer.
  6707. */
  6708. if (xmlStrEqual(name, BAD_CAST "xmlns")) {
  6709. xmlSchemaPSimpleTypeErr(pctxt,
  6710. XML_SCHEMAP_NO_XMLNS,
  6711. NULL, (xmlNodePtr) attr,
  6712. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6713. "The value of the attribute must not match 'xmlns'",
  6714. NULL, NULL);
  6715. return (NULL);
  6716. }
  6717. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
  6718. goto check_children;
  6719. /*
  6720. * Create the attribute use component.
  6721. */
  6722. use = xmlSchemaAddAttributeUse(pctxt, node);
  6723. if (use == NULL)
  6724. return(NULL);
  6725. use->occurs = occurs;
  6726. /*
  6727. * Create the attribute declaration.
  6728. */
  6729. attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
  6730. if (attrDecl == NULL)
  6731. return (NULL);
  6732. if (tmpName != NULL) {
  6733. attrDecl->typeName = tmpName;
  6734. attrDecl->typeNs = tmpNs;
  6735. }
  6736. use->attrDecl = attrDecl;
  6737. /*
  6738. * Value constraint.
  6739. */
  6740. if (defValue != NULL) {
  6741. attrDecl->defValue = defValue;
  6742. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6743. attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
  6744. }
  6745. } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6746. xmlSchemaQNameRefPtr ref;
  6747. /*
  6748. * Create the attribute use component.
  6749. */
  6750. use = xmlSchemaAddAttributeUse(pctxt, node);
  6751. if (use == NULL)
  6752. return(NULL);
  6753. /*
  6754. * We need to resolve the reference at later stage.
  6755. */
  6756. WXS_ADD_PENDING(pctxt, use);
  6757. use->occurs = occurs;
  6758. /*
  6759. * Create a QName reference to the attribute declaration.
  6760. */
  6761. ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
  6762. tmpName, tmpNs);
  6763. if (ref == NULL)
  6764. return(NULL);
  6765. /*
  6766. * Assign the reference. This will be substituted for the
  6767. * referenced attribute declaration when the QName is resolved.
  6768. */
  6769. use->attrDecl = WXS_ATTR_CAST ref;
  6770. /*
  6771. * Value constraint.
  6772. */
  6773. if (defValue != NULL)
  6774. use->defValue = defValue;
  6775. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6776. use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
  6777. }
  6778. check_children:
  6779. /*
  6780. * And now for the children...
  6781. */
  6782. child = node->children;
  6783. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6784. xmlSchemaAttributeUseProhibPtr prohib;
  6785. if (IS_SCHEMA(child, "annotation")) {
  6786. xmlSchemaParseAnnotation(pctxt, child, 0);
  6787. child = child->next;
  6788. }
  6789. if (child != NULL) {
  6790. xmlSchemaPContentErr(pctxt,
  6791. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6792. NULL, node, child, NULL,
  6793. "(annotation?)");
  6794. }
  6795. /*
  6796. * Check for pointlessness of attribute prohibitions.
  6797. */
  6798. if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
  6799. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6800. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6801. node, NULL,
  6802. "Skipping attribute use prohibition, since it is "
  6803. "pointless inside an <attributeGroup>",
  6804. NULL, NULL, NULL);
  6805. return(NULL);
  6806. } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
  6807. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6808. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6809. node, NULL,
  6810. "Skipping attribute use prohibition, since it is "
  6811. "pointless when extending a type",
  6812. NULL, NULL, NULL);
  6813. return(NULL);
  6814. }
  6815. if (! isRef) {
  6816. tmpName = name;
  6817. tmpNs = ns;
  6818. }
  6819. /*
  6820. * Check for duplicate attribute prohibitions.
  6821. */
  6822. if (uses) {
  6823. int i;
  6824. for (i = 0; i < uses->nbItems; i++) {
  6825. use = uses->items[i];
  6826. if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
  6827. (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
  6828. (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
  6829. {
  6830. xmlChar *str = NULL;
  6831. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6832. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6833. node, NULL,
  6834. "Skipping duplicate attribute use prohibition '%s'",
  6835. xmlSchemaFormatQName(&str, tmpNs, tmpName),
  6836. NULL, NULL);
  6837. FREE_AND_NULL(str)
  6838. return(NULL);
  6839. }
  6840. }
  6841. }
  6842. /*
  6843. * Create the attribute prohibition helper component.
  6844. */
  6845. prohib = xmlSchemaAddAttributeUseProhib(pctxt);
  6846. if (prohib == NULL)
  6847. return(NULL);
  6848. prohib->node = node;
  6849. prohib->name = tmpName;
  6850. prohib->targetNamespace = tmpNs;
  6851. if (isRef) {
  6852. /*
  6853. * We need at least to resolve to the attribute declaration.
  6854. */
  6855. WXS_ADD_PENDING(pctxt, prohib);
  6856. }
  6857. return(WXS_BASIC_CAST prohib);
  6858. } else {
  6859. if (IS_SCHEMA(child, "annotation")) {
  6860. /*
  6861. * TODO: Should this go into the attr decl?
  6862. */
  6863. use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  6864. child = child->next;
  6865. }
  6866. if (isRef) {
  6867. if (child != NULL) {
  6868. if (IS_SCHEMA(child, "simpleType"))
  6869. /*
  6870. * 3.2.3 : 3.2
  6871. * If ref is present, then all of <simpleType>,
  6872. * form and type must be absent.
  6873. */
  6874. xmlSchemaPContentErr(pctxt,
  6875. XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
  6876. NULL, node, child, NULL,
  6877. "(annotation?)");
  6878. else
  6879. xmlSchemaPContentErr(pctxt,
  6880. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6881. NULL, node, child, NULL,
  6882. "(annotation?)");
  6883. }
  6884. } else {
  6885. if (IS_SCHEMA(child, "simpleType")) {
  6886. if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
  6887. /*
  6888. * 3.2.3 : 4
  6889. * type and <simpleType> must not both be present.
  6890. */
  6891. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  6892. NULL, node, child,
  6893. "The attribute 'type' and the <simpleType> child "
  6894. "are mutually exclusive", NULL);
  6895. } else
  6896. WXS_ATTRUSE_TYPEDEF(use) =
  6897. xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  6898. child = child->next;
  6899. }
  6900. if (child != NULL)
  6901. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6902. NULL, node, child, NULL,
  6903. "(annotation?, simpleType?)");
  6904. }
  6905. }
  6906. return (WXS_BASIC_CAST use);
  6907. }
  6908. static xmlSchemaAttributePtr
  6909. xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6910. xmlSchemaPtr schema,
  6911. xmlNodePtr node)
  6912. {
  6913. const xmlChar *attrValue;
  6914. xmlSchemaAttributePtr ret;
  6915. xmlNodePtr child = NULL;
  6916. xmlAttrPtr attr;
  6917. /*
  6918. * Note that the w3c spec assumes the schema to be validated with schema
  6919. * for schemas beforehand.
  6920. *
  6921. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6922. */
  6923. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6924. return (NULL);
  6925. /*
  6926. * 3.2.3 : 3.1
  6927. * One of ref or name must be present, but not both
  6928. */
  6929. attr = xmlSchemaGetPropNode(node, "name");
  6930. if (attr == NULL) {
  6931. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6932. NULL, node, "name", NULL);
  6933. return (NULL);
  6934. }
  6935. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6936. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
  6937. return (NULL);
  6938. }
  6939. /*
  6940. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6941. * TODO: Move this to the component layer.
  6942. */
  6943. if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
  6944. xmlSchemaPSimpleTypeErr(pctxt,
  6945. XML_SCHEMAP_NO_XMLNS,
  6946. NULL, (xmlNodePtr) attr,
  6947. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6948. "The value of the attribute must not match 'xmlns'",
  6949. NULL, NULL);
  6950. return (NULL);
  6951. }
  6952. /*
  6953. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6954. * TODO: Move this to the component layer.
  6955. * Or better leave it here and add it to the component layer
  6956. * if we have a schema construction API.
  6957. */
  6958. if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
  6959. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6960. XML_SCHEMAP_NO_XSI, node, NULL,
  6961. "The target namespace must not match '%s'",
  6962. xmlSchemaInstanceNs, NULL);
  6963. }
  6964. ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
  6965. pctxt->targetNamespace, node, 1);
  6966. if (ret == NULL)
  6967. return (NULL);
  6968. ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
  6969. /*
  6970. * Check for illegal attributes.
  6971. */
  6972. attr = node->properties;
  6973. while (attr != NULL) {
  6974. if (attr->ns == NULL) {
  6975. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6976. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  6977. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  6978. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  6979. (!xmlStrEqual(attr->name, BAD_CAST "type")))
  6980. {
  6981. xmlSchemaPIllegalAttrErr(pctxt,
  6982. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6983. }
  6984. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6985. xmlSchemaPIllegalAttrErr(pctxt,
  6986. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6987. }
  6988. attr = attr->next;
  6989. }
  6990. xmlSchemaPValAttrQName(pctxt, schema, NULL,
  6991. node, "type", &ret->typeNs, &ret->typeName);
  6992. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  6993. /*
  6994. * Attribute "fixed".
  6995. */
  6996. ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
  6997. if (ret->defValue != NULL)
  6998. ret->flags |= XML_SCHEMAS_ATTR_FIXED;
  6999. /*
  7000. * Attribute "default".
  7001. */
  7002. attr = xmlSchemaGetPropNode(node, "default");
  7003. if (attr != NULL) {
  7004. /*
  7005. * 3.2.3 : 1
  7006. * default and fixed must not both be present.
  7007. */
  7008. if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
  7009. xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
  7010. WXS_BASIC_CAST ret, attr, "default", "fixed");
  7011. } else
  7012. ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  7013. }
  7014. /*
  7015. * And now for the children...
  7016. */
  7017. child = node->children;
  7018. if (IS_SCHEMA(child, "annotation")) {
  7019. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7020. child = child->next;
  7021. }
  7022. if (IS_SCHEMA(child, "simpleType")) {
  7023. if (ret->typeName != NULL) {
  7024. /*
  7025. * 3.2.3 : 4
  7026. * type and <simpleType> must not both be present.
  7027. */
  7028. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7029. NULL, node, child,
  7030. "The attribute 'type' and the <simpleType> child "
  7031. "are mutually exclusive", NULL);
  7032. } else
  7033. ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7034. child = child->next;
  7035. }
  7036. if (child != NULL)
  7037. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7038. NULL, node, child, NULL,
  7039. "(annotation?, simpleType?)");
  7040. return (ret);
  7041. }
  7042. /**
  7043. * xmlSchemaParseAttributeGroupRef:
  7044. * @ctxt: a schema validation context
  7045. * @schema: the schema being built
  7046. * @node: a subtree containing XML Schema information
  7047. *
  7048. * Parse an attribute group definition reference.
  7049. * Note that a reference to an attribute group does not
  7050. * correspond to any component at all.
  7051. * *WARNING* this interface is highly subject to change
  7052. *
  7053. * Returns the attribute group or NULL in case of error.
  7054. */
  7055. static xmlSchemaQNameRefPtr
  7056. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  7057. xmlSchemaPtr schema,
  7058. xmlNodePtr node)
  7059. {
  7060. xmlSchemaQNameRefPtr ret;
  7061. xmlNodePtr child = NULL;
  7062. xmlAttrPtr attr;
  7063. const xmlChar *refNs = NULL, *ref = NULL;
  7064. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7065. return (NULL);
  7066. attr = xmlSchemaGetPropNode(node, "ref");
  7067. if (attr == NULL) {
  7068. xmlSchemaPMissingAttrErr(pctxt,
  7069. XML_SCHEMAP_S4S_ATTR_MISSING,
  7070. NULL, node, "ref", NULL);
  7071. return (NULL);
  7072. }
  7073. xmlSchemaPValAttrNodeQName(pctxt, schema,
  7074. NULL, attr, &refNs, &ref);
  7075. if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
  7076. return(NULL);
  7077. /*
  7078. * Check for illegal attributes.
  7079. */
  7080. attr = node->properties;
  7081. while (attr != NULL) {
  7082. if (attr->ns == NULL) {
  7083. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  7084. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7085. {
  7086. xmlSchemaPIllegalAttrErr(pctxt,
  7087. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7088. }
  7089. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7090. xmlSchemaPIllegalAttrErr(pctxt,
  7091. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7092. }
  7093. attr = attr->next;
  7094. }
  7095. /* Attribute ID */
  7096. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7097. /*
  7098. * And now for the children...
  7099. */
  7100. child = node->children;
  7101. if (IS_SCHEMA(child, "annotation")) {
  7102. /*
  7103. * TODO: We do not have a place to store the annotation, do we?
  7104. */
  7105. xmlSchemaParseAnnotation(pctxt, child, 0);
  7106. child = child->next;
  7107. }
  7108. if (child != NULL) {
  7109. xmlSchemaPContentErr(pctxt,
  7110. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7111. NULL, node, child, NULL,
  7112. "(annotation?)");
  7113. }
  7114. /*
  7115. * Handle attribute group redefinitions.
  7116. */
  7117. if (pctxt->isRedefine && pctxt->redef &&
  7118. (pctxt->redef->item->type ==
  7119. XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  7120. (ref == pctxt->redef->refName) &&
  7121. (refNs == pctxt->redef->refTargetNs))
  7122. {
  7123. /*
  7124. * SPEC src-redefine:
  7125. * (7.1) "If it has an <attributeGroup> among its contents
  7126. * the `actual value` of whose ref [attribute] is the same
  7127. * as the `actual value` of its own name attribute plus
  7128. * target namespace, then it must have exactly one such group."
  7129. */
  7130. if (pctxt->redefCounter != 0) {
  7131. xmlChar *str = NULL;
  7132. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7133. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  7134. "The redefining attribute group definition "
  7135. "'%s' must not contain more than one "
  7136. "reference to the redefined definition",
  7137. xmlSchemaFormatQName(&str, refNs, ref), NULL);
  7138. FREE_AND_NULL(str);
  7139. return(NULL);
  7140. }
  7141. pctxt->redefCounter++;
  7142. /*
  7143. * URGENT TODO: How to ensure that the reference will not be
  7144. * handled by the normal component resolution mechanism?
  7145. */
  7146. ret = xmlSchemaNewQNameRef(pctxt,
  7147. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7148. if (ret == NULL)
  7149. return(NULL);
  7150. ret->node = node;
  7151. pctxt->redef->reference = WXS_BASIC_CAST ret;
  7152. } else {
  7153. /*
  7154. * Create a QName-reference helper component. We will substitute this
  7155. * component for the attribute uses of the referenced attribute group
  7156. * definition.
  7157. */
  7158. ret = xmlSchemaNewQNameRef(pctxt,
  7159. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7160. if (ret == NULL)
  7161. return(NULL);
  7162. ret->node = node;
  7163. /* Add to pending items, to be able to resolve the reference. */
  7164. WXS_ADD_PENDING(pctxt, ret);
  7165. }
  7166. return (ret);
  7167. }
  7168. /**
  7169. * xmlSchemaParseAttributeGroupDefinition:
  7170. * @pctxt: a schema validation context
  7171. * @schema: the schema being built
  7172. * @node: a subtree containing XML Schema information
  7173. *
  7174. * parse a XML schema Attribute Group declaration
  7175. * *WARNING* this interface is highly subject to change
  7176. *
  7177. * Returns the attribute group definition or NULL in case of error.
  7178. */
  7179. static xmlSchemaAttributeGroupPtr
  7180. xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  7181. xmlSchemaPtr schema,
  7182. xmlNodePtr node)
  7183. {
  7184. const xmlChar *name;
  7185. xmlSchemaAttributeGroupPtr ret;
  7186. xmlNodePtr child = NULL;
  7187. xmlAttrPtr attr;
  7188. int hasRefs = 0;
  7189. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7190. return (NULL);
  7191. attr = xmlSchemaGetPropNode(node, "name");
  7192. if (attr == NULL) {
  7193. xmlSchemaPMissingAttrErr(pctxt,
  7194. XML_SCHEMAP_S4S_ATTR_MISSING,
  7195. NULL, node, "name", NULL);
  7196. return (NULL);
  7197. }
  7198. /*
  7199. * The name is crucial, exit if invalid.
  7200. */
  7201. if (xmlSchemaPValAttrNode(pctxt,
  7202. NULL, attr,
  7203. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7204. return (NULL);
  7205. }
  7206. ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
  7207. name, pctxt->targetNamespace, node);
  7208. if (ret == NULL)
  7209. return (NULL);
  7210. /*
  7211. * Check for illegal attributes.
  7212. */
  7213. attr = node->properties;
  7214. while (attr != NULL) {
  7215. if (attr->ns == NULL) {
  7216. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7217. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7218. {
  7219. xmlSchemaPIllegalAttrErr(pctxt,
  7220. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7221. }
  7222. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7223. xmlSchemaPIllegalAttrErr(pctxt,
  7224. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7225. }
  7226. attr = attr->next;
  7227. }
  7228. /* Attribute ID */
  7229. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7230. /*
  7231. * And now for the children...
  7232. */
  7233. child = node->children;
  7234. if (IS_SCHEMA(child, "annotation")) {
  7235. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7236. child = child->next;
  7237. }
  7238. /*
  7239. * Parse contained attribute decls/refs.
  7240. */
  7241. if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
  7242. (xmlSchemaItemListPtr *) &(ret->attrUses),
  7243. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
  7244. return(NULL);
  7245. if (hasRefs)
  7246. ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
  7247. /*
  7248. * Parse the attribute wildcard.
  7249. */
  7250. if (IS_SCHEMA(child, "anyAttribute")) {
  7251. ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
  7252. schema, child);
  7253. child = child->next;
  7254. }
  7255. if (child != NULL) {
  7256. xmlSchemaPContentErr(pctxt,
  7257. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7258. NULL, node, child, NULL,
  7259. "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
  7260. }
  7261. return (ret);
  7262. }
  7263. /**
  7264. * xmlSchemaPValAttrFormDefault:
  7265. * @value: the value
  7266. * @flags: the flags to be modified
  7267. * @flagQualified: the specific flag for "qualified"
  7268. *
  7269. * Returns 0 if the value is valid, 1 otherwise.
  7270. */
  7271. static int
  7272. xmlSchemaPValAttrFormDefault(const xmlChar *value,
  7273. int *flags,
  7274. int flagQualified)
  7275. {
  7276. if (xmlStrEqual(value, BAD_CAST "qualified")) {
  7277. if ((*flags & flagQualified) == 0)
  7278. *flags |= flagQualified;
  7279. } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
  7280. return (1);
  7281. return (0);
  7282. }
  7283. /**
  7284. * xmlSchemaPValAttrBlockFinal:
  7285. * @value: the value
  7286. * @flags: the flags to be modified
  7287. * @flagAll: the specific flag for "#all"
  7288. * @flagExtension: the specific flag for "extension"
  7289. * @flagRestriction: the specific flag for "restriction"
  7290. * @flagSubstitution: the specific flag for "substitution"
  7291. * @flagList: the specific flag for "list"
  7292. * @flagUnion: the specific flag for "union"
  7293. *
  7294. * Validates the value of the attribute "final" and "block". The value
  7295. * is converted into the specified flag values and returned in @flags.
  7296. *
  7297. * Returns 0 if the value is valid, 1 otherwise.
  7298. */
  7299. static int
  7300. xmlSchemaPValAttrBlockFinal(const xmlChar *value,
  7301. int *flags,
  7302. int flagAll,
  7303. int flagExtension,
  7304. int flagRestriction,
  7305. int flagSubstitution,
  7306. int flagList,
  7307. int flagUnion)
  7308. {
  7309. int ret = 0;
  7310. /*
  7311. * TODO: This does not check for duplicate entries.
  7312. */
  7313. if ((flags == NULL) || (value == NULL))
  7314. return (-1);
  7315. if (value[0] == 0)
  7316. return (0);
  7317. if (xmlStrEqual(value, BAD_CAST "#all")) {
  7318. if (flagAll != -1)
  7319. *flags |= flagAll;
  7320. else {
  7321. if (flagExtension != -1)
  7322. *flags |= flagExtension;
  7323. if (flagRestriction != -1)
  7324. *flags |= flagRestriction;
  7325. if (flagSubstitution != -1)
  7326. *flags |= flagSubstitution;
  7327. if (flagList != -1)
  7328. *flags |= flagList;
  7329. if (flagUnion != -1)
  7330. *flags |= flagUnion;
  7331. }
  7332. } else {
  7333. const xmlChar *end, *cur = value;
  7334. xmlChar *item;
  7335. do {
  7336. while (IS_BLANK_CH(*cur))
  7337. cur++;
  7338. end = cur;
  7339. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  7340. end++;
  7341. if (end == cur)
  7342. break;
  7343. item = xmlStrndup(cur, end - cur);
  7344. if (xmlStrEqual(item, BAD_CAST "extension")) {
  7345. if (flagExtension != -1) {
  7346. if ((*flags & flagExtension) == 0)
  7347. *flags |= flagExtension;
  7348. } else
  7349. ret = 1;
  7350. } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
  7351. if (flagRestriction != -1) {
  7352. if ((*flags & flagRestriction) == 0)
  7353. *flags |= flagRestriction;
  7354. } else
  7355. ret = 1;
  7356. } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
  7357. if (flagSubstitution != -1) {
  7358. if ((*flags & flagSubstitution) == 0)
  7359. *flags |= flagSubstitution;
  7360. } else
  7361. ret = 1;
  7362. } else if (xmlStrEqual(item, BAD_CAST "list")) {
  7363. if (flagList != -1) {
  7364. if ((*flags & flagList) == 0)
  7365. *flags |= flagList;
  7366. } else
  7367. ret = 1;
  7368. } else if (xmlStrEqual(item, BAD_CAST "union")) {
  7369. if (flagUnion != -1) {
  7370. if ((*flags & flagUnion) == 0)
  7371. *flags |= flagUnion;
  7372. } else
  7373. ret = 1;
  7374. } else
  7375. ret = 1;
  7376. if (item != NULL)
  7377. xmlFree(item);
  7378. cur = end;
  7379. } while ((ret == 0) && (*cur != 0));
  7380. }
  7381. return (ret);
  7382. }
  7383. static int
  7384. xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
  7385. xmlSchemaIDCPtr idc,
  7386. xmlSchemaIDCSelectPtr selector,
  7387. xmlAttrPtr attr,
  7388. int isField)
  7389. {
  7390. xmlNodePtr node;
  7391. /*
  7392. * c-selector-xpath:
  7393. * Schema Component Constraint: Selector Value OK
  7394. *
  7395. * TODO: 1 The {selector} must be a valid XPath expression, as defined
  7396. * in [XPath].
  7397. */
  7398. if (selector == NULL) {
  7399. xmlSchemaPErr(ctxt, idc->node,
  7400. XML_SCHEMAP_INTERNAL,
  7401. "Internal error: xmlSchemaCheckCSelectorXPath, "
  7402. "the selector is not specified.\n", NULL, NULL);
  7403. return (-1);
  7404. }
  7405. if (attr == NULL)
  7406. node = idc->node;
  7407. else
  7408. node = (xmlNodePtr) attr;
  7409. if (selector->xpath == NULL) {
  7410. xmlSchemaPCustomErr(ctxt,
  7411. /* TODO: Adjust error code. */
  7412. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7413. NULL, node,
  7414. "The XPath expression of the selector is not valid", NULL);
  7415. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7416. } else {
  7417. const xmlChar **nsArray = NULL;
  7418. xmlNsPtr *nsList = NULL;
  7419. /*
  7420. * Compile the XPath expression.
  7421. */
  7422. /*
  7423. * TODO: We need the array of in-scope namespaces for compilation.
  7424. * TODO: Call xmlPatterncompile with different options for selector/
  7425. * field.
  7426. */
  7427. if (attr == NULL)
  7428. nsList = NULL;
  7429. else
  7430. nsList = xmlGetNsList(attr->doc, attr->parent);
  7431. /*
  7432. * Build an array of prefixes and namespaces.
  7433. */
  7434. if (nsList != NULL) {
  7435. int i, count = 0;
  7436. for (i = 0; nsList[i] != NULL; i++)
  7437. count++;
  7438. nsArray = (const xmlChar **) xmlMalloc(
  7439. (count * 2 + 1) * sizeof(const xmlChar *));
  7440. if (nsArray == NULL) {
  7441. xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
  7442. NULL);
  7443. xmlFree(nsList);
  7444. return (-1);
  7445. }
  7446. for (i = 0; i < count; i++) {
  7447. nsArray[2 * i] = nsList[i]->href;
  7448. nsArray[2 * i + 1] = nsList[i]->prefix;
  7449. }
  7450. nsArray[count * 2] = NULL;
  7451. xmlFree(nsList);
  7452. }
  7453. /*
  7454. * TODO: Differentiate between "selector" and "field".
  7455. */
  7456. if (isField)
  7457. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7458. NULL, XML_PATTERN_XSFIELD, nsArray);
  7459. else
  7460. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7461. NULL, XML_PATTERN_XSSEL, nsArray);
  7462. if (nsArray != NULL)
  7463. xmlFree((xmlChar **) nsArray);
  7464. if (selector->xpathComp == NULL) {
  7465. xmlSchemaPCustomErr(ctxt,
  7466. /* TODO: Adjust error code? */
  7467. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7468. NULL, node,
  7469. "The XPath expression '%s' could not be "
  7470. "compiled", selector->xpath);
  7471. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7472. }
  7473. }
  7474. return (0);
  7475. }
  7476. #define ADD_ANNOTATION(annot) \
  7477. xmlSchemaAnnotPtr cur = item->annot; \
  7478. if (item->annot == NULL) { \
  7479. item->annot = annot; \
  7480. return (annot); \
  7481. } \
  7482. cur = item->annot; \
  7483. if (cur->next != NULL) { \
  7484. cur = cur->next; \
  7485. } \
  7486. cur->next = annot;
  7487. /**
  7488. * xmlSchemaAssignAnnotation:
  7489. * @item: the schema component
  7490. * @annot: the annotation
  7491. *
  7492. * Adds the annotation to the given schema component.
  7493. *
  7494. * Returns the given annotation.
  7495. */
  7496. static xmlSchemaAnnotPtr
  7497. xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
  7498. xmlSchemaAnnotPtr annot)
  7499. {
  7500. if ((annItem == NULL) || (annot == NULL))
  7501. return (NULL);
  7502. switch (annItem->type) {
  7503. case XML_SCHEMA_TYPE_ELEMENT: {
  7504. xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
  7505. ADD_ANNOTATION(annot)
  7506. }
  7507. break;
  7508. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  7509. xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
  7510. ADD_ANNOTATION(annot)
  7511. }
  7512. break;
  7513. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  7514. case XML_SCHEMA_TYPE_ANY: {
  7515. xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
  7516. ADD_ANNOTATION(annot)
  7517. }
  7518. break;
  7519. case XML_SCHEMA_TYPE_PARTICLE:
  7520. case XML_SCHEMA_TYPE_IDC_KEY:
  7521. case XML_SCHEMA_TYPE_IDC_KEYREF:
  7522. case XML_SCHEMA_TYPE_IDC_UNIQUE: {
  7523. xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
  7524. ADD_ANNOTATION(annot)
  7525. }
  7526. break;
  7527. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
  7528. xmlSchemaAttributeGroupPtr item =
  7529. (xmlSchemaAttributeGroupPtr) annItem;
  7530. ADD_ANNOTATION(annot)
  7531. }
  7532. break;
  7533. case XML_SCHEMA_TYPE_NOTATION: {
  7534. xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
  7535. ADD_ANNOTATION(annot)
  7536. }
  7537. break;
  7538. case XML_SCHEMA_FACET_MININCLUSIVE:
  7539. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  7540. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  7541. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  7542. case XML_SCHEMA_FACET_TOTALDIGITS:
  7543. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  7544. case XML_SCHEMA_FACET_PATTERN:
  7545. case XML_SCHEMA_FACET_ENUMERATION:
  7546. case XML_SCHEMA_FACET_WHITESPACE:
  7547. case XML_SCHEMA_FACET_LENGTH:
  7548. case XML_SCHEMA_FACET_MAXLENGTH:
  7549. case XML_SCHEMA_FACET_MINLENGTH: {
  7550. xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
  7551. ADD_ANNOTATION(annot)
  7552. }
  7553. break;
  7554. case XML_SCHEMA_TYPE_SIMPLE:
  7555. case XML_SCHEMA_TYPE_COMPLEX: {
  7556. xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
  7557. ADD_ANNOTATION(annot)
  7558. }
  7559. break;
  7560. case XML_SCHEMA_TYPE_GROUP: {
  7561. xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
  7562. ADD_ANNOTATION(annot)
  7563. }
  7564. break;
  7565. case XML_SCHEMA_TYPE_SEQUENCE:
  7566. case XML_SCHEMA_TYPE_CHOICE:
  7567. case XML_SCHEMA_TYPE_ALL: {
  7568. xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
  7569. ADD_ANNOTATION(annot)
  7570. }
  7571. break;
  7572. default:
  7573. xmlSchemaPCustomErr(NULL,
  7574. XML_SCHEMAP_INTERNAL,
  7575. NULL, NULL,
  7576. "Internal error: xmlSchemaAddAnnotation, "
  7577. "The item is not a annotated schema component", NULL);
  7578. break;
  7579. }
  7580. return (annot);
  7581. }
  7582. /**
  7583. * xmlSchemaParseIDCSelectorAndField:
  7584. * @ctxt: a schema validation context
  7585. * @schema: the schema being built
  7586. * @node: a subtree containing XML Schema information
  7587. *
  7588. * Parses a XML Schema identity-constraint definition's
  7589. * <selector> and <field> elements.
  7590. *
  7591. * Returns the parsed identity-constraint definition.
  7592. */
  7593. static xmlSchemaIDCSelectPtr
  7594. xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
  7595. xmlSchemaIDCPtr idc,
  7596. xmlNodePtr node,
  7597. int isField)
  7598. {
  7599. xmlSchemaIDCSelectPtr item;
  7600. xmlNodePtr child = NULL;
  7601. xmlAttrPtr attr;
  7602. /*
  7603. * Check for illegal attributes.
  7604. */
  7605. attr = node->properties;
  7606. while (attr != NULL) {
  7607. if (attr->ns == NULL) {
  7608. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7609. (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
  7610. xmlSchemaPIllegalAttrErr(ctxt,
  7611. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7612. }
  7613. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7614. xmlSchemaPIllegalAttrErr(ctxt,
  7615. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7616. }
  7617. attr = attr->next;
  7618. }
  7619. /*
  7620. * Create the item.
  7621. */
  7622. item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
  7623. if (item == NULL) {
  7624. xmlSchemaPErrMemory(ctxt,
  7625. "allocating a 'selector' of an identity-constraint definition",
  7626. NULL);
  7627. return (NULL);
  7628. }
  7629. memset(item, 0, sizeof(xmlSchemaIDCSelect));
  7630. /*
  7631. * Attribute "xpath" (mandatory).
  7632. */
  7633. attr = xmlSchemaGetPropNode(node, "xpath");
  7634. if (attr == NULL) {
  7635. xmlSchemaPMissingAttrErr(ctxt,
  7636. XML_SCHEMAP_S4S_ATTR_MISSING,
  7637. NULL, node,
  7638. "name", NULL);
  7639. } else {
  7640. item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7641. /*
  7642. * URGENT TODO: "field"s have an other syntax than "selector"s.
  7643. */
  7644. if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
  7645. isField) == -1) {
  7646. xmlSchemaPErr(ctxt,
  7647. (xmlNodePtr) attr,
  7648. XML_SCHEMAP_INTERNAL,
  7649. "Internal error: xmlSchemaParseIDCSelectorAndField, "
  7650. "validating the XPath expression of a IDC selector.\n",
  7651. NULL, NULL);
  7652. }
  7653. }
  7654. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7655. /*
  7656. * And now for the children...
  7657. */
  7658. child = node->children;
  7659. if (IS_SCHEMA(child, "annotation")) {
  7660. /*
  7661. * Add the annotation to the parent IDC.
  7662. */
  7663. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
  7664. xmlSchemaParseAnnotation(ctxt, child, 1));
  7665. child = child->next;
  7666. }
  7667. if (child != NULL) {
  7668. xmlSchemaPContentErr(ctxt,
  7669. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7670. NULL, node, child,
  7671. NULL, "(annotation?)");
  7672. }
  7673. return (item);
  7674. }
  7675. /**
  7676. * xmlSchemaParseIDC:
  7677. * @ctxt: a schema validation context
  7678. * @schema: the schema being built
  7679. * @node: a subtree containing XML Schema information
  7680. *
  7681. * Parses a XML Schema identity-constraint definition.
  7682. *
  7683. * Returns the parsed identity-constraint definition.
  7684. */
  7685. static xmlSchemaIDCPtr
  7686. xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
  7687. xmlSchemaPtr schema,
  7688. xmlNodePtr node,
  7689. xmlSchemaTypeType idcCategory,
  7690. const xmlChar *targetNamespace)
  7691. {
  7692. xmlSchemaIDCPtr item = NULL;
  7693. xmlNodePtr child = NULL;
  7694. xmlAttrPtr attr;
  7695. const xmlChar *name = NULL;
  7696. xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
  7697. /*
  7698. * Check for illegal attributes.
  7699. */
  7700. attr = node->properties;
  7701. while (attr != NULL) {
  7702. if (attr->ns == NULL) {
  7703. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7704. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7705. ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
  7706. (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
  7707. xmlSchemaPIllegalAttrErr(ctxt,
  7708. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7709. }
  7710. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7711. xmlSchemaPIllegalAttrErr(ctxt,
  7712. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7713. }
  7714. attr = attr->next;
  7715. }
  7716. /*
  7717. * Attribute "name" (mandatory).
  7718. */
  7719. attr = xmlSchemaGetPropNode(node, "name");
  7720. if (attr == NULL) {
  7721. xmlSchemaPMissingAttrErr(ctxt,
  7722. XML_SCHEMAP_S4S_ATTR_MISSING,
  7723. NULL, node,
  7724. "name", NULL);
  7725. return (NULL);
  7726. } else if (xmlSchemaPValAttrNode(ctxt,
  7727. NULL, attr,
  7728. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7729. return (NULL);
  7730. }
  7731. /* Create the component. */
  7732. item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
  7733. idcCategory, node);
  7734. if (item == NULL)
  7735. return(NULL);
  7736. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7737. if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
  7738. /*
  7739. * Attribute "refer" (mandatory).
  7740. */
  7741. attr = xmlSchemaGetPropNode(node, "refer");
  7742. if (attr == NULL) {
  7743. xmlSchemaPMissingAttrErr(ctxt,
  7744. XML_SCHEMAP_S4S_ATTR_MISSING,
  7745. NULL, node,
  7746. "refer", NULL);
  7747. } else {
  7748. /*
  7749. * Create a reference item.
  7750. */
  7751. item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
  7752. NULL, NULL);
  7753. if (item->ref == NULL)
  7754. return (NULL);
  7755. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7756. NULL, attr,
  7757. &(item->ref->targetNamespace),
  7758. &(item->ref->name));
  7759. xmlSchemaCheckReference(ctxt, schema, node, attr,
  7760. item->ref->targetNamespace);
  7761. }
  7762. }
  7763. /*
  7764. * And now for the children...
  7765. */
  7766. child = node->children;
  7767. if (IS_SCHEMA(child, "annotation")) {
  7768. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7769. child = child->next;
  7770. }
  7771. if (child == NULL) {
  7772. xmlSchemaPContentErr(ctxt,
  7773. XML_SCHEMAP_S4S_ELEM_MISSING,
  7774. NULL, node, child,
  7775. "A child element is missing",
  7776. "(annotation?, (selector, field+))");
  7777. }
  7778. /*
  7779. * Child element <selector>.
  7780. */
  7781. if (IS_SCHEMA(child, "selector")) {
  7782. item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
  7783. item, child, 0);
  7784. child = child->next;
  7785. /*
  7786. * Child elements <field>.
  7787. */
  7788. if (IS_SCHEMA(child, "field")) {
  7789. do {
  7790. field = xmlSchemaParseIDCSelectorAndField(ctxt,
  7791. item, child, 1);
  7792. if (field != NULL) {
  7793. field->index = item->nbFields;
  7794. item->nbFields++;
  7795. if (lastField != NULL)
  7796. lastField->next = field;
  7797. else
  7798. item->fields = field;
  7799. lastField = field;
  7800. }
  7801. child = child->next;
  7802. } while (IS_SCHEMA(child, "field"));
  7803. } else {
  7804. xmlSchemaPContentErr(ctxt,
  7805. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7806. NULL, node, child,
  7807. NULL, "(annotation?, (selector, field+))");
  7808. }
  7809. }
  7810. if (child != NULL) {
  7811. xmlSchemaPContentErr(ctxt,
  7812. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7813. NULL, node, child,
  7814. NULL, "(annotation?, (selector, field+))");
  7815. }
  7816. return (item);
  7817. }
  7818. /**
  7819. * xmlSchemaParseElement:
  7820. * @ctxt: a schema validation context
  7821. * @schema: the schema being built
  7822. * @node: a subtree containing XML Schema information
  7823. * @topLevel: indicates if this is global declaration
  7824. *
  7825. * Parses a XML schema element declaration.
  7826. * *WARNING* this interface is highly subject to change
  7827. *
  7828. * Returns the element declaration or a particle; NULL in case
  7829. * of an error or if the particle has minOccurs==maxOccurs==0.
  7830. */
  7831. static xmlSchemaBasicItemPtr
  7832. xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  7833. xmlNodePtr node, int *isElemRef, int topLevel)
  7834. {
  7835. xmlSchemaElementPtr decl = NULL;
  7836. xmlSchemaParticlePtr particle = NULL;
  7837. xmlSchemaAnnotPtr annot = NULL;
  7838. xmlNodePtr child = NULL;
  7839. xmlAttrPtr attr, nameAttr;
  7840. int min, max, isRef = 0;
  7841. xmlChar *des = NULL;
  7842. /* 3.3.3 Constraints on XML Representations of Element Declarations */
  7843. /* TODO: Complete implementation of 3.3.6 */
  7844. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  7845. return (NULL);
  7846. if (isElemRef != NULL)
  7847. *isElemRef = 0;
  7848. /*
  7849. * If we get a "ref" attribute on a local <element> we will assume it's
  7850. * a reference - even if there's a "name" attribute; this seems to be more
  7851. * robust.
  7852. */
  7853. nameAttr = xmlSchemaGetPropNode(node, "name");
  7854. attr = xmlSchemaGetPropNode(node, "ref");
  7855. if ((topLevel) || (attr == NULL)) {
  7856. if (nameAttr == NULL) {
  7857. xmlSchemaPMissingAttrErr(ctxt,
  7858. XML_SCHEMAP_S4S_ATTR_MISSING,
  7859. NULL, node, "name", NULL);
  7860. return (NULL);
  7861. }
  7862. } else
  7863. isRef = 1;
  7864. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7865. child = node->children;
  7866. if (IS_SCHEMA(child, "annotation")) {
  7867. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7868. child = child->next;
  7869. }
  7870. /*
  7871. * Skip particle part if a global declaration.
  7872. */
  7873. if (topLevel)
  7874. goto declaration_part;
  7875. /*
  7876. * The particle part ==================================================
  7877. */
  7878. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  7879. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
  7880. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  7881. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  7882. if (particle == NULL)
  7883. goto return_null;
  7884. /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
  7885. if (isRef) {
  7886. const xmlChar *refNs = NULL, *ref = NULL;
  7887. xmlSchemaQNameRefPtr refer = NULL;
  7888. /*
  7889. * The reference part =============================================
  7890. */
  7891. if (isElemRef != NULL)
  7892. *isElemRef = 1;
  7893. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7894. NULL, attr, &refNs, &ref);
  7895. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  7896. /*
  7897. * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
  7898. */
  7899. if (nameAttr != NULL) {
  7900. xmlSchemaPMutualExclAttrErr(ctxt,
  7901. XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
  7902. }
  7903. /*
  7904. * Check for illegal attributes.
  7905. */
  7906. attr = node->properties;
  7907. while (attr != NULL) {
  7908. if (attr->ns == NULL) {
  7909. if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
  7910. xmlStrEqual(attr->name, BAD_CAST "name") ||
  7911. xmlStrEqual(attr->name, BAD_CAST "id") ||
  7912. xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
  7913. xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
  7914. {
  7915. attr = attr->next;
  7916. continue;
  7917. } else {
  7918. /* SPEC (3.3.3 : 2.2) */
  7919. xmlSchemaPCustomAttrErr(ctxt,
  7920. XML_SCHEMAP_SRC_ELEMENT_2_2,
  7921. NULL, NULL, attr,
  7922. "Only the attributes 'minOccurs', 'maxOccurs' and "
  7923. "'id' are allowed in addition to 'ref'");
  7924. break;
  7925. }
  7926. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7927. xmlSchemaPIllegalAttrErr(ctxt,
  7928. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7929. }
  7930. attr = attr->next;
  7931. }
  7932. /*
  7933. * No children except <annotation> expected.
  7934. */
  7935. if (child != NULL) {
  7936. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7937. NULL, node, child, NULL, "(annotation?)");
  7938. }
  7939. if ((min == 0) && (max == 0))
  7940. goto return_null;
  7941. /*
  7942. * Create the reference item and attach it to the particle.
  7943. */
  7944. refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
  7945. ref, refNs);
  7946. if (refer == NULL)
  7947. goto return_null;
  7948. particle->children = (xmlSchemaTreeItemPtr) refer;
  7949. particle->annot = annot;
  7950. /*
  7951. * Add the particle to pending components, since the reference
  7952. * need to be resolved.
  7953. */
  7954. WXS_ADD_PENDING(ctxt, particle);
  7955. return ((xmlSchemaBasicItemPtr) particle);
  7956. }
  7957. /*
  7958. * The declaration part ===============================================
  7959. */
  7960. declaration_part:
  7961. {
  7962. const xmlChar *ns = NULL, *fixed, *name, *attrValue;
  7963. xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
  7964. if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
  7965. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
  7966. goto return_null;
  7967. /*
  7968. * Evaluate the target namespace.
  7969. */
  7970. if (topLevel) {
  7971. ns = ctxt->targetNamespace;
  7972. } else {
  7973. attr = xmlSchemaGetPropNode(node, "form");
  7974. if (attr != NULL) {
  7975. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7976. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  7977. ns = ctxt->targetNamespace;
  7978. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
  7979. xmlSchemaPSimpleTypeErr(ctxt,
  7980. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7981. NULL, (xmlNodePtr) attr,
  7982. NULL, "(qualified | unqualified)",
  7983. attrValue, NULL, NULL, NULL);
  7984. }
  7985. } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  7986. ns = ctxt->targetNamespace;
  7987. }
  7988. decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
  7989. if (decl == NULL) {
  7990. goto return_null;
  7991. }
  7992. /*
  7993. * Check for illegal attributes.
  7994. */
  7995. attr = node->properties;
  7996. while (attr != NULL) {
  7997. if (attr->ns == NULL) {
  7998. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7999. (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
  8000. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8001. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  8002. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  8003. (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
  8004. (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
  8005. {
  8006. if (topLevel == 0) {
  8007. if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  8008. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8009. (!xmlStrEqual(attr->name, BAD_CAST "form")))
  8010. {
  8011. xmlSchemaPIllegalAttrErr(ctxt,
  8012. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8013. }
  8014. } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
  8015. (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
  8016. (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
  8017. xmlSchemaPIllegalAttrErr(ctxt,
  8018. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8019. }
  8020. }
  8021. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8022. xmlSchemaPIllegalAttrErr(ctxt,
  8023. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8024. }
  8025. attr = attr->next;
  8026. }
  8027. /*
  8028. * Extract/validate attributes.
  8029. */
  8030. if (topLevel) {
  8031. /*
  8032. * Process top attributes of global element declarations here.
  8033. */
  8034. decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
  8035. decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
  8036. xmlSchemaPValAttrQName(ctxt, schema,
  8037. NULL, node, "substitutionGroup",
  8038. &(decl->substGroupNs), &(decl->substGroup));
  8039. if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
  8040. decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
  8041. /*
  8042. * Attribute "final".
  8043. */
  8044. attr = xmlSchemaGetPropNode(node, "final");
  8045. if (attr == NULL) {
  8046. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8047. decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
  8048. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8049. decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
  8050. } else {
  8051. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8052. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8053. -1,
  8054. XML_SCHEMAS_ELEM_FINAL_EXTENSION,
  8055. XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
  8056. xmlSchemaPSimpleTypeErr(ctxt,
  8057. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8058. NULL, (xmlNodePtr) attr,
  8059. NULL, "(#all | List of (extension | restriction))",
  8060. attrValue, NULL, NULL, NULL);
  8061. }
  8062. }
  8063. }
  8064. /*
  8065. * Attribute "block".
  8066. */
  8067. attr = xmlSchemaGetPropNode(node, "block");
  8068. if (attr == NULL) {
  8069. /*
  8070. * Apply default "block" values.
  8071. */
  8072. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8073. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
  8074. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8075. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
  8076. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8077. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
  8078. } else {
  8079. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8080. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8081. -1,
  8082. XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
  8083. XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
  8084. XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
  8085. xmlSchemaPSimpleTypeErr(ctxt,
  8086. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8087. NULL, (xmlNodePtr) attr,
  8088. NULL, "(#all | List of (extension | "
  8089. "restriction | substitution))", attrValue,
  8090. NULL, NULL, NULL);
  8091. }
  8092. }
  8093. if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
  8094. decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
  8095. attr = xmlSchemaGetPropNode(node, "type");
  8096. if (attr != NULL) {
  8097. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8098. NULL, attr,
  8099. &(decl->namedTypeNs), &(decl->namedType));
  8100. xmlSchemaCheckReference(ctxt, schema, node,
  8101. attr, decl->namedTypeNs);
  8102. }
  8103. decl->value = xmlSchemaGetProp(ctxt, node, "default");
  8104. attr = xmlSchemaGetPropNode(node, "fixed");
  8105. if (attr != NULL) {
  8106. fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8107. if (decl->value != NULL) {
  8108. /*
  8109. * 3.3.3 : 1
  8110. * default and fixed must not both be present.
  8111. */
  8112. xmlSchemaPMutualExclAttrErr(ctxt,
  8113. XML_SCHEMAP_SRC_ELEMENT_1,
  8114. NULL, attr, "default", "fixed");
  8115. } else {
  8116. decl->flags |= XML_SCHEMAS_ELEM_FIXED;
  8117. decl->value = fixed;
  8118. }
  8119. }
  8120. /*
  8121. * And now for the children...
  8122. */
  8123. if (IS_SCHEMA(child, "complexType")) {
  8124. /*
  8125. * 3.3.3 : 3
  8126. * "type" and either <simpleType> or <complexType> are mutually
  8127. * exclusive
  8128. */
  8129. if (decl->namedType != NULL) {
  8130. xmlSchemaPContentErr(ctxt,
  8131. XML_SCHEMAP_SRC_ELEMENT_3,
  8132. NULL, node, child,
  8133. "The attribute 'type' and the <complexType> child are "
  8134. "mutually exclusive", NULL);
  8135. } else
  8136. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
  8137. child = child->next;
  8138. } else if (IS_SCHEMA(child, "simpleType")) {
  8139. /*
  8140. * 3.3.3 : 3
  8141. * "type" and either <simpleType> or <complexType> are
  8142. * mutually exclusive
  8143. */
  8144. if (decl->namedType != NULL) {
  8145. xmlSchemaPContentErr(ctxt,
  8146. XML_SCHEMAP_SRC_ELEMENT_3,
  8147. NULL, node, child,
  8148. "The attribute 'type' and the <simpleType> child are "
  8149. "mutually exclusive", NULL);
  8150. } else
  8151. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8152. child = child->next;
  8153. }
  8154. while ((IS_SCHEMA(child, "unique")) ||
  8155. (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
  8156. if (IS_SCHEMA(child, "unique")) {
  8157. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8158. XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
  8159. } else if (IS_SCHEMA(child, "key")) {
  8160. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8161. XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
  8162. } else if (IS_SCHEMA(child, "keyref")) {
  8163. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8164. XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
  8165. }
  8166. if (lastIDC != NULL)
  8167. lastIDC->next = curIDC;
  8168. else
  8169. decl->idcs = (void *) curIDC;
  8170. lastIDC = curIDC;
  8171. child = child->next;
  8172. }
  8173. if (child != NULL) {
  8174. xmlSchemaPContentErr(ctxt,
  8175. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8176. NULL, node, child,
  8177. NULL, "(annotation?, ((simpleType | complexType)?, "
  8178. "(unique | key | keyref)*))");
  8179. }
  8180. decl->annot = annot;
  8181. }
  8182. /*
  8183. * NOTE: Element Declaration Representation OK 4. will be checked at a
  8184. * different layer.
  8185. */
  8186. FREE_AND_NULL(des)
  8187. if (topLevel)
  8188. return ((xmlSchemaBasicItemPtr) decl);
  8189. else {
  8190. particle->children = (xmlSchemaTreeItemPtr) decl;
  8191. return ((xmlSchemaBasicItemPtr) particle);
  8192. }
  8193. return_null:
  8194. FREE_AND_NULL(des);
  8195. if (annot != NULL) {
  8196. if (particle != NULL)
  8197. particle->annot = NULL;
  8198. if (decl != NULL)
  8199. decl->annot = NULL;
  8200. xmlSchemaFreeAnnot(annot);
  8201. }
  8202. return (NULL);
  8203. }
  8204. /**
  8205. * xmlSchemaParseUnion:
  8206. * @ctxt: a schema validation context
  8207. * @schema: the schema being built
  8208. * @node: a subtree containing XML Schema information
  8209. *
  8210. * parse a XML schema Union definition
  8211. * *WARNING* this interface is highly subject to change
  8212. *
  8213. * Returns -1 in case of internal error, 0 in case of success and a positive
  8214. * error code otherwise.
  8215. */
  8216. static int
  8217. xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8218. xmlNodePtr node)
  8219. {
  8220. xmlSchemaTypePtr type;
  8221. xmlNodePtr child = NULL;
  8222. xmlAttrPtr attr;
  8223. const xmlChar *cur = NULL;
  8224. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8225. return (-1);
  8226. /* Not a component, don't create it. */
  8227. type = ctxt->ctxtType;
  8228. /*
  8229. * Mark the simple type as being of variety "union".
  8230. */
  8231. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  8232. /*
  8233. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8234. * then the `simple ur-type definition`."
  8235. */
  8236. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8237. /*
  8238. * Check for illegal attributes.
  8239. */
  8240. attr = node->properties;
  8241. while (attr != NULL) {
  8242. if (attr->ns == NULL) {
  8243. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8244. (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
  8245. xmlSchemaPIllegalAttrErr(ctxt,
  8246. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8247. }
  8248. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8249. xmlSchemaPIllegalAttrErr(ctxt,
  8250. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8251. }
  8252. attr = attr->next;
  8253. }
  8254. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8255. /*
  8256. * Attribute "memberTypes". This is a list of QNames.
  8257. * TODO: Check the value to contain anything.
  8258. */
  8259. attr = xmlSchemaGetPropNode(node, "memberTypes");
  8260. if (attr != NULL) {
  8261. const xmlChar *end;
  8262. xmlChar *tmp;
  8263. const xmlChar *localName, *nsName;
  8264. xmlSchemaTypeLinkPtr link, lastLink = NULL;
  8265. xmlSchemaQNameRefPtr ref;
  8266. cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8267. if (cur == NULL)
  8268. return (-1);
  8269. type->base = cur;
  8270. do {
  8271. while (IS_BLANK_CH(*cur))
  8272. cur++;
  8273. end = cur;
  8274. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  8275. end++;
  8276. if (end == cur)
  8277. break;
  8278. tmp = xmlStrndup(cur, end - cur);
  8279. if (tmp == NULL) {
  8280. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8281. "duplicating type name", NULL);
  8282. return (-1);
  8283. }
  8284. if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  8285. NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
  8286. /*
  8287. * Create the member type link.
  8288. */
  8289. link = (xmlSchemaTypeLinkPtr)
  8290. xmlMalloc(sizeof(xmlSchemaTypeLink));
  8291. if (link == NULL) {
  8292. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8293. "allocating a type link", NULL);
  8294. FREE_AND_NULL(tmp)
  8295. return (-1);
  8296. }
  8297. link->type = NULL;
  8298. link->next = NULL;
  8299. if (lastLink == NULL)
  8300. type->memberTypes = link;
  8301. else
  8302. lastLink->next = link;
  8303. lastLink = link;
  8304. /*
  8305. * Create a reference item.
  8306. */
  8307. ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
  8308. localName, nsName);
  8309. if (ref == NULL) {
  8310. FREE_AND_NULL(tmp)
  8311. return (-1);
  8312. }
  8313. /*
  8314. * Assign the reference to the link, it will be resolved
  8315. * later during fixup of the union simple type.
  8316. */
  8317. link->type = (xmlSchemaTypePtr) ref;
  8318. }
  8319. FREE_AND_NULL(tmp)
  8320. cur = end;
  8321. } while (*cur != 0);
  8322. }
  8323. /*
  8324. * And now for the children...
  8325. */
  8326. child = node->children;
  8327. if (IS_SCHEMA(child, "annotation")) {
  8328. /*
  8329. * Add the annotation to the simple type ancestor.
  8330. */
  8331. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8332. xmlSchemaParseAnnotation(ctxt, child, 1));
  8333. child = child->next;
  8334. }
  8335. if (IS_SCHEMA(child, "simpleType")) {
  8336. xmlSchemaTypePtr subtype, last = NULL;
  8337. /*
  8338. * Anchor the member types in the "subtypes" field of the
  8339. * simple type.
  8340. */
  8341. while (IS_SCHEMA(child, "simpleType")) {
  8342. subtype = (xmlSchemaTypePtr)
  8343. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8344. if (subtype != NULL) {
  8345. if (last == NULL) {
  8346. type->subtypes = subtype;
  8347. last = subtype;
  8348. } else {
  8349. last->next = subtype;
  8350. last = subtype;
  8351. }
  8352. last->next = NULL;
  8353. }
  8354. child = child->next;
  8355. }
  8356. }
  8357. if (child != NULL) {
  8358. xmlSchemaPContentErr(ctxt,
  8359. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8360. NULL, node, child, NULL, "(annotation?, simpleType*)");
  8361. }
  8362. if ((attr == NULL) && (type->subtypes == NULL)) {
  8363. /*
  8364. * src-union-memberTypes-or-simpleTypes
  8365. * Either the memberTypes [attribute] of the <union> element must
  8366. * be non-empty or there must be at least one simpleType [child].
  8367. */
  8368. xmlSchemaPCustomErr(ctxt,
  8369. XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
  8370. NULL, node,
  8371. "Either the attribute 'memberTypes' or "
  8372. "at least one <simpleType> child must be present", NULL);
  8373. }
  8374. return (0);
  8375. }
  8376. /**
  8377. * xmlSchemaParseList:
  8378. * @ctxt: a schema validation context
  8379. * @schema: the schema being built
  8380. * @node: a subtree containing XML Schema information
  8381. *
  8382. * parse a XML schema List definition
  8383. * *WARNING* this interface is highly subject to change
  8384. *
  8385. * Returns -1 in case of error, 0 if the declaration is improper and
  8386. * 1 in case of success.
  8387. */
  8388. static xmlSchemaTypePtr
  8389. xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8390. xmlNodePtr node)
  8391. {
  8392. xmlSchemaTypePtr type;
  8393. xmlNodePtr child = NULL;
  8394. xmlAttrPtr attr;
  8395. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8396. return (NULL);
  8397. /* Not a component, don't create it. */
  8398. type = ctxt->ctxtType;
  8399. /*
  8400. * Mark the type as being of variety "list".
  8401. */
  8402. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  8403. /*
  8404. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8405. * then the `simple ur-type definition`."
  8406. */
  8407. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8408. /*
  8409. * Check for illegal attributes.
  8410. */
  8411. attr = node->properties;
  8412. while (attr != NULL) {
  8413. if (attr->ns == NULL) {
  8414. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8415. (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
  8416. xmlSchemaPIllegalAttrErr(ctxt,
  8417. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8418. }
  8419. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8420. xmlSchemaPIllegalAttrErr(ctxt,
  8421. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8422. }
  8423. attr = attr->next;
  8424. }
  8425. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8426. /*
  8427. * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
  8428. * fields for holding the reference to the itemType.
  8429. *
  8430. * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
  8431. * the "ref" fields.
  8432. */
  8433. xmlSchemaPValAttrQName(ctxt, schema, NULL,
  8434. node, "itemType", &(type->baseNs), &(type->base));
  8435. /*
  8436. * And now for the children...
  8437. */
  8438. child = node->children;
  8439. if (IS_SCHEMA(child, "annotation")) {
  8440. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8441. xmlSchemaParseAnnotation(ctxt, child, 1));
  8442. child = child->next;
  8443. }
  8444. if (IS_SCHEMA(child, "simpleType")) {
  8445. /*
  8446. * src-list-itemType-or-simpleType
  8447. * Either the itemType [attribute] or the <simpleType> [child] of
  8448. * the <list> element must be present, but not both.
  8449. */
  8450. if (type->base != NULL) {
  8451. xmlSchemaPCustomErr(ctxt,
  8452. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8453. NULL, node,
  8454. "The attribute 'itemType' and the <simpleType> child "
  8455. "are mutually exclusive", NULL);
  8456. } else {
  8457. type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8458. }
  8459. child = child->next;
  8460. } else if (type->base == NULL) {
  8461. xmlSchemaPCustomErr(ctxt,
  8462. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8463. NULL, node,
  8464. "Either the attribute 'itemType' or the <simpleType> child "
  8465. "must be present", NULL);
  8466. }
  8467. if (child != NULL) {
  8468. xmlSchemaPContentErr(ctxt,
  8469. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8470. NULL, node, child, NULL, "(annotation?, simpleType?)");
  8471. }
  8472. if ((type->base == NULL) &&
  8473. (type->subtypes == NULL) &&
  8474. (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
  8475. xmlSchemaPCustomErr(ctxt,
  8476. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8477. NULL, node,
  8478. "Either the attribute 'itemType' or the <simpleType> child "
  8479. "must be present", NULL);
  8480. }
  8481. return (NULL);
  8482. }
  8483. /**
  8484. * xmlSchemaParseSimpleType:
  8485. * @ctxt: a schema validation context
  8486. * @schema: the schema being built
  8487. * @node: a subtree containing XML Schema information
  8488. *
  8489. * parse a XML schema Simple Type definition
  8490. * *WARNING* this interface is highly subject to change
  8491. *
  8492. * Returns -1 in case of error, 0 if the declaration is improper and
  8493. * 1 in case of success.
  8494. */
  8495. static xmlSchemaTypePtr
  8496. xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8497. xmlNodePtr node, int topLevel)
  8498. {
  8499. xmlSchemaTypePtr type, oldCtxtType;
  8500. xmlNodePtr child = NULL;
  8501. const xmlChar *attrValue = NULL;
  8502. xmlAttrPtr attr;
  8503. int hasRestriction = 0;
  8504. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8505. return (NULL);
  8506. if (topLevel) {
  8507. attr = xmlSchemaGetPropNode(node, "name");
  8508. if (attr == NULL) {
  8509. xmlSchemaPMissingAttrErr(ctxt,
  8510. XML_SCHEMAP_S4S_ATTR_MISSING,
  8511. NULL, node,
  8512. "name", NULL);
  8513. return (NULL);
  8514. } else {
  8515. if (xmlSchemaPValAttrNode(ctxt,
  8516. NULL, attr,
  8517. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
  8518. return (NULL);
  8519. /*
  8520. * Skip built-in types.
  8521. */
  8522. if (ctxt->isS4S) {
  8523. xmlSchemaTypePtr biType;
  8524. if (ctxt->isRedefine) {
  8525. /*
  8526. * REDEFINE: Disallow redefinition of built-in-types.
  8527. * TODO: It seems that the spec does not say anything
  8528. * about this case.
  8529. */
  8530. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8531. NULL, node,
  8532. "Redefinition of built-in simple types is not "
  8533. "supported", NULL);
  8534. return(NULL);
  8535. }
  8536. biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
  8537. if (biType != NULL)
  8538. return (biType);
  8539. }
  8540. }
  8541. }
  8542. /*
  8543. * TargetNamespace:
  8544. * SPEC "The `actual value` of the targetNamespace [attribute]
  8545. * of the <schema> ancestor element information item if present,
  8546. * otherwise `absent`.
  8547. */
  8548. if (topLevel == 0) {
  8549. #ifdef ENABLE_NAMED_LOCALS
  8550. char buf[40];
  8551. #endif
  8552. /*
  8553. * Parse as local simple type definition.
  8554. */
  8555. #ifdef ENABLE_NAMED_LOCALS
  8556. snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
  8557. type = xmlSchemaAddType(ctxt, schema,
  8558. XML_SCHEMA_TYPE_SIMPLE,
  8559. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  8560. ctxt->targetNamespace, node, 0);
  8561. #else
  8562. type = xmlSchemaAddType(ctxt, schema,
  8563. XML_SCHEMA_TYPE_SIMPLE,
  8564. NULL, ctxt->targetNamespace, node, 0);
  8565. #endif
  8566. if (type == NULL)
  8567. return (NULL);
  8568. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8569. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8570. /*
  8571. * Check for illegal attributes.
  8572. */
  8573. attr = node->properties;
  8574. while (attr != NULL) {
  8575. if (attr->ns == NULL) {
  8576. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  8577. xmlSchemaPIllegalAttrErr(ctxt,
  8578. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8579. }
  8580. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8581. xmlSchemaPIllegalAttrErr(ctxt,
  8582. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8583. }
  8584. attr = attr->next;
  8585. }
  8586. } else {
  8587. /*
  8588. * Parse as global simple type definition.
  8589. *
  8590. * Note that attrValue is the value of the attribute "name" here.
  8591. */
  8592. type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
  8593. attrValue, ctxt->targetNamespace, node, 1);
  8594. if (type == NULL)
  8595. return (NULL);
  8596. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8597. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8598. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  8599. /*
  8600. * Check for illegal attributes.
  8601. */
  8602. attr = node->properties;
  8603. while (attr != NULL) {
  8604. if (attr->ns == NULL) {
  8605. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8606. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8607. (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
  8608. xmlSchemaPIllegalAttrErr(ctxt,
  8609. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8610. }
  8611. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8612. xmlSchemaPIllegalAttrErr(ctxt,
  8613. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8614. }
  8615. attr = attr->next;
  8616. }
  8617. /*
  8618. * Attribute "final".
  8619. */
  8620. attr = xmlSchemaGetPropNode(node, "final");
  8621. if (attr == NULL) {
  8622. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8623. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  8624. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8625. type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
  8626. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8627. type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
  8628. } else {
  8629. attrValue = xmlSchemaGetProp(ctxt, node, "final");
  8630. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  8631. -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
  8632. XML_SCHEMAS_TYPE_FINAL_LIST,
  8633. XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
  8634. xmlSchemaPSimpleTypeErr(ctxt,
  8635. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8636. WXS_BASIC_CAST type, (xmlNodePtr) attr,
  8637. NULL, "(#all | List of (list | union | restriction)",
  8638. attrValue, NULL, NULL, NULL);
  8639. }
  8640. }
  8641. }
  8642. type->targetNamespace = ctxt->targetNamespace;
  8643. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8644. /*
  8645. * And now for the children...
  8646. */
  8647. oldCtxtType = ctxt->ctxtType;
  8648. ctxt->ctxtType = type;
  8649. child = node->children;
  8650. if (IS_SCHEMA(child, "annotation")) {
  8651. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8652. child = child->next;
  8653. }
  8654. if (child == NULL) {
  8655. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
  8656. NULL, node, child, NULL,
  8657. "(annotation?, (restriction | list | union))");
  8658. } else if (IS_SCHEMA(child, "restriction")) {
  8659. xmlSchemaParseRestriction(ctxt, schema, child,
  8660. XML_SCHEMA_TYPE_SIMPLE);
  8661. hasRestriction = 1;
  8662. child = child->next;
  8663. } else if (IS_SCHEMA(child, "list")) {
  8664. xmlSchemaParseList(ctxt, schema, child);
  8665. child = child->next;
  8666. } else if (IS_SCHEMA(child, "union")) {
  8667. xmlSchemaParseUnion(ctxt, schema, child);
  8668. child = child->next;
  8669. }
  8670. if (child != NULL) {
  8671. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8672. NULL, node, child, NULL,
  8673. "(annotation?, (restriction | list | union))");
  8674. }
  8675. /*
  8676. * REDEFINE: SPEC src-redefine (5)
  8677. * "Within the [children], each <simpleType> must have a
  8678. * <restriction> among its [children] ... the `actual value` of whose
  8679. * base [attribute] must be the same as the `actual value` of its own
  8680. * name attribute plus target namespace;"
  8681. */
  8682. if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
  8683. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8684. NULL, node, "This is a redefinition, thus the "
  8685. "<simpleType> must have a <restriction> child", NULL);
  8686. }
  8687. ctxt->ctxtType = oldCtxtType;
  8688. return (type);
  8689. }
  8690. /**
  8691. * xmlSchemaParseModelGroupDefRef:
  8692. * @ctxt: the parser context
  8693. * @schema: the schema being built
  8694. * @node: the node
  8695. *
  8696. * Parses a reference to a model group definition.
  8697. *
  8698. * We will return a particle component with a qname-component or
  8699. * NULL in case of an error.
  8700. */
  8701. static xmlSchemaTreeItemPtr
  8702. xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
  8703. xmlSchemaPtr schema,
  8704. xmlNodePtr node)
  8705. {
  8706. xmlSchemaParticlePtr item;
  8707. xmlNodePtr child = NULL;
  8708. xmlAttrPtr attr;
  8709. const xmlChar *ref = NULL, *refNs = NULL;
  8710. int min, max;
  8711. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8712. return (NULL);
  8713. attr = xmlSchemaGetPropNode(node, "ref");
  8714. if (attr == NULL) {
  8715. xmlSchemaPMissingAttrErr(ctxt,
  8716. XML_SCHEMAP_S4S_ATTR_MISSING,
  8717. NULL, node, "ref", NULL);
  8718. return (NULL);
  8719. } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
  8720. attr, &refNs, &ref) != 0) {
  8721. return (NULL);
  8722. }
  8723. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8724. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  8725. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  8726. "(xs:nonNegativeInteger | unbounded)");
  8727. /*
  8728. * Check for illegal attributes.
  8729. */
  8730. attr = node->properties;
  8731. while (attr != NULL) {
  8732. if (attr->ns == NULL) {
  8733. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  8734. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8735. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8736. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
  8737. xmlSchemaPIllegalAttrErr(ctxt,
  8738. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8739. }
  8740. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8741. xmlSchemaPIllegalAttrErr(ctxt,
  8742. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8743. }
  8744. attr = attr->next;
  8745. }
  8746. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8747. item = xmlSchemaAddParticle(ctxt, node, min, max);
  8748. if (item == NULL)
  8749. return (NULL);
  8750. /*
  8751. * Create a qname-reference and set as the term; it will be substituted
  8752. * for the model group after the reference has been resolved.
  8753. */
  8754. item->children = (xmlSchemaTreeItemPtr)
  8755. xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
  8756. xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
  8757. /*
  8758. * And now for the children...
  8759. */
  8760. child = node->children;
  8761. /* TODO: Is annotation even allowed for a model group reference? */
  8762. if (IS_SCHEMA(child, "annotation")) {
  8763. /*
  8764. * TODO: What to do exactly with the annotation?
  8765. */
  8766. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8767. child = child->next;
  8768. }
  8769. if (child != NULL) {
  8770. xmlSchemaPContentErr(ctxt,
  8771. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8772. NULL, node, child, NULL,
  8773. "(annotation?)");
  8774. }
  8775. /*
  8776. * Corresponds to no component at all if minOccurs==maxOccurs==0.
  8777. */
  8778. if ((min == 0) && (max == 0))
  8779. return (NULL);
  8780. return ((xmlSchemaTreeItemPtr) item);
  8781. }
  8782. /**
  8783. * xmlSchemaParseModelGroupDefinition:
  8784. * @ctxt: a schema validation context
  8785. * @schema: the schema being built
  8786. * @node: a subtree containing XML Schema information
  8787. *
  8788. * Parses a XML schema model group definition.
  8789. *
  8790. * Note that the constraint src-redefine (6.2) can't be applied until
  8791. * references have been resolved. So we will do this at the
  8792. * component fixup level.
  8793. *
  8794. * *WARNING* this interface is highly subject to change
  8795. *
  8796. * Returns -1 in case of error, 0 if the declaration is improper and
  8797. * 1 in case of success.
  8798. */
  8799. static xmlSchemaModelGroupDefPtr
  8800. xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  8801. xmlSchemaPtr schema,
  8802. xmlNodePtr node)
  8803. {
  8804. xmlSchemaModelGroupDefPtr item;
  8805. xmlNodePtr child = NULL;
  8806. xmlAttrPtr attr;
  8807. const xmlChar *name;
  8808. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8809. return (NULL);
  8810. attr = xmlSchemaGetPropNode(node, "name");
  8811. if (attr == NULL) {
  8812. xmlSchemaPMissingAttrErr(ctxt,
  8813. XML_SCHEMAP_S4S_ATTR_MISSING,
  8814. NULL, node,
  8815. "name", NULL);
  8816. return (NULL);
  8817. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8818. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  8819. return (NULL);
  8820. }
  8821. item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
  8822. ctxt->targetNamespace, node);
  8823. if (item == NULL)
  8824. return (NULL);
  8825. /*
  8826. * Check for illegal attributes.
  8827. */
  8828. attr = node->properties;
  8829. while (attr != NULL) {
  8830. if (attr->ns == NULL) {
  8831. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8832. (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  8833. xmlSchemaPIllegalAttrErr(ctxt,
  8834. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8835. }
  8836. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8837. xmlSchemaPIllegalAttrErr(ctxt,
  8838. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8839. }
  8840. attr = attr->next;
  8841. }
  8842. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8843. /*
  8844. * And now for the children...
  8845. */
  8846. child = node->children;
  8847. if (IS_SCHEMA(child, "annotation")) {
  8848. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8849. child = child->next;
  8850. }
  8851. if (IS_SCHEMA(child, "all")) {
  8852. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8853. XML_SCHEMA_TYPE_ALL, 0);
  8854. child = child->next;
  8855. } else if (IS_SCHEMA(child, "choice")) {
  8856. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8857. XML_SCHEMA_TYPE_CHOICE, 0);
  8858. child = child->next;
  8859. } else if (IS_SCHEMA(child, "sequence")) {
  8860. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8861. XML_SCHEMA_TYPE_SEQUENCE, 0);
  8862. child = child->next;
  8863. }
  8864. if (child != NULL) {
  8865. xmlSchemaPContentErr(ctxt,
  8866. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8867. NULL, node, child, NULL,
  8868. "(annotation?, (all | choice | sequence)?)");
  8869. }
  8870. return (item);
  8871. }
  8872. /**
  8873. * xmlSchemaCleanupDoc:
  8874. * @ctxt: a schema validation context
  8875. * @node: the root of the document.
  8876. *
  8877. * removes unwanted nodes in a schemas document tree
  8878. */
  8879. static void
  8880. xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
  8881. {
  8882. xmlNodePtr delete, cur;
  8883. if ((ctxt == NULL) || (root == NULL)) return;
  8884. /*
  8885. * Remove all the blank text nodes
  8886. */
  8887. delete = NULL;
  8888. cur = root;
  8889. while (cur != NULL) {
  8890. if (delete != NULL) {
  8891. xmlUnlinkNode(delete);
  8892. xmlFreeNode(delete);
  8893. delete = NULL;
  8894. }
  8895. if (cur->type == XML_TEXT_NODE) {
  8896. if (IS_BLANK_NODE(cur)) {
  8897. if (xmlNodeGetSpacePreserve(cur) != 1) {
  8898. delete = cur;
  8899. }
  8900. }
  8901. } else if ((cur->type != XML_ELEMENT_NODE) &&
  8902. (cur->type != XML_CDATA_SECTION_NODE)) {
  8903. delete = cur;
  8904. goto skip_children;
  8905. }
  8906. /*
  8907. * Skip to next node
  8908. */
  8909. if (cur->children != NULL) {
  8910. if ((cur->children->type != XML_ENTITY_DECL) &&
  8911. (cur->children->type != XML_ENTITY_REF_NODE) &&
  8912. (cur->children->type != XML_ENTITY_NODE)) {
  8913. cur = cur->children;
  8914. continue;
  8915. }
  8916. }
  8917. skip_children:
  8918. if (cur->next != NULL) {
  8919. cur = cur->next;
  8920. continue;
  8921. }
  8922. do {
  8923. cur = cur->parent;
  8924. if (cur == NULL)
  8925. break;
  8926. if (cur == root) {
  8927. cur = NULL;
  8928. break;
  8929. }
  8930. if (cur->next != NULL) {
  8931. cur = cur->next;
  8932. break;
  8933. }
  8934. } while (cur != NULL);
  8935. }
  8936. if (delete != NULL) {
  8937. xmlUnlinkNode(delete);
  8938. xmlFreeNode(delete);
  8939. delete = NULL;
  8940. }
  8941. }
  8942. static void
  8943. xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
  8944. {
  8945. if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8946. schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
  8947. if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
  8948. schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
  8949. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8950. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
  8951. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8952. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
  8953. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8954. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
  8955. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8956. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
  8957. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8958. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
  8959. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8960. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
  8961. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8962. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
  8963. }
  8964. static int
  8965. xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
  8966. xmlSchemaPtr schema,
  8967. xmlNodePtr node)
  8968. {
  8969. xmlAttrPtr attr;
  8970. const xmlChar *val;
  8971. int res = 0, oldErrs = ctxt->nberrors;
  8972. /*
  8973. * Those flags should be moved to the parser context flags,
  8974. * since they are not visible at the component level. I.e.
  8975. * they are used if processing schema *documents* only.
  8976. */
  8977. res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8978. HFAILURE;
  8979. /*
  8980. * Since the version is of type xs:token, we won't bother to
  8981. * check it.
  8982. */
  8983. /* REMOVED:
  8984. attr = xmlSchemaGetPropNode(node, "version");
  8985. if (attr != NULL) {
  8986. res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
  8987. xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
  8988. HFAILURE;
  8989. }
  8990. */
  8991. attr = xmlSchemaGetPropNode(node, "targetNamespace");
  8992. if (attr != NULL) {
  8993. res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8994. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  8995. HFAILURE;
  8996. if (res != 0) {
  8997. ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  8998. goto exit;
  8999. }
  9000. }
  9001. attr = xmlSchemaGetPropNode(node, "elementFormDefault");
  9002. if (attr != NULL) {
  9003. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9004. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9005. XML_SCHEMAS_QUALIF_ELEM);
  9006. HFAILURE;
  9007. if (res != 0) {
  9008. xmlSchemaPSimpleTypeErr(ctxt,
  9009. XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
  9010. NULL, (xmlNodePtr) attr, NULL,
  9011. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9012. }
  9013. }
  9014. attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
  9015. if (attr != NULL) {
  9016. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9017. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9018. XML_SCHEMAS_QUALIF_ATTR);
  9019. HFAILURE;
  9020. if (res != 0) {
  9021. xmlSchemaPSimpleTypeErr(ctxt,
  9022. XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
  9023. NULL, (xmlNodePtr) attr, NULL,
  9024. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9025. }
  9026. }
  9027. attr = xmlSchemaGetPropNode(node, "finalDefault");
  9028. if (attr != NULL) {
  9029. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9030. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9031. XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
  9032. XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
  9033. -1,
  9034. XML_SCHEMAS_FINAL_DEFAULT_LIST,
  9035. XML_SCHEMAS_FINAL_DEFAULT_UNION);
  9036. HFAILURE;
  9037. if (res != 0) {
  9038. xmlSchemaPSimpleTypeErr(ctxt,
  9039. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9040. NULL, (xmlNodePtr) attr, NULL,
  9041. "(#all | List of (extension | restriction | list | union))",
  9042. val, NULL, NULL, NULL);
  9043. }
  9044. }
  9045. attr = xmlSchemaGetPropNode(node, "blockDefault");
  9046. if (attr != NULL) {
  9047. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9048. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9049. XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
  9050. XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
  9051. XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
  9052. HFAILURE;
  9053. if (res != 0) {
  9054. xmlSchemaPSimpleTypeErr(ctxt,
  9055. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9056. NULL, (xmlNodePtr) attr, NULL,
  9057. "(#all | List of (extension | restriction | substitution))",
  9058. val, NULL, NULL, NULL);
  9059. }
  9060. }
  9061. exit:
  9062. if (oldErrs != ctxt->nberrors)
  9063. res = ctxt->err;
  9064. return(res);
  9065. exit_failure:
  9066. return(-1);
  9067. }
  9068. /**
  9069. * xmlSchemaParseSchemaTopLevel:
  9070. * @ctxt: a schema validation context
  9071. * @schema: the schemas
  9072. * @nodes: the list of top level nodes
  9073. *
  9074. * Returns the internal XML Schema structure built from the resource or
  9075. * NULL in case of error
  9076. */
  9077. static int
  9078. xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
  9079. xmlSchemaPtr schema, xmlNodePtr nodes)
  9080. {
  9081. xmlNodePtr child;
  9082. xmlSchemaAnnotPtr annot;
  9083. int res = 0, oldErrs, tmpOldErrs;
  9084. if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
  9085. return(-1);
  9086. oldErrs = ctxt->nberrors;
  9087. child = nodes;
  9088. while ((IS_SCHEMA(child, "include")) ||
  9089. (IS_SCHEMA(child, "import")) ||
  9090. (IS_SCHEMA(child, "redefine")) ||
  9091. (IS_SCHEMA(child, "annotation"))) {
  9092. if (IS_SCHEMA(child, "annotation")) {
  9093. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9094. if (schema->annot == NULL)
  9095. schema->annot = annot;
  9096. else
  9097. xmlSchemaFreeAnnot(annot);
  9098. } else if (IS_SCHEMA(child, "import")) {
  9099. tmpOldErrs = ctxt->nberrors;
  9100. res = xmlSchemaParseImport(ctxt, schema, child);
  9101. HFAILURE;
  9102. HSTOP(ctxt);
  9103. if (tmpOldErrs != ctxt->nberrors)
  9104. goto exit;
  9105. } else if (IS_SCHEMA(child, "include")) {
  9106. tmpOldErrs = ctxt->nberrors;
  9107. res = xmlSchemaParseInclude(ctxt, schema, child);
  9108. HFAILURE;
  9109. HSTOP(ctxt);
  9110. if (tmpOldErrs != ctxt->nberrors)
  9111. goto exit;
  9112. } else if (IS_SCHEMA(child, "redefine")) {
  9113. tmpOldErrs = ctxt->nberrors;
  9114. res = xmlSchemaParseRedefine(ctxt, schema, child);
  9115. HFAILURE;
  9116. HSTOP(ctxt);
  9117. if (tmpOldErrs != ctxt->nberrors)
  9118. goto exit;
  9119. }
  9120. child = child->next;
  9121. }
  9122. /*
  9123. * URGENT TODO: Change the functions to return int results.
  9124. * We need especially to catch internal errors.
  9125. */
  9126. while (child != NULL) {
  9127. if (IS_SCHEMA(child, "complexType")) {
  9128. xmlSchemaParseComplexType(ctxt, schema, child, 1);
  9129. child = child->next;
  9130. } else if (IS_SCHEMA(child, "simpleType")) {
  9131. xmlSchemaParseSimpleType(ctxt, schema, child, 1);
  9132. child = child->next;
  9133. } else if (IS_SCHEMA(child, "element")) {
  9134. xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
  9135. child = child->next;
  9136. } else if (IS_SCHEMA(child, "attribute")) {
  9137. xmlSchemaParseGlobalAttribute(ctxt, schema, child);
  9138. child = child->next;
  9139. } else if (IS_SCHEMA(child, "attributeGroup")) {
  9140. xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
  9141. child = child->next;
  9142. } else if (IS_SCHEMA(child, "group")) {
  9143. xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
  9144. child = child->next;
  9145. } else if (IS_SCHEMA(child, "notation")) {
  9146. xmlSchemaParseNotation(ctxt, schema, child);
  9147. child = child->next;
  9148. } else {
  9149. xmlSchemaPContentErr(ctxt,
  9150. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  9151. NULL, child->parent, child,
  9152. NULL, "((include | import | redefine | annotation)*, "
  9153. "(((simpleType | complexType | group | attributeGroup) "
  9154. "| element | attribute | notation), annotation*)*)");
  9155. child = child->next;
  9156. }
  9157. while (IS_SCHEMA(child, "annotation")) {
  9158. /*
  9159. * TODO: We should add all annotations.
  9160. */
  9161. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9162. if (schema->annot == NULL)
  9163. schema->annot = annot;
  9164. else
  9165. xmlSchemaFreeAnnot(annot);
  9166. child = child->next;
  9167. }
  9168. }
  9169. exit:
  9170. ctxt->ctxtType = NULL;
  9171. if (oldErrs != ctxt->nberrors)
  9172. res = ctxt->err;
  9173. return(res);
  9174. exit_failure:
  9175. return(-1);
  9176. }
  9177. static xmlSchemaSchemaRelationPtr
  9178. xmlSchemaSchemaRelationCreate(void)
  9179. {
  9180. xmlSchemaSchemaRelationPtr ret;
  9181. ret = (xmlSchemaSchemaRelationPtr)
  9182. xmlMalloc(sizeof(xmlSchemaSchemaRelation));
  9183. if (ret == NULL) {
  9184. xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
  9185. return(NULL);
  9186. }
  9187. memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
  9188. return(ret);
  9189. }
  9190. #if 0
  9191. static void
  9192. xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
  9193. {
  9194. xmlFree(rel);
  9195. }
  9196. #endif
  9197. static void
  9198. xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
  9199. {
  9200. xmlSchemaRedefPtr prev;
  9201. while (redef != NULL) {
  9202. prev = redef;
  9203. redef = redef->next;
  9204. xmlFree(prev);
  9205. }
  9206. }
  9207. static void
  9208. xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
  9209. {
  9210. /*
  9211. * After the construction context has been freed, there will be
  9212. * no schema graph available any more. Only the schema buckets
  9213. * will stay alive, which are put into the "schemasImports" and
  9214. * "includes" slots of the xmlSchema.
  9215. */
  9216. if (con->buckets != NULL)
  9217. xmlSchemaItemListFree(con->buckets);
  9218. if (con->pending != NULL)
  9219. xmlSchemaItemListFree(con->pending);
  9220. if (con->substGroups != NULL)
  9221. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  9222. if (con->redefs != NULL)
  9223. xmlSchemaRedefListFree(con->redefs);
  9224. if (con->dict != NULL)
  9225. xmlDictFree(con->dict);
  9226. xmlFree(con);
  9227. }
  9228. static xmlSchemaConstructionCtxtPtr
  9229. xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
  9230. {
  9231. xmlSchemaConstructionCtxtPtr ret;
  9232. ret = (xmlSchemaConstructionCtxtPtr)
  9233. xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
  9234. if (ret == NULL) {
  9235. xmlSchemaPErrMemory(NULL,
  9236. "allocating schema construction context", NULL);
  9237. return (NULL);
  9238. }
  9239. memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
  9240. ret->buckets = xmlSchemaItemListCreate();
  9241. if (ret->buckets == NULL) {
  9242. xmlSchemaPErrMemory(NULL,
  9243. "allocating list of schema buckets", NULL);
  9244. xmlFree(ret);
  9245. return (NULL);
  9246. }
  9247. ret->pending = xmlSchemaItemListCreate();
  9248. if (ret->pending == NULL) {
  9249. xmlSchemaPErrMemory(NULL,
  9250. "allocating list of pending global components", NULL);
  9251. xmlSchemaConstructionCtxtFree(ret);
  9252. return (NULL);
  9253. }
  9254. ret->dict = dict;
  9255. xmlDictReference(dict);
  9256. return(ret);
  9257. }
  9258. static xmlSchemaParserCtxtPtr
  9259. xmlSchemaParserCtxtCreate(void)
  9260. {
  9261. xmlSchemaParserCtxtPtr ret;
  9262. ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
  9263. if (ret == NULL) {
  9264. xmlSchemaPErrMemory(NULL, "allocating schema parser context",
  9265. NULL);
  9266. return (NULL);
  9267. }
  9268. memset(ret, 0, sizeof(xmlSchemaParserCtxt));
  9269. ret->type = XML_SCHEMA_CTXT_PARSER;
  9270. ret->attrProhibs = xmlSchemaItemListCreate();
  9271. if (ret->attrProhibs == NULL) {
  9272. xmlFree(ret);
  9273. return(NULL);
  9274. }
  9275. return(ret);
  9276. }
  9277. /**
  9278. * xmlSchemaNewParserCtxtUseDict:
  9279. * @URL: the location of the schema
  9280. * @dict: the dictionary to be used
  9281. *
  9282. * Create an XML Schemas parse context for that file/resource expected
  9283. * to contain an XML Schemas file.
  9284. *
  9285. * Returns the parser context or NULL in case of error
  9286. */
  9287. static xmlSchemaParserCtxtPtr
  9288. xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
  9289. {
  9290. xmlSchemaParserCtxtPtr ret;
  9291. ret = xmlSchemaParserCtxtCreate();
  9292. if (ret == NULL)
  9293. return (NULL);
  9294. ret->dict = dict;
  9295. xmlDictReference(dict);
  9296. if (URL != NULL)
  9297. ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
  9298. return (ret);
  9299. }
  9300. static int
  9301. xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
  9302. {
  9303. if (vctxt->pctxt == NULL) {
  9304. if (vctxt->schema != NULL)
  9305. vctxt->pctxt =
  9306. xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
  9307. else
  9308. vctxt->pctxt = xmlSchemaNewParserCtxt("*");
  9309. if (vctxt->pctxt == NULL) {
  9310. VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
  9311. "failed to create a temp. parser context");
  9312. return (-1);
  9313. }
  9314. /* TODO: Pass user data. */
  9315. xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
  9316. vctxt->warning, vctxt->errCtxt);
  9317. xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
  9318. vctxt->errCtxt);
  9319. }
  9320. return (0);
  9321. }
  9322. /**
  9323. * xmlSchemaGetSchemaBucket:
  9324. * @pctxt: the schema parser context
  9325. * @schemaLocation: the URI of the schema document
  9326. *
  9327. * Returns a schema bucket if it was already parsed.
  9328. *
  9329. * Returns a schema bucket if it was already parsed from
  9330. * @schemaLocation, NULL otherwise.
  9331. */
  9332. static xmlSchemaBucketPtr
  9333. xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9334. const xmlChar *schemaLocation)
  9335. {
  9336. xmlSchemaBucketPtr cur;
  9337. xmlSchemaItemListPtr list;
  9338. list = pctxt->constructor->buckets;
  9339. if (list->nbItems == 0)
  9340. return(NULL);
  9341. else {
  9342. int i;
  9343. for (i = 0; i < list->nbItems; i++) {
  9344. cur = (xmlSchemaBucketPtr) list->items[i];
  9345. /* Pointer comparison! */
  9346. if (cur->schemaLocation == schemaLocation)
  9347. return(cur);
  9348. }
  9349. }
  9350. return(NULL);
  9351. }
  9352. static xmlSchemaBucketPtr
  9353. xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9354. const xmlChar *schemaLocation,
  9355. const xmlChar *targetNamespace)
  9356. {
  9357. xmlSchemaBucketPtr cur;
  9358. xmlSchemaItemListPtr list;
  9359. list = pctxt->constructor->buckets;
  9360. if (list->nbItems == 0)
  9361. return(NULL);
  9362. else {
  9363. int i;
  9364. for (i = 0; i < list->nbItems; i++) {
  9365. cur = (xmlSchemaBucketPtr) list->items[i];
  9366. /* Pointer comparison! */
  9367. if ((cur->origTargetNamespace == NULL) &&
  9368. (cur->schemaLocation == schemaLocation) &&
  9369. (cur->targetNamespace == targetNamespace))
  9370. return(cur);
  9371. }
  9372. }
  9373. return(NULL);
  9374. }
  9375. #define IS_BAD_SCHEMA_DOC(b) \
  9376. (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
  9377. static xmlSchemaBucketPtr
  9378. xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
  9379. const xmlChar *targetNamespace,
  9380. int imported)
  9381. {
  9382. xmlSchemaBucketPtr cur;
  9383. xmlSchemaItemListPtr list;
  9384. list = pctxt->constructor->buckets;
  9385. if (list->nbItems == 0)
  9386. return(NULL);
  9387. else {
  9388. int i;
  9389. for (i = 0; i < list->nbItems; i++) {
  9390. cur = (xmlSchemaBucketPtr) list->items[i];
  9391. if ((! IS_BAD_SCHEMA_DOC(cur)) &&
  9392. (cur->origTargetNamespace == targetNamespace) &&
  9393. ((imported && cur->imported) ||
  9394. ((!imported) && (!cur->imported))))
  9395. return(cur);
  9396. }
  9397. }
  9398. return(NULL);
  9399. }
  9400. static int
  9401. xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
  9402. xmlSchemaPtr schema,
  9403. xmlSchemaBucketPtr bucket)
  9404. {
  9405. int oldFlags;
  9406. xmlDocPtr oldDoc;
  9407. xmlNodePtr node;
  9408. int ret, oldErrs;
  9409. xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
  9410. /*
  9411. * Save old values; reset the *main* schema.
  9412. * URGENT TODO: This is not good; move the per-document information
  9413. * to the parser. Get rid of passing the main schema to the
  9414. * parsing functions.
  9415. */
  9416. oldFlags = schema->flags;
  9417. oldDoc = schema->doc;
  9418. if (schema->flags != 0)
  9419. xmlSchemaClearSchemaDefaults(schema);
  9420. schema->doc = bucket->doc;
  9421. pctxt->schema = schema;
  9422. /*
  9423. * Keep the current target namespace on the parser *not* on the
  9424. * main schema.
  9425. */
  9426. pctxt->targetNamespace = bucket->targetNamespace;
  9427. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  9428. if ((bucket->targetNamespace != NULL) &&
  9429. xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
  9430. /*
  9431. * We are parsing the schema for schemas!
  9432. */
  9433. pctxt->isS4S = 1;
  9434. }
  9435. /* Mark it as parsed, even if parsing fails. */
  9436. bucket->parsed++;
  9437. /* Compile the schema doc. */
  9438. node = xmlDocGetRootElement(bucket->doc);
  9439. ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
  9440. if (ret != 0)
  9441. goto exit;
  9442. /* An empty schema; just get out. */
  9443. if (node->children == NULL)
  9444. goto exit;
  9445. oldErrs = pctxt->nberrors;
  9446. ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
  9447. if (ret != 0)
  9448. goto exit;
  9449. /*
  9450. * TODO: Not nice, but I'm not 100% sure we will get always an error
  9451. * as a result of the above functions; so better rely on pctxt->err
  9452. * as well.
  9453. */
  9454. if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
  9455. ret = pctxt->err;
  9456. goto exit;
  9457. }
  9458. exit:
  9459. WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
  9460. /* Restore schema values. */
  9461. schema->doc = oldDoc;
  9462. schema->flags = oldFlags;
  9463. return(ret);
  9464. }
  9465. static int
  9466. xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
  9467. xmlSchemaPtr schema,
  9468. xmlSchemaBucketPtr bucket)
  9469. {
  9470. xmlSchemaParserCtxtPtr newpctxt;
  9471. int res = 0;
  9472. if (bucket == NULL)
  9473. return(0);
  9474. if (bucket->parsed) {
  9475. PERROR_INT("xmlSchemaParseNewDoc",
  9476. "reparsing a schema doc");
  9477. return(-1);
  9478. }
  9479. if (bucket->doc == NULL) {
  9480. PERROR_INT("xmlSchemaParseNewDoc",
  9481. "parsing a schema doc, but there's no doc");
  9482. return(-1);
  9483. }
  9484. if (pctxt->constructor == NULL) {
  9485. PERROR_INT("xmlSchemaParseNewDoc",
  9486. "no constructor");
  9487. return(-1);
  9488. }
  9489. /* Create and init the temporary parser context. */
  9490. newpctxt = xmlSchemaNewParserCtxtUseDict(
  9491. (const char *) bucket->schemaLocation, pctxt->dict);
  9492. if (newpctxt == NULL)
  9493. return(-1);
  9494. newpctxt->constructor = pctxt->constructor;
  9495. /*
  9496. * TODO: Can we avoid that the parser knows about the main schema?
  9497. * It would be better if he knows about the current schema bucket
  9498. * only.
  9499. */
  9500. newpctxt->schema = schema;
  9501. xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
  9502. pctxt->errCtxt);
  9503. xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
  9504. pctxt->errCtxt);
  9505. newpctxt->counter = pctxt->counter;
  9506. res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
  9507. /* Channel back errors and cleanup the temporary parser context. */
  9508. if (res != 0)
  9509. pctxt->err = res;
  9510. pctxt->nberrors += newpctxt->nberrors;
  9511. pctxt->counter = newpctxt->counter;
  9512. newpctxt->constructor = NULL;
  9513. /* Free the parser context. */
  9514. xmlSchemaFreeParserCtxt(newpctxt);
  9515. return(res);
  9516. }
  9517. static void
  9518. xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
  9519. xmlSchemaSchemaRelationPtr rel)
  9520. {
  9521. xmlSchemaSchemaRelationPtr cur = bucket->relations;
  9522. if (cur == NULL) {
  9523. bucket->relations = rel;
  9524. return;
  9525. }
  9526. while (cur->next != NULL)
  9527. cur = cur->next;
  9528. cur->next = rel;
  9529. }
  9530. static const xmlChar *
  9531. xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
  9532. xmlNodePtr ctxtNode)
  9533. {
  9534. /*
  9535. * Build an absolute location URI.
  9536. */
  9537. if (location != NULL) {
  9538. if (ctxtNode == NULL)
  9539. return(location);
  9540. else {
  9541. xmlChar *base, *URI;
  9542. const xmlChar *ret = NULL;
  9543. base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
  9544. if (base == NULL) {
  9545. URI = xmlBuildURI(location, ctxtNode->doc->URL);
  9546. } else {
  9547. URI = xmlBuildURI(location, base);
  9548. xmlFree(base);
  9549. }
  9550. if (URI != NULL) {
  9551. ret = xmlDictLookup(dict, URI, -1);
  9552. xmlFree(URI);
  9553. return(ret);
  9554. }
  9555. }
  9556. }
  9557. return(NULL);
  9558. }
  9559. /**
  9560. * xmlSchemaAddSchemaDoc:
  9561. * @pctxt: a schema validation context
  9562. * @schema: the schema being built
  9563. * @node: a subtree containing XML Schema information
  9564. *
  9565. * Parse an included (and to-be-redefined) XML schema document.
  9566. *
  9567. * Returns 0 on success, a positive error code on errors and
  9568. * -1 in case of an internal or API error.
  9569. */
  9570. static int
  9571. xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
  9572. int type, /* import or include or redefine */
  9573. const xmlChar *schemaLocation,
  9574. xmlDocPtr schemaDoc,
  9575. const char *schemaBuffer,
  9576. int schemaBufferLen,
  9577. xmlNodePtr invokingNode,
  9578. const xmlChar *sourceTargetNamespace,
  9579. const xmlChar *importNamespace,
  9580. xmlSchemaBucketPtr *bucket)
  9581. {
  9582. const xmlChar *targetNamespace = NULL;
  9583. xmlSchemaSchemaRelationPtr relation = NULL;
  9584. xmlDocPtr doc = NULL;
  9585. int res = 0, err = 0, located = 0, preserveDoc = 0;
  9586. xmlSchemaBucketPtr bkt = NULL;
  9587. if (bucket != NULL)
  9588. *bucket = NULL;
  9589. switch (type) {
  9590. case XML_SCHEMA_SCHEMA_IMPORT:
  9591. case XML_SCHEMA_SCHEMA_MAIN:
  9592. err = XML_SCHEMAP_SRC_IMPORT;
  9593. break;
  9594. case XML_SCHEMA_SCHEMA_INCLUDE:
  9595. err = XML_SCHEMAP_SRC_INCLUDE;
  9596. break;
  9597. case XML_SCHEMA_SCHEMA_REDEFINE:
  9598. err = XML_SCHEMAP_SRC_REDEFINE;
  9599. break;
  9600. }
  9601. /* Special handling for the main schema:
  9602. * skip the location and relation logic and just parse the doc.
  9603. * We need just a bucket to be returned in this case.
  9604. */
  9605. if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
  9606. goto doc_load;
  9607. /* Note that we expect the location to be an absolute URI. */
  9608. if (schemaLocation != NULL) {
  9609. bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
  9610. if ((bkt != NULL) &&
  9611. (pctxt->constructor->bucket == bkt)) {
  9612. /* Report self-imports/inclusions/redefinitions. */
  9613. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9614. invokingNode, NULL,
  9615. "The schema must not import/include/redefine itself",
  9616. NULL, NULL);
  9617. goto exit;
  9618. }
  9619. }
  9620. /*
  9621. * Create a relation for the graph of schemas.
  9622. */
  9623. relation = xmlSchemaSchemaRelationCreate();
  9624. if (relation == NULL)
  9625. return(-1);
  9626. xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
  9627. relation);
  9628. relation->type = type;
  9629. /*
  9630. * Save the namespace import information.
  9631. */
  9632. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9633. relation->importNamespace = importNamespace;
  9634. if (schemaLocation == NULL) {
  9635. /*
  9636. * No location; this is just an import of the namespace.
  9637. * Note that we don't assign a bucket to the relation
  9638. * in this case.
  9639. */
  9640. goto exit;
  9641. }
  9642. targetNamespace = importNamespace;
  9643. }
  9644. /* Did we already fetch the doc? */
  9645. if (bkt != NULL) {
  9646. if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
  9647. /*
  9648. * We included/redefined and then try to import a schema,
  9649. * but the new location provided for import was different.
  9650. */
  9651. if (schemaLocation == NULL)
  9652. schemaLocation = BAD_CAST "in_memory_buffer";
  9653. if (!xmlStrEqual(schemaLocation,
  9654. bkt->schemaLocation)) {
  9655. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9656. invokingNode, NULL,
  9657. "The schema document '%s' cannot be imported, since "
  9658. "it was already included or redefined",
  9659. schemaLocation, NULL);
  9660. goto exit;
  9661. }
  9662. } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
  9663. /*
  9664. * We imported and then try to include/redefine a schema,
  9665. * but the new location provided for the include/redefine
  9666. * was different.
  9667. */
  9668. if (schemaLocation == NULL)
  9669. schemaLocation = BAD_CAST "in_memory_buffer";
  9670. if (!xmlStrEqual(schemaLocation,
  9671. bkt->schemaLocation)) {
  9672. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9673. invokingNode, NULL,
  9674. "The schema document '%s' cannot be included or "
  9675. "redefined, since it was already imported",
  9676. schemaLocation, NULL);
  9677. goto exit;
  9678. }
  9679. }
  9680. }
  9681. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9682. /*
  9683. * Given that the schemaLocation [attribute] is only a hint, it is open
  9684. * to applications to ignore all but the first <import> for a given
  9685. * namespace, regardless of the `actual value` of schemaLocation, but
  9686. * such a strategy risks missing useful information when new
  9687. * schemaLocations are offered.
  9688. *
  9689. * We will use the first <import> that comes with a location.
  9690. * Further <import>s *with* a location, will result in an error.
  9691. * TODO: Better would be to just report a warning here, but
  9692. * we'll try it this way until someone complains.
  9693. *
  9694. * Schema Document Location Strategy:
  9695. * 3 Based on the namespace name, identify an existing schema document,
  9696. * either as a resource which is an XML document or a <schema> element
  9697. * information item, in some local schema repository;
  9698. * 5 Attempt to resolve the namespace name to locate such a resource.
  9699. *
  9700. * NOTE: (3) and (5) are not supported.
  9701. */
  9702. if (bkt != NULL) {
  9703. relation->bucket = bkt;
  9704. goto exit;
  9705. }
  9706. bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
  9707. importNamespace, 1);
  9708. if (bkt != NULL) {
  9709. relation->bucket = bkt;
  9710. if (bkt->schemaLocation == NULL) {
  9711. /* First given location of the schema; load the doc. */
  9712. bkt->schemaLocation = schemaLocation;
  9713. } else {
  9714. if (!xmlStrEqual(schemaLocation,
  9715. bkt->schemaLocation)) {
  9716. /*
  9717. * Additional location given; just skip it.
  9718. * URGENT TODO: We should report a warning here.
  9719. * res = XML_SCHEMAP_SRC_IMPORT;
  9720. */
  9721. if (schemaLocation == NULL)
  9722. schemaLocation = BAD_CAST "in_memory_buffer";
  9723. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  9724. XML_SCHEMAP_WARN_SKIP_SCHEMA,
  9725. invokingNode, NULL,
  9726. "Skipping import of schema located at '%s' for the "
  9727. "namespace '%s', since this namespace was already "
  9728. "imported with the schema located at '%s'",
  9729. schemaLocation, importNamespace, bkt->schemaLocation);
  9730. }
  9731. goto exit;
  9732. }
  9733. }
  9734. /*
  9735. * No bucket + first location: load the doc and create a
  9736. * bucket.
  9737. */
  9738. } else {
  9739. /* <include> and <redefine> */
  9740. if (bkt != NULL) {
  9741. if ((bkt->origTargetNamespace == NULL) &&
  9742. (bkt->targetNamespace != sourceTargetNamespace)) {
  9743. xmlSchemaBucketPtr chamel;
  9744. /*
  9745. * Chameleon include/redefine: skip loading only if it was
  9746. * already build for the targetNamespace of the including
  9747. * schema.
  9748. */
  9749. /*
  9750. * URGENT TODO: If the schema is a chameleon-include then copy
  9751. * the components into the including schema and modify the
  9752. * targetNamespace of those components, do nothing otherwise.
  9753. * NOTE: This is currently worked-around by compiling the
  9754. * chameleon for every distinct including targetNamespace; thus
  9755. * not performant at the moment.
  9756. * TODO: Check when the namespace in wildcards for chameleons
  9757. * needs to be converted: before we built wildcard intersections
  9758. * or after.
  9759. * Answer: after!
  9760. */
  9761. chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
  9762. schemaLocation, sourceTargetNamespace);
  9763. if (chamel != NULL) {
  9764. /* A fitting chameleon was already parsed; NOP. */
  9765. relation->bucket = chamel;
  9766. goto exit;
  9767. }
  9768. /*
  9769. * We need to parse the chameleon again for a different
  9770. * targetNamespace.
  9771. * CHAMELEON TODO: Optimize this by only parsing the
  9772. * chameleon once, and then copying the components to
  9773. * the new targetNamespace.
  9774. */
  9775. bkt = NULL;
  9776. } else {
  9777. relation->bucket = bkt;
  9778. goto exit;
  9779. }
  9780. }
  9781. }
  9782. if ((bkt != NULL) && (bkt->doc != NULL)) {
  9783. PERROR_INT("xmlSchemaAddSchemaDoc",
  9784. "trying to load a schema doc, but a doc is already "
  9785. "assigned to the schema bucket");
  9786. goto exit_failure;
  9787. }
  9788. doc_load:
  9789. /*
  9790. * Load the document.
  9791. */
  9792. if (schemaDoc != NULL) {
  9793. doc = schemaDoc;
  9794. /* Don' free this one, since it was provided by the caller. */
  9795. preserveDoc = 1;
  9796. /* TODO: Does the context or the doc hold the location? */
  9797. if (schemaDoc->URL != NULL)
  9798. schemaLocation = xmlDictLookup(pctxt->dict,
  9799. schemaDoc->URL, -1);
  9800. else
  9801. schemaLocation = BAD_CAST "in_memory_buffer";
  9802. } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
  9803. xmlParserCtxtPtr parserCtxt;
  9804. parserCtxt = xmlNewParserCtxt();
  9805. if (parserCtxt == NULL) {
  9806. xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
  9807. "allocating a parser context", NULL);
  9808. goto exit_failure;
  9809. }
  9810. if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
  9811. /*
  9812. * TODO: Do we have to burden the schema parser dict with all
  9813. * the content of the schema doc?
  9814. */
  9815. xmlDictFree(parserCtxt->dict);
  9816. parserCtxt->dict = pctxt->dict;
  9817. xmlDictReference(parserCtxt->dict);
  9818. }
  9819. if (schemaLocation != NULL) {
  9820. /* Parse from file. */
  9821. doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
  9822. NULL, SCHEMAS_PARSE_OPTIONS);
  9823. } else if (schemaBuffer != NULL) {
  9824. /* Parse from memory buffer. */
  9825. doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
  9826. NULL, NULL, SCHEMAS_PARSE_OPTIONS);
  9827. schemaLocation = BAD_CAST "in_memory_buffer";
  9828. if (doc != NULL)
  9829. doc->URL = xmlStrdup(schemaLocation);
  9830. }
  9831. /*
  9832. * For <import>:
  9833. * 2.1 The referent is (a fragment of) a resource which is an
  9834. * XML document (see clause 1.1), which in turn corresponds to
  9835. * a <schema> element information item in a well-formed information
  9836. * set, which in turn corresponds to a valid schema.
  9837. * TODO: (2.1) fragments of XML documents are not supported.
  9838. *
  9839. * 2.2 The referent is a <schema> element information item in
  9840. * a well-formed information set, which in turn corresponds
  9841. * to a valid schema.
  9842. * TODO: (2.2) is not supported.
  9843. */
  9844. if (doc == NULL) {
  9845. const xmlError *lerr;
  9846. lerr = xmlGetLastError();
  9847. /*
  9848. * Check if this a parser error, or if the document could
  9849. * just not be located.
  9850. * TODO: Try to find specific error codes to react only on
  9851. * localisation failures.
  9852. */
  9853. if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
  9854. /*
  9855. * We assume a parser error here.
  9856. */
  9857. located = 1;
  9858. /* TODO: Error code ?? */
  9859. res = XML_SCHEMAP_SRC_IMPORT_2_1;
  9860. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  9861. invokingNode, NULL,
  9862. "Failed to parse the XML resource '%s'",
  9863. schemaLocation, NULL);
  9864. }
  9865. }
  9866. xmlFreeParserCtxt(parserCtxt);
  9867. if ((doc == NULL) && located)
  9868. goto exit_error;
  9869. } else {
  9870. xmlSchemaPErr(pctxt, NULL,
  9871. XML_SCHEMAP_NOTHING_TO_PARSE,
  9872. "No information for parsing was provided with the "
  9873. "given schema parser context.\n",
  9874. NULL, NULL);
  9875. goto exit_failure;
  9876. }
  9877. /*
  9878. * Preprocess the document.
  9879. */
  9880. if (doc != NULL) {
  9881. xmlNodePtr docElem = NULL;
  9882. located = 1;
  9883. docElem = xmlDocGetRootElement(doc);
  9884. if (docElem == NULL) {
  9885. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
  9886. invokingNode, NULL,
  9887. "The document '%s' has no document element",
  9888. schemaLocation, NULL);
  9889. goto exit_error;
  9890. }
  9891. /*
  9892. * Remove all the blank text nodes.
  9893. */
  9894. xmlSchemaCleanupDoc(pctxt, docElem);
  9895. /*
  9896. * Check the schema's top level element.
  9897. */
  9898. if (!IS_SCHEMA(docElem, "schema")) {
  9899. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
  9900. invokingNode, NULL,
  9901. "The XML document '%s' is not a schema document",
  9902. schemaLocation, NULL);
  9903. goto exit_error;
  9904. }
  9905. /*
  9906. * Note that we don't apply a type check for the
  9907. * targetNamespace value here.
  9908. */
  9909. targetNamespace = xmlSchemaGetProp(pctxt, docElem,
  9910. "targetNamespace");
  9911. }
  9912. /* after_doc_loading: */
  9913. if ((bkt == NULL) && located) {
  9914. /* Only create a bucket if the schema was located. */
  9915. bkt = xmlSchemaBucketCreate(pctxt, type,
  9916. targetNamespace);
  9917. if (bkt == NULL)
  9918. goto exit_failure;
  9919. }
  9920. if (bkt != NULL) {
  9921. bkt->schemaLocation = schemaLocation;
  9922. bkt->located = located;
  9923. if (doc != NULL) {
  9924. bkt->doc = doc;
  9925. bkt->targetNamespace = targetNamespace;
  9926. bkt->origTargetNamespace = targetNamespace;
  9927. if (preserveDoc)
  9928. bkt->preserveDoc = 1;
  9929. }
  9930. if (WXS_IS_BUCKET_IMPMAIN(type))
  9931. bkt->imported++;
  9932. /*
  9933. * Add it to the graph of schemas.
  9934. */
  9935. if (relation != NULL)
  9936. relation->bucket = bkt;
  9937. }
  9938. exit:
  9939. /*
  9940. * Return the bucket explicitly; this is needed for the
  9941. * main schema.
  9942. */
  9943. if (bucket != NULL)
  9944. *bucket = bkt;
  9945. return (0);
  9946. exit_error:
  9947. if ((doc != NULL) && (! preserveDoc)) {
  9948. xmlFreeDoc(doc);
  9949. if (bkt != NULL)
  9950. bkt->doc = NULL;
  9951. }
  9952. return(pctxt->err);
  9953. exit_failure:
  9954. if ((doc != NULL) && (! preserveDoc)) {
  9955. xmlFreeDoc(doc);
  9956. if (bkt != NULL)
  9957. bkt->doc = NULL;
  9958. }
  9959. return (-1);
  9960. }
  9961. /**
  9962. * xmlSchemaParseImport:
  9963. * @ctxt: a schema validation context
  9964. * @schema: the schema being built
  9965. * @node: a subtree containing XML Schema information
  9966. *
  9967. * parse a XML schema Import definition
  9968. * *WARNING* this interface is highly subject to change
  9969. *
  9970. * Returns 0 in case of success, a positive error code if
  9971. * not valid and -1 in case of an internal error.
  9972. */
  9973. static int
  9974. xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  9975. xmlNodePtr node)
  9976. {
  9977. xmlNodePtr child;
  9978. const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
  9979. const xmlChar *thisTargetNamespace;
  9980. xmlAttrPtr attr;
  9981. int ret = 0;
  9982. xmlSchemaBucketPtr bucket = NULL;
  9983. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  9984. return (-1);
  9985. /*
  9986. * Check for illegal attributes.
  9987. */
  9988. attr = node->properties;
  9989. while (attr != NULL) {
  9990. if (attr->ns == NULL) {
  9991. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  9992. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  9993. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  9994. xmlSchemaPIllegalAttrErr(pctxt,
  9995. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  9996. }
  9997. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  9998. xmlSchemaPIllegalAttrErr(pctxt,
  9999. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10000. }
  10001. attr = attr->next;
  10002. }
  10003. /*
  10004. * Extract and validate attributes.
  10005. */
  10006. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10007. "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10008. &namespaceName) != 0) {
  10009. xmlSchemaPSimpleTypeErr(pctxt,
  10010. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10011. NULL, node,
  10012. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10013. NULL, namespaceName, NULL, NULL, NULL);
  10014. return (pctxt->err);
  10015. }
  10016. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10017. "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10018. &schemaLocation) != 0) {
  10019. xmlSchemaPSimpleTypeErr(pctxt,
  10020. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10021. NULL, node,
  10022. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10023. NULL, schemaLocation, NULL, NULL, NULL);
  10024. return (pctxt->err);
  10025. }
  10026. /*
  10027. * And now for the children...
  10028. */
  10029. child = node->children;
  10030. if (IS_SCHEMA(child, "annotation")) {
  10031. /*
  10032. * the annotation here is simply discarded ...
  10033. * TODO: really?
  10034. */
  10035. child = child->next;
  10036. }
  10037. if (child != NULL) {
  10038. xmlSchemaPContentErr(pctxt,
  10039. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10040. NULL, node, child, NULL,
  10041. "(annotation?)");
  10042. }
  10043. /*
  10044. * Apply additional constraints.
  10045. *
  10046. * Note that it is important to use the original @targetNamespace
  10047. * (or none at all), to rule out imports of schemas _with_ a
  10048. * @targetNamespace if the importing schema is a chameleon schema
  10049. * (with no @targetNamespace).
  10050. */
  10051. thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
  10052. if (namespaceName != NULL) {
  10053. /*
  10054. * 1.1 If the namespace [attribute] is present, then its `actual value`
  10055. * must not match the `actual value` of the enclosing <schema>'s
  10056. * targetNamespace [attribute].
  10057. */
  10058. if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
  10059. xmlSchemaPCustomErr(pctxt,
  10060. XML_SCHEMAP_SRC_IMPORT_1_1,
  10061. NULL, node,
  10062. "The value of the attribute 'namespace' must not match "
  10063. "the target namespace '%s' of the importing schema",
  10064. thisTargetNamespace);
  10065. return (pctxt->err);
  10066. }
  10067. } else {
  10068. /*
  10069. * 1.2 If the namespace [attribute] is not present, then the enclosing
  10070. * <schema> must have a targetNamespace [attribute].
  10071. */
  10072. if (thisTargetNamespace == NULL) {
  10073. xmlSchemaPCustomErr(pctxt,
  10074. XML_SCHEMAP_SRC_IMPORT_1_2,
  10075. NULL, node,
  10076. "The attribute 'namespace' must be existent if "
  10077. "the importing schema has no target namespace",
  10078. NULL);
  10079. return (pctxt->err);
  10080. }
  10081. }
  10082. /*
  10083. * Locate and acquire the schema document.
  10084. */
  10085. if (schemaLocation != NULL)
  10086. schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  10087. schemaLocation, node);
  10088. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  10089. schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
  10090. namespaceName, &bucket);
  10091. if (ret != 0)
  10092. return(ret);
  10093. /*
  10094. * For <import>: "It is *not* an error for the application
  10095. * schema reference strategy to fail."
  10096. * So just don't parse if no schema document was found.
  10097. * Note that we will get no bucket if the schema could not be
  10098. * located or if there was no schemaLocation.
  10099. */
  10100. if ((bucket == NULL) && (schemaLocation != NULL)) {
  10101. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  10102. XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
  10103. node, NULL,
  10104. "Failed to locate a schema at location '%s'. "
  10105. "Skipping the import", schemaLocation, NULL, NULL);
  10106. }
  10107. if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
  10108. ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10109. }
  10110. return (ret);
  10111. }
  10112. static int
  10113. xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
  10114. xmlSchemaPtr schema,
  10115. xmlNodePtr node,
  10116. xmlChar **schemaLocation,
  10117. int type)
  10118. {
  10119. xmlAttrPtr attr;
  10120. if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
  10121. (schemaLocation == NULL))
  10122. return (-1);
  10123. *schemaLocation = NULL;
  10124. /*
  10125. * Check for illegal attributes.
  10126. * Applies for both <include> and <redefine>.
  10127. */
  10128. attr = node->properties;
  10129. while (attr != NULL) {
  10130. if (attr->ns == NULL) {
  10131. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10132. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10133. xmlSchemaPIllegalAttrErr(pctxt,
  10134. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10135. }
  10136. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10137. xmlSchemaPIllegalAttrErr(pctxt,
  10138. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10139. }
  10140. attr = attr->next;
  10141. }
  10142. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  10143. /*
  10144. * Preliminary step, extract the URI-Reference and make an URI
  10145. * from the base.
  10146. */
  10147. /*
  10148. * Attribute "schemaLocation" is mandatory.
  10149. */
  10150. attr = xmlSchemaGetPropNode(node, "schemaLocation");
  10151. if (attr != NULL) {
  10152. xmlChar *base = NULL;
  10153. xmlChar *uri = NULL;
  10154. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  10155. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10156. (const xmlChar **) schemaLocation) != 0)
  10157. goto exit_error;
  10158. base = xmlNodeGetBase(node->doc, node);
  10159. if (base == NULL) {
  10160. uri = xmlBuildURI(*schemaLocation, node->doc->URL);
  10161. } else {
  10162. uri = xmlBuildURI(*schemaLocation, base);
  10163. xmlFree(base);
  10164. }
  10165. if (uri == NULL) {
  10166. PERROR_INT("xmlSchemaParseIncludeOrRedefine",
  10167. "could not build an URI from the schemaLocation")
  10168. goto exit_failure;
  10169. }
  10170. (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
  10171. xmlFree(uri);
  10172. } else {
  10173. xmlSchemaPMissingAttrErr(pctxt,
  10174. XML_SCHEMAP_S4S_ATTR_MISSING,
  10175. NULL, node, "schemaLocation", NULL);
  10176. goto exit_error;
  10177. }
  10178. /*
  10179. * Report self-inclusion and self-redefinition.
  10180. */
  10181. if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
  10182. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10183. xmlSchemaPCustomErr(pctxt,
  10184. XML_SCHEMAP_SRC_REDEFINE,
  10185. NULL, node,
  10186. "The schema document '%s' cannot redefine itself.",
  10187. *schemaLocation);
  10188. } else {
  10189. xmlSchemaPCustomErr(pctxt,
  10190. XML_SCHEMAP_SRC_INCLUDE,
  10191. NULL, node,
  10192. "The schema document '%s' cannot include itself.",
  10193. *schemaLocation);
  10194. }
  10195. goto exit_error;
  10196. }
  10197. return(0);
  10198. exit_error:
  10199. return(pctxt->err);
  10200. exit_failure:
  10201. return(-1);
  10202. }
  10203. static int
  10204. xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
  10205. xmlSchemaPtr schema,
  10206. xmlNodePtr node,
  10207. int type)
  10208. {
  10209. xmlNodePtr child = NULL;
  10210. const xmlChar *schemaLocation = NULL;
  10211. int res = 0; /* hasRedefinitions = 0 */
  10212. int isChameleon = 0, wasChameleon = 0;
  10213. xmlSchemaBucketPtr bucket = NULL;
  10214. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10215. return (-1);
  10216. /*
  10217. * Parse attributes. Note that the returned schemaLocation will
  10218. * be already converted to an absolute URI.
  10219. */
  10220. res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
  10221. node, (xmlChar **) (&schemaLocation), type);
  10222. if (res != 0)
  10223. return(res);
  10224. /*
  10225. * Load and add the schema document.
  10226. */
  10227. res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
  10228. NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
  10229. if (res != 0)
  10230. return(res);
  10231. /*
  10232. * If we get no schema bucket back, then this means that the schema
  10233. * document could not be located or was broken XML or was not
  10234. * a schema document.
  10235. */
  10236. if ((bucket == NULL) || (bucket->doc == NULL)) {
  10237. if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
  10238. /*
  10239. * WARNING for <include>:
  10240. * We will raise an error if the schema cannot be located
  10241. * for inclusions, since the that was the feedback from the
  10242. * schema people. I.e. the following spec piece will *not* be
  10243. * satisfied:
  10244. * SPEC src-include: "It is not an error for the `actual value` of the
  10245. * schemaLocation [attribute] to fail to resolve it all, in which
  10246. * case no corresponding inclusion is performed.
  10247. * So do we need a warning report here?"
  10248. */
  10249. res = XML_SCHEMAP_SRC_INCLUDE;
  10250. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10251. node, NULL,
  10252. "Failed to load the document '%s' for inclusion",
  10253. schemaLocation, NULL);
  10254. } else {
  10255. /*
  10256. * NOTE: This was changed to raise an error even if no redefinitions
  10257. * are specified.
  10258. *
  10259. * SPEC src-redefine (1)
  10260. * "If there are any element information items among the [children]
  10261. * other than <annotation> then the `actual value` of the
  10262. * schemaLocation [attribute] must successfully resolve."
  10263. * TODO: Ask the WG if a the location has always to resolve
  10264. * here as well!
  10265. */
  10266. res = XML_SCHEMAP_SRC_REDEFINE;
  10267. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10268. node, NULL,
  10269. "Failed to load the document '%s' for redefinition",
  10270. schemaLocation, NULL);
  10271. }
  10272. } else {
  10273. /*
  10274. * Check targetNamespace sanity before parsing the new schema.
  10275. * TODO: Note that we won't check further content if the
  10276. * targetNamespace was bad.
  10277. */
  10278. if (bucket->origTargetNamespace != NULL) {
  10279. /*
  10280. * SPEC src-include (2.1)
  10281. * "SII has a targetNamespace [attribute], and its `actual
  10282. * value` is identical to the `actual value` of the targetNamespace
  10283. * [attribute] of SII' (which must have such an [attribute])."
  10284. */
  10285. if (pctxt->targetNamespace == NULL) {
  10286. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10287. XML_SCHEMAP_SRC_INCLUDE,
  10288. node, NULL,
  10289. "The target namespace of the included/redefined schema "
  10290. "'%s' has to be absent, since the including/redefining "
  10291. "schema has no target namespace",
  10292. schemaLocation, NULL);
  10293. goto exit_error;
  10294. } else if (!xmlStrEqual(bucket->origTargetNamespace,
  10295. pctxt->targetNamespace)) {
  10296. /* TODO: Change error function. */
  10297. xmlSchemaPCustomErrExt(pctxt,
  10298. XML_SCHEMAP_SRC_INCLUDE,
  10299. NULL, node,
  10300. "The target namespace '%s' of the included/redefined "
  10301. "schema '%s' differs from '%s' of the "
  10302. "including/redefining schema",
  10303. bucket->origTargetNamespace, schemaLocation,
  10304. pctxt->targetNamespace);
  10305. goto exit_error;
  10306. }
  10307. } else if (pctxt->targetNamespace != NULL) {
  10308. /*
  10309. * Chameleons: the original target namespace will
  10310. * differ from the resulting namespace.
  10311. */
  10312. isChameleon = 1;
  10313. bucket->targetNamespace = pctxt->targetNamespace;
  10314. }
  10315. }
  10316. /*
  10317. * Parse the schema.
  10318. */
  10319. if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
  10320. if (isChameleon) {
  10321. /* TODO: Get rid of this flag on the schema itself. */
  10322. if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
  10323. schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10324. } else
  10325. wasChameleon = 1;
  10326. }
  10327. xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10328. /* Restore chameleon flag. */
  10329. if (isChameleon && (!wasChameleon))
  10330. schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10331. }
  10332. /*
  10333. * And now for the children...
  10334. */
  10335. child = node->children;
  10336. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10337. /*
  10338. * Parse (simpleType | complexType | group | attributeGroup))*
  10339. */
  10340. pctxt->redefined = bucket;
  10341. /*
  10342. * How to proceed if the redefined schema was not located?
  10343. */
  10344. pctxt->isRedefine = 1;
  10345. while (IS_SCHEMA(child, "annotation") ||
  10346. IS_SCHEMA(child, "simpleType") ||
  10347. IS_SCHEMA(child, "complexType") ||
  10348. IS_SCHEMA(child, "group") ||
  10349. IS_SCHEMA(child, "attributeGroup")) {
  10350. if (IS_SCHEMA(child, "annotation")) {
  10351. /*
  10352. * TODO: discard or not?
  10353. */
  10354. } else if (IS_SCHEMA(child, "simpleType")) {
  10355. xmlSchemaParseSimpleType(pctxt, schema, child, 1);
  10356. } else if (IS_SCHEMA(child, "complexType")) {
  10357. xmlSchemaParseComplexType(pctxt, schema, child, 1);
  10358. /* hasRedefinitions = 1; */
  10359. } else if (IS_SCHEMA(child, "group")) {
  10360. /* hasRedefinitions = 1; */
  10361. xmlSchemaParseModelGroupDefinition(pctxt,
  10362. schema, child);
  10363. } else if (IS_SCHEMA(child, "attributeGroup")) {
  10364. /* hasRedefinitions = 1; */
  10365. xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
  10366. child);
  10367. }
  10368. child = child->next;
  10369. }
  10370. pctxt->redefined = NULL;
  10371. pctxt->isRedefine = 0;
  10372. } else {
  10373. if (IS_SCHEMA(child, "annotation")) {
  10374. /*
  10375. * TODO: discard or not?
  10376. */
  10377. child = child->next;
  10378. }
  10379. }
  10380. if (child != NULL) {
  10381. res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
  10382. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10383. xmlSchemaPContentErr(pctxt, res,
  10384. NULL, node, child, NULL,
  10385. "(annotation | (simpleType | complexType | group | attributeGroup))*");
  10386. } else {
  10387. xmlSchemaPContentErr(pctxt, res,
  10388. NULL, node, child, NULL,
  10389. "(annotation?)");
  10390. }
  10391. }
  10392. return(res);
  10393. exit_error:
  10394. return(pctxt->err);
  10395. }
  10396. static int
  10397. xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10398. xmlNodePtr node)
  10399. {
  10400. int res;
  10401. #ifndef ENABLE_REDEFINE
  10402. TODO
  10403. return(0);
  10404. #endif
  10405. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10406. XML_SCHEMA_SCHEMA_REDEFINE);
  10407. if (res != 0)
  10408. return(res);
  10409. return(0);
  10410. }
  10411. static int
  10412. xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10413. xmlNodePtr node)
  10414. {
  10415. int res;
  10416. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10417. XML_SCHEMA_SCHEMA_INCLUDE);
  10418. if (res != 0)
  10419. return(res);
  10420. return(0);
  10421. }
  10422. /**
  10423. * xmlSchemaParseModelGroup:
  10424. * @ctxt: a schema validation context
  10425. * @schema: the schema being built
  10426. * @node: a subtree containing XML Schema information
  10427. * @type: the "compositor" type
  10428. * @particleNeeded: if a a model group with a particle
  10429. *
  10430. * parse a XML schema Sequence definition.
  10431. * Applies parts of:
  10432. * Schema Representation Constraint:
  10433. * Redefinition Constraints and Semantics (src-redefine)
  10434. * (6.1), (6.1.1), (6.1.2)
  10435. *
  10436. * Schema Component Constraint:
  10437. * All Group Limited (cos-all-limited) (2)
  10438. * TODO: Actually this should go to component-level checks,
  10439. * but is done here due to performance. Move it to an other layer
  10440. * is schema construction via an API is implemented.
  10441. *
  10442. * *WARNING* this interface is highly subject to change
  10443. *
  10444. * Returns -1 in case of error, 0 if the declaration is improper and
  10445. * 1 in case of success.
  10446. */
  10447. static xmlSchemaTreeItemPtr
  10448. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10449. xmlNodePtr node, xmlSchemaTypeType type,
  10450. int withParticle)
  10451. {
  10452. xmlSchemaModelGroupPtr item;
  10453. xmlSchemaParticlePtr particle = NULL;
  10454. xmlNodePtr child = NULL;
  10455. xmlAttrPtr attr;
  10456. int min = 1, max = 1, isElemRef, hasRefs = 0;
  10457. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10458. return (NULL);
  10459. /*
  10460. * Create a model group with the given compositor.
  10461. */
  10462. item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
  10463. if (item == NULL)
  10464. return (NULL);
  10465. if (withParticle) {
  10466. if (type == XML_SCHEMA_TYPE_ALL) {
  10467. min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
  10468. max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
  10469. } else {
  10470. /* choice + sequence */
  10471. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  10472. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  10473. "(xs:nonNegativeInteger | unbounded)");
  10474. }
  10475. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  10476. /*
  10477. * Create a particle
  10478. */
  10479. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  10480. if (particle == NULL)
  10481. return (NULL);
  10482. particle->children = (xmlSchemaTreeItemPtr) item;
  10483. /*
  10484. * Check for illegal attributes.
  10485. */
  10486. attr = node->properties;
  10487. while (attr != NULL) {
  10488. if (attr->ns == NULL) {
  10489. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10490. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  10491. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
  10492. xmlSchemaPIllegalAttrErr(ctxt,
  10493. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10494. }
  10495. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10496. xmlSchemaPIllegalAttrErr(ctxt,
  10497. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10498. }
  10499. attr = attr->next;
  10500. }
  10501. } else {
  10502. /*
  10503. * Check for illegal attributes.
  10504. */
  10505. attr = node->properties;
  10506. while (attr != NULL) {
  10507. if (attr->ns == NULL) {
  10508. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  10509. xmlSchemaPIllegalAttrErr(ctxt,
  10510. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10511. }
  10512. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10513. xmlSchemaPIllegalAttrErr(ctxt,
  10514. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10515. }
  10516. attr = attr->next;
  10517. }
  10518. }
  10519. /*
  10520. * Extract and validate attributes.
  10521. */
  10522. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10523. /*
  10524. * And now for the children...
  10525. */
  10526. child = node->children;
  10527. if (IS_SCHEMA(child, "annotation")) {
  10528. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  10529. child = child->next;
  10530. }
  10531. if (type == XML_SCHEMA_TYPE_ALL) {
  10532. xmlSchemaParticlePtr part, last = NULL;
  10533. while (IS_SCHEMA(child, "element")) {
  10534. part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
  10535. schema, child, &isElemRef, 0);
  10536. /*
  10537. * SPEC cos-all-limited (2)
  10538. * "The {max occurs} of all the particles in the {particles}
  10539. * of the ('all') group must be 0 or 1.
  10540. */
  10541. if (part != NULL) {
  10542. if (isElemRef)
  10543. hasRefs++;
  10544. if (part->minOccurs > 1) {
  10545. xmlSchemaPCustomErr(ctxt,
  10546. XML_SCHEMAP_COS_ALL_LIMITED,
  10547. NULL, child,
  10548. "Invalid value for minOccurs (must be 0 or 1)",
  10549. NULL);
  10550. /* Reset to 1. */
  10551. part->minOccurs = 1;
  10552. }
  10553. if (part->maxOccurs > 1) {
  10554. xmlSchemaPCustomErr(ctxt,
  10555. XML_SCHEMAP_COS_ALL_LIMITED,
  10556. NULL, child,
  10557. "Invalid value for maxOccurs (must be 0 or 1)",
  10558. NULL);
  10559. /* Reset to 1. */
  10560. part->maxOccurs = 1;
  10561. }
  10562. if (last == NULL)
  10563. item->children = (xmlSchemaTreeItemPtr) part;
  10564. else
  10565. last->next = (xmlSchemaTreeItemPtr) part;
  10566. last = part;
  10567. }
  10568. child = child->next;
  10569. }
  10570. if (child != NULL) {
  10571. xmlSchemaPContentErr(ctxt,
  10572. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10573. NULL, node, child, NULL,
  10574. "(annotation?, (annotation?, element*)");
  10575. }
  10576. } else {
  10577. /* choice + sequence */
  10578. xmlSchemaTreeItemPtr part = NULL, last = NULL;
  10579. while ((IS_SCHEMA(child, "element")) ||
  10580. (IS_SCHEMA(child, "group")) ||
  10581. (IS_SCHEMA(child, "any")) ||
  10582. (IS_SCHEMA(child, "choice")) ||
  10583. (IS_SCHEMA(child, "sequence"))) {
  10584. if (IS_SCHEMA(child, "element")) {
  10585. part = (xmlSchemaTreeItemPtr)
  10586. xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
  10587. if (part && isElemRef)
  10588. hasRefs++;
  10589. } else if (IS_SCHEMA(child, "group")) {
  10590. part =
  10591. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10592. if (part != NULL)
  10593. hasRefs++;
  10594. /*
  10595. * Handle redefinitions.
  10596. */
  10597. if (ctxt->isRedefine && ctxt->redef &&
  10598. (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
  10599. part && part->children)
  10600. {
  10601. if ((xmlSchemaGetQNameRefName(part->children) ==
  10602. ctxt->redef->refName) &&
  10603. (xmlSchemaGetQNameRefTargetNs(part->children) ==
  10604. ctxt->redef->refTargetNs))
  10605. {
  10606. /*
  10607. * SPEC src-redefine:
  10608. * (6.1) "If it has a <group> among its contents at
  10609. * some level the `actual value` of whose ref
  10610. * [attribute] is the same as the `actual value` of
  10611. * its own name attribute plus target namespace, then
  10612. * all of the following must be true:"
  10613. * (6.1.1) "It must have exactly one such group."
  10614. */
  10615. if (ctxt->redefCounter != 0) {
  10616. xmlChar *str = NULL;
  10617. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10618. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10619. "The redefining model group definition "
  10620. "'%s' must not contain more than one "
  10621. "reference to the redefined definition",
  10622. xmlSchemaFormatQName(&str,
  10623. ctxt->redef->refTargetNs,
  10624. ctxt->redef->refName),
  10625. NULL);
  10626. FREE_AND_NULL(str)
  10627. part = NULL;
  10628. } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
  10629. ((WXS_PARTICLE(part))->maxOccurs != 1))
  10630. {
  10631. xmlChar *str = NULL;
  10632. /*
  10633. * SPEC src-redefine:
  10634. * (6.1.2) "The `actual value` of both that
  10635. * group's minOccurs and maxOccurs [attribute]
  10636. * must be 1 (or `absent`).
  10637. */
  10638. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10639. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10640. "The redefining model group definition "
  10641. "'%s' must not contain a reference to the "
  10642. "redefined definition with a "
  10643. "maxOccurs/minOccurs other than 1",
  10644. xmlSchemaFormatQName(&str,
  10645. ctxt->redef->refTargetNs,
  10646. ctxt->redef->refName),
  10647. NULL);
  10648. FREE_AND_NULL(str)
  10649. part = NULL;
  10650. }
  10651. ctxt->redef->reference = WXS_BASIC_CAST part;
  10652. ctxt->redefCounter++;
  10653. }
  10654. }
  10655. } else if (IS_SCHEMA(child, "any")) {
  10656. part = (xmlSchemaTreeItemPtr)
  10657. xmlSchemaParseAny(ctxt, schema, child);
  10658. } else if (IS_SCHEMA(child, "choice")) {
  10659. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10660. XML_SCHEMA_TYPE_CHOICE, 1);
  10661. } else if (IS_SCHEMA(child, "sequence")) {
  10662. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10663. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10664. }
  10665. if (part != NULL) {
  10666. if (last == NULL)
  10667. item->children = part;
  10668. else
  10669. last->next = part;
  10670. last = part;
  10671. }
  10672. child = child->next;
  10673. }
  10674. if (child != NULL) {
  10675. xmlSchemaPContentErr(ctxt,
  10676. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10677. NULL, node, child, NULL,
  10678. "(annotation?, (element | group | choice | sequence | any)*)");
  10679. }
  10680. }
  10681. if ((max == 0) && (min == 0))
  10682. return (NULL);
  10683. if (hasRefs) {
  10684. /*
  10685. * We need to resolve references.
  10686. */
  10687. WXS_ADD_PENDING(ctxt, item);
  10688. }
  10689. if (withParticle)
  10690. return ((xmlSchemaTreeItemPtr) particle);
  10691. else
  10692. return ((xmlSchemaTreeItemPtr) item);
  10693. }
  10694. /**
  10695. * xmlSchemaParseRestriction:
  10696. * @ctxt: a schema validation context
  10697. * @schema: the schema being built
  10698. * @node: a subtree containing XML Schema information
  10699. *
  10700. * parse a XML schema Restriction definition
  10701. * *WARNING* this interface is highly subject to change
  10702. *
  10703. * Returns the type definition or NULL in case of error
  10704. */
  10705. static xmlSchemaTypePtr
  10706. xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10707. xmlNodePtr node, xmlSchemaTypeType parentType)
  10708. {
  10709. xmlSchemaTypePtr type;
  10710. xmlNodePtr child = NULL;
  10711. xmlAttrPtr attr;
  10712. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10713. return (NULL);
  10714. /* Not a component, don't create it. */
  10715. type = ctxt->ctxtType;
  10716. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  10717. /*
  10718. * Check for illegal attributes.
  10719. */
  10720. attr = node->properties;
  10721. while (attr != NULL) {
  10722. if (attr->ns == NULL) {
  10723. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10724. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  10725. xmlSchemaPIllegalAttrErr(ctxt,
  10726. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10727. }
  10728. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10729. xmlSchemaPIllegalAttrErr(ctxt,
  10730. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10731. }
  10732. attr = attr->next;
  10733. }
  10734. /*
  10735. * Extract and validate attributes.
  10736. */
  10737. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10738. /*
  10739. * Attribute
  10740. */
  10741. /*
  10742. * Extract the base type. The "base" attribute is mandatory if inside
  10743. * a complex type or if redefining.
  10744. *
  10745. * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
  10746. * among its [children]), the simple type definition which is
  10747. * the {content type} of the type definition `resolved` to by
  10748. * the `actual value` of the base [attribute]"
  10749. */
  10750. if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
  10751. &(type->baseNs), &(type->base)) == 0)
  10752. {
  10753. if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
  10754. xmlSchemaPMissingAttrErr(ctxt,
  10755. XML_SCHEMAP_S4S_ATTR_MISSING,
  10756. NULL, node, "base", NULL);
  10757. } else if ((ctxt->isRedefine) &&
  10758. (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
  10759. {
  10760. if (type->base == NULL) {
  10761. xmlSchemaPMissingAttrErr(ctxt,
  10762. XML_SCHEMAP_S4S_ATTR_MISSING,
  10763. NULL, node, "base", NULL);
  10764. } else if ((! xmlStrEqual(type->base, type->name)) ||
  10765. (! xmlStrEqual(type->baseNs, type->targetNamespace)))
  10766. {
  10767. xmlChar *str1 = NULL, *str2 = NULL;
  10768. /*
  10769. * REDEFINE: SPEC src-redefine (5)
  10770. * "Within the [children], each <simpleType> must have a
  10771. * <restriction> among its [children] ... the `actual value` of
  10772. * whose base [attribute] must be the same as the `actual value`
  10773. * of its own name attribute plus target namespace;"
  10774. */
  10775. xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  10776. NULL, node, "This is a redefinition, but the QName "
  10777. "value '%s' of the 'base' attribute does not match the "
  10778. "type's designation '%s'",
  10779. xmlSchemaFormatQName(&str1, type->baseNs, type->base),
  10780. xmlSchemaFormatQName(&str2, type->targetNamespace,
  10781. type->name), NULL);
  10782. FREE_AND_NULL(str1);
  10783. FREE_AND_NULL(str2);
  10784. /* Avoid confusion and erase the values. */
  10785. type->base = NULL;
  10786. type->baseNs = NULL;
  10787. }
  10788. }
  10789. }
  10790. /*
  10791. * And now for the children...
  10792. */
  10793. child = node->children;
  10794. if (IS_SCHEMA(child, "annotation")) {
  10795. /*
  10796. * Add the annotation to the simple type ancestor.
  10797. */
  10798. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  10799. xmlSchemaParseAnnotation(ctxt, child, 1));
  10800. child = child->next;
  10801. }
  10802. if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
  10803. /*
  10804. * Corresponds to <simpleType><restriction><simpleType>.
  10805. */
  10806. if (IS_SCHEMA(child, "simpleType")) {
  10807. if (type->base != NULL) {
  10808. /*
  10809. * src-restriction-base-or-simpleType
  10810. * Either the base [attribute] or the simpleType [child] of the
  10811. * <restriction> element must be present, but not both.
  10812. */
  10813. xmlSchemaPContentErr(ctxt,
  10814. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10815. NULL, node, child,
  10816. "The attribute 'base' and the <simpleType> child are "
  10817. "mutually exclusive", NULL);
  10818. } else {
  10819. type->baseType = (xmlSchemaTypePtr)
  10820. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10821. }
  10822. child = child->next;
  10823. } else if (type->base == NULL) {
  10824. xmlSchemaPContentErr(ctxt,
  10825. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10826. NULL, node, child,
  10827. "Either the attribute 'base' or a <simpleType> child "
  10828. "must be present", NULL);
  10829. }
  10830. } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10831. /*
  10832. * Corresponds to <complexType><complexContent><restriction>...
  10833. * followed by:
  10834. *
  10835. * Model groups <all>, <choice> and <sequence>.
  10836. */
  10837. if (IS_SCHEMA(child, "all")) {
  10838. type->subtypes = (xmlSchemaTypePtr)
  10839. xmlSchemaParseModelGroup(ctxt, schema, child,
  10840. XML_SCHEMA_TYPE_ALL, 1);
  10841. child = child->next;
  10842. } else if (IS_SCHEMA(child, "choice")) {
  10843. type->subtypes = (xmlSchemaTypePtr)
  10844. xmlSchemaParseModelGroup(ctxt,
  10845. schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
  10846. child = child->next;
  10847. } else if (IS_SCHEMA(child, "sequence")) {
  10848. type->subtypes = (xmlSchemaTypePtr)
  10849. xmlSchemaParseModelGroup(ctxt, schema, child,
  10850. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10851. child = child->next;
  10852. /*
  10853. * Model group reference <group>.
  10854. */
  10855. } else if (IS_SCHEMA(child, "group")) {
  10856. type->subtypes = (xmlSchemaTypePtr)
  10857. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10858. /*
  10859. * Note that the reference will be resolved in
  10860. * xmlSchemaResolveTypeReferences();
  10861. */
  10862. child = child->next;
  10863. }
  10864. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10865. /*
  10866. * Corresponds to <complexType><simpleContent><restriction>...
  10867. *
  10868. * "1.1 the simple type definition corresponding to the <simpleType>
  10869. * among the [children] of <restriction> if there is one;"
  10870. */
  10871. if (IS_SCHEMA(child, "simpleType")) {
  10872. /*
  10873. * We will store the to-be-restricted simple type in
  10874. * type->contentTypeDef *temporarily*.
  10875. */
  10876. type->contentTypeDef = (xmlSchemaTypePtr)
  10877. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10878. if ( type->contentTypeDef == NULL)
  10879. return (NULL);
  10880. child = child->next;
  10881. }
  10882. }
  10883. if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
  10884. (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
  10885. xmlSchemaFacetPtr facet, lastfacet = NULL;
  10886. /*
  10887. * Corresponds to <complexType><simpleContent><restriction>...
  10888. * <simpleType><restriction>...
  10889. */
  10890. /*
  10891. * Add the facets to the simple type ancestor.
  10892. */
  10893. /*
  10894. * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
  10895. * Simple Type Definition Schema Representation Constraint:
  10896. * *Single Facet Value*
  10897. */
  10898. while ((IS_SCHEMA(child, "minInclusive")) ||
  10899. (IS_SCHEMA(child, "minExclusive")) ||
  10900. (IS_SCHEMA(child, "maxInclusive")) ||
  10901. (IS_SCHEMA(child, "maxExclusive")) ||
  10902. (IS_SCHEMA(child, "totalDigits")) ||
  10903. (IS_SCHEMA(child, "fractionDigits")) ||
  10904. (IS_SCHEMA(child, "pattern")) ||
  10905. (IS_SCHEMA(child, "enumeration")) ||
  10906. (IS_SCHEMA(child, "whiteSpace")) ||
  10907. (IS_SCHEMA(child, "length")) ||
  10908. (IS_SCHEMA(child, "maxLength")) ||
  10909. (IS_SCHEMA(child, "minLength"))) {
  10910. facet = xmlSchemaParseFacet(ctxt, schema, child);
  10911. if (facet != NULL) {
  10912. if (lastfacet == NULL)
  10913. type->facets = facet;
  10914. else
  10915. lastfacet->next = facet;
  10916. lastfacet = facet;
  10917. lastfacet->next = NULL;
  10918. }
  10919. child = child->next;
  10920. }
  10921. /*
  10922. * Create links for derivation and validation.
  10923. */
  10924. if (type->facets != NULL) {
  10925. xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
  10926. facet = type->facets;
  10927. do {
  10928. facetLink = (xmlSchemaFacetLinkPtr)
  10929. xmlMalloc(sizeof(xmlSchemaFacetLink));
  10930. if (facetLink == NULL) {
  10931. xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
  10932. xmlFree(facetLink);
  10933. return (NULL);
  10934. }
  10935. facetLink->facet = facet;
  10936. facetLink->next = NULL;
  10937. if (lastFacetLink == NULL)
  10938. type->facetSet = facetLink;
  10939. else
  10940. lastFacetLink->next = facetLink;
  10941. lastFacetLink = facetLink;
  10942. facet = facet->next;
  10943. } while (facet != NULL);
  10944. }
  10945. }
  10946. if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
  10947. /*
  10948. * Attribute uses/declarations.
  10949. */
  10950. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  10951. (xmlSchemaItemListPtr *) &(type->attrUses),
  10952. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  10953. return(NULL);
  10954. /*
  10955. * Attribute wildcard.
  10956. */
  10957. if (IS_SCHEMA(child, "anyAttribute")) {
  10958. type->attributeWildcard =
  10959. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  10960. child = child->next;
  10961. }
  10962. }
  10963. if (child != NULL) {
  10964. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10965. xmlSchemaPContentErr(ctxt,
  10966. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10967. NULL, node, child, NULL,
  10968. "annotation?, (group | all | choice | sequence)?, "
  10969. "((attribute | attributeGroup)*, anyAttribute?))");
  10970. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10971. xmlSchemaPContentErr(ctxt,
  10972. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10973. NULL, node, child, NULL,
  10974. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  10975. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  10976. "length | minLength | maxLength | enumeration | whiteSpace | "
  10977. "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
  10978. } else {
  10979. /* Simple type */
  10980. xmlSchemaPContentErr(ctxt,
  10981. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10982. NULL, node, child, NULL,
  10983. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  10984. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  10985. "length | minLength | maxLength | enumeration | whiteSpace | "
  10986. "pattern)*))");
  10987. }
  10988. }
  10989. return (NULL);
  10990. }
  10991. /**
  10992. * xmlSchemaParseExtension:
  10993. * @ctxt: a schema validation context
  10994. * @schema: the schema being built
  10995. * @node: a subtree containing XML Schema information
  10996. *
  10997. * Parses an <extension>, which is found inside a
  10998. * <simpleContent> or <complexContent>.
  10999. * *WARNING* this interface is highly subject to change.
  11000. *
  11001. * TODO: Returns the type definition or NULL in case of error
  11002. */
  11003. static xmlSchemaTypePtr
  11004. xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11005. xmlNodePtr node, xmlSchemaTypeType parentType)
  11006. {
  11007. xmlSchemaTypePtr type;
  11008. xmlNodePtr child = NULL;
  11009. xmlAttrPtr attr;
  11010. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11011. return (NULL);
  11012. /* Not a component, don't create it. */
  11013. type = ctxt->ctxtType;
  11014. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
  11015. /*
  11016. * Check for illegal attributes.
  11017. */
  11018. attr = node->properties;
  11019. while (attr != NULL) {
  11020. if (attr->ns == NULL) {
  11021. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11022. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  11023. xmlSchemaPIllegalAttrErr(ctxt,
  11024. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11025. }
  11026. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11027. xmlSchemaPIllegalAttrErr(ctxt,
  11028. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11029. }
  11030. attr = attr->next;
  11031. }
  11032. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11033. /*
  11034. * Attribute "base" - mandatory.
  11035. */
  11036. if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
  11037. "base", &(type->baseNs), &(type->base)) == 0) &&
  11038. (type->base == NULL)) {
  11039. xmlSchemaPMissingAttrErr(ctxt,
  11040. XML_SCHEMAP_S4S_ATTR_MISSING,
  11041. NULL, node, "base", NULL);
  11042. }
  11043. /*
  11044. * And now for the children...
  11045. */
  11046. child = node->children;
  11047. if (IS_SCHEMA(child, "annotation")) {
  11048. /*
  11049. * Add the annotation to the type ancestor.
  11050. */
  11051. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11052. xmlSchemaParseAnnotation(ctxt, child, 1));
  11053. child = child->next;
  11054. }
  11055. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11056. /*
  11057. * Corresponds to <complexType><complexContent><extension>... and:
  11058. *
  11059. * Model groups <all>, <choice>, <sequence> and <group>.
  11060. */
  11061. if (IS_SCHEMA(child, "all")) {
  11062. type->subtypes = (xmlSchemaTypePtr)
  11063. xmlSchemaParseModelGroup(ctxt, schema,
  11064. child, XML_SCHEMA_TYPE_ALL, 1);
  11065. child = child->next;
  11066. } else if (IS_SCHEMA(child, "choice")) {
  11067. type->subtypes = (xmlSchemaTypePtr)
  11068. xmlSchemaParseModelGroup(ctxt, schema,
  11069. child, XML_SCHEMA_TYPE_CHOICE, 1);
  11070. child = child->next;
  11071. } else if (IS_SCHEMA(child, "sequence")) {
  11072. type->subtypes = (xmlSchemaTypePtr)
  11073. xmlSchemaParseModelGroup(ctxt, schema,
  11074. child, XML_SCHEMA_TYPE_SEQUENCE, 1);
  11075. child = child->next;
  11076. } else if (IS_SCHEMA(child, "group")) {
  11077. type->subtypes = (xmlSchemaTypePtr)
  11078. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11079. /*
  11080. * Note that the reference will be resolved in
  11081. * xmlSchemaResolveTypeReferences();
  11082. */
  11083. child = child->next;
  11084. }
  11085. }
  11086. if (child != NULL) {
  11087. /*
  11088. * Attribute uses/declarations.
  11089. */
  11090. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11091. (xmlSchemaItemListPtr *) &(type->attrUses),
  11092. XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
  11093. return(NULL);
  11094. /*
  11095. * Attribute wildcard.
  11096. */
  11097. if (IS_SCHEMA(child, "anyAttribute")) {
  11098. ctxt->ctxtType->attributeWildcard =
  11099. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11100. child = child->next;
  11101. }
  11102. }
  11103. if (child != NULL) {
  11104. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11105. /* Complex content extension. */
  11106. xmlSchemaPContentErr(ctxt,
  11107. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11108. NULL, node, child, NULL,
  11109. "(annotation?, ((group | all | choice | sequence)?, "
  11110. "((attribute | attributeGroup)*, anyAttribute?)))");
  11111. } else {
  11112. /* Simple content extension. */
  11113. xmlSchemaPContentErr(ctxt,
  11114. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11115. NULL, node, child, NULL,
  11116. "(annotation?, ((attribute | attributeGroup)*, "
  11117. "anyAttribute?))");
  11118. }
  11119. }
  11120. return (NULL);
  11121. }
  11122. /**
  11123. * xmlSchemaParseSimpleContent:
  11124. * @ctxt: a schema validation context
  11125. * @schema: the schema being built
  11126. * @node: a subtree containing XML Schema information
  11127. *
  11128. * parse a XML schema SimpleContent definition
  11129. * *WARNING* this interface is highly subject to change
  11130. *
  11131. * Returns the type definition or NULL in case of error
  11132. */
  11133. static int
  11134. xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
  11135. xmlSchemaPtr schema, xmlNodePtr node,
  11136. int *hasRestrictionOrExtension)
  11137. {
  11138. xmlSchemaTypePtr type;
  11139. xmlNodePtr child = NULL;
  11140. xmlAttrPtr attr;
  11141. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11142. (hasRestrictionOrExtension == NULL))
  11143. return (-1);
  11144. *hasRestrictionOrExtension = 0;
  11145. /* Not a component, don't create it. */
  11146. type = ctxt->ctxtType;
  11147. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  11148. /*
  11149. * Check for illegal attributes.
  11150. */
  11151. attr = node->properties;
  11152. while (attr != NULL) {
  11153. if (attr->ns == NULL) {
  11154. if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  11155. xmlSchemaPIllegalAttrErr(ctxt,
  11156. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11157. }
  11158. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11159. xmlSchemaPIllegalAttrErr(ctxt,
  11160. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11161. }
  11162. attr = attr->next;
  11163. }
  11164. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11165. /*
  11166. * And now for the children...
  11167. */
  11168. child = node->children;
  11169. if (IS_SCHEMA(child, "annotation")) {
  11170. /*
  11171. * Add the annotation to the complex type ancestor.
  11172. */
  11173. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11174. xmlSchemaParseAnnotation(ctxt, child, 1));
  11175. child = child->next;
  11176. }
  11177. if (child == NULL) {
  11178. xmlSchemaPContentErr(ctxt,
  11179. XML_SCHEMAP_S4S_ELEM_MISSING,
  11180. NULL, node, NULL, NULL,
  11181. "(annotation?, (restriction | extension))");
  11182. }
  11183. if (child == NULL) {
  11184. xmlSchemaPContentErr(ctxt,
  11185. XML_SCHEMAP_S4S_ELEM_MISSING,
  11186. NULL, node, NULL, NULL,
  11187. "(annotation?, (restriction | extension))");
  11188. }
  11189. if (IS_SCHEMA(child, "restriction")) {
  11190. xmlSchemaParseRestriction(ctxt, schema, child,
  11191. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11192. (*hasRestrictionOrExtension) = 1;
  11193. child = child->next;
  11194. } else if (IS_SCHEMA(child, "extension")) {
  11195. xmlSchemaParseExtension(ctxt, schema, child,
  11196. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11197. (*hasRestrictionOrExtension) = 1;
  11198. child = child->next;
  11199. }
  11200. if (child != NULL) {
  11201. xmlSchemaPContentErr(ctxt,
  11202. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11203. NULL, node, child, NULL,
  11204. "(annotation?, (restriction | extension))");
  11205. }
  11206. return (0);
  11207. }
  11208. /**
  11209. * xmlSchemaParseComplexContent:
  11210. * @ctxt: a schema validation context
  11211. * @schema: the schema being built
  11212. * @node: a subtree containing XML Schema information
  11213. *
  11214. * parse a XML schema ComplexContent definition
  11215. * *WARNING* this interface is highly subject to change
  11216. *
  11217. * Returns the type definition or NULL in case of error
  11218. */
  11219. static int
  11220. xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
  11221. xmlSchemaPtr schema, xmlNodePtr node,
  11222. int *hasRestrictionOrExtension)
  11223. {
  11224. xmlSchemaTypePtr type;
  11225. xmlNodePtr child = NULL;
  11226. xmlAttrPtr attr;
  11227. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11228. (hasRestrictionOrExtension == NULL))
  11229. return (-1);
  11230. *hasRestrictionOrExtension = 0;
  11231. /* Not a component, don't create it. */
  11232. type = ctxt->ctxtType;
  11233. /*
  11234. * Check for illegal attributes.
  11235. */
  11236. attr = node->properties;
  11237. while (attr != NULL) {
  11238. if (attr->ns == NULL) {
  11239. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11240. (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
  11241. {
  11242. xmlSchemaPIllegalAttrErr(ctxt,
  11243. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11244. }
  11245. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11246. xmlSchemaPIllegalAttrErr(ctxt,
  11247. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11248. }
  11249. attr = attr->next;
  11250. }
  11251. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11252. /*
  11253. * Set the 'mixed' on the complex type ancestor.
  11254. */
  11255. if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
  11256. if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
  11257. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11258. }
  11259. child = node->children;
  11260. if (IS_SCHEMA(child, "annotation")) {
  11261. /*
  11262. * Add the annotation to the complex type ancestor.
  11263. */
  11264. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11265. xmlSchemaParseAnnotation(ctxt, child, 1));
  11266. child = child->next;
  11267. }
  11268. if (child == NULL) {
  11269. xmlSchemaPContentErr(ctxt,
  11270. XML_SCHEMAP_S4S_ELEM_MISSING,
  11271. NULL, node, NULL,
  11272. NULL, "(annotation?, (restriction | extension))");
  11273. }
  11274. if (child == NULL) {
  11275. xmlSchemaPContentErr(ctxt,
  11276. XML_SCHEMAP_S4S_ELEM_MISSING,
  11277. NULL, node, NULL,
  11278. NULL, "(annotation?, (restriction | extension))");
  11279. }
  11280. if (IS_SCHEMA(child, "restriction")) {
  11281. xmlSchemaParseRestriction(ctxt, schema, child,
  11282. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11283. (*hasRestrictionOrExtension) = 1;
  11284. child = child->next;
  11285. } else if (IS_SCHEMA(child, "extension")) {
  11286. xmlSchemaParseExtension(ctxt, schema, child,
  11287. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11288. (*hasRestrictionOrExtension) = 1;
  11289. child = child->next;
  11290. }
  11291. if (child != NULL) {
  11292. xmlSchemaPContentErr(ctxt,
  11293. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11294. NULL, node, child,
  11295. NULL, "(annotation?, (restriction | extension))");
  11296. }
  11297. return (0);
  11298. }
  11299. /**
  11300. * xmlSchemaParseComplexType:
  11301. * @ctxt: a schema validation context
  11302. * @schema: the schema being built
  11303. * @node: a subtree containing XML Schema information
  11304. *
  11305. * parse a XML schema Complex Type definition
  11306. * *WARNING* this interface is highly subject to change
  11307. *
  11308. * Returns the type definition or NULL in case of error
  11309. */
  11310. static xmlSchemaTypePtr
  11311. xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11312. xmlNodePtr node, int topLevel)
  11313. {
  11314. xmlSchemaTypePtr type, ctxtType;
  11315. xmlNodePtr child = NULL;
  11316. const xmlChar *name = NULL;
  11317. xmlAttrPtr attr;
  11318. const xmlChar *attrValue;
  11319. #ifdef ENABLE_NAMED_LOCALS
  11320. char buf[40];
  11321. #endif
  11322. int final = 0, block = 0, hasRestrictionOrExtension = 0;
  11323. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11324. return (NULL);
  11325. ctxtType = ctxt->ctxtType;
  11326. if (topLevel) {
  11327. attr = xmlSchemaGetPropNode(node, "name");
  11328. if (attr == NULL) {
  11329. xmlSchemaPMissingAttrErr(ctxt,
  11330. XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
  11331. return (NULL);
  11332. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  11333. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  11334. return (NULL);
  11335. }
  11336. }
  11337. if (topLevel == 0) {
  11338. /*
  11339. * Parse as local complex type definition.
  11340. */
  11341. #ifdef ENABLE_NAMED_LOCALS
  11342. snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
  11343. type = xmlSchemaAddType(ctxt, schema,
  11344. XML_SCHEMA_TYPE_COMPLEX,
  11345. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  11346. ctxt->targetNamespace, node, 0);
  11347. #else
  11348. type = xmlSchemaAddType(ctxt, schema,
  11349. XML_SCHEMA_TYPE_COMPLEX,
  11350. NULL, ctxt->targetNamespace, node, 0);
  11351. #endif
  11352. if (type == NULL)
  11353. return (NULL);
  11354. name = type->name;
  11355. type->node = node;
  11356. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11357. /*
  11358. * TODO: We need the target namespace.
  11359. */
  11360. } else {
  11361. /*
  11362. * Parse as global complex type definition.
  11363. */
  11364. type = xmlSchemaAddType(ctxt, schema,
  11365. XML_SCHEMA_TYPE_COMPLEX,
  11366. name, ctxt->targetNamespace, node, 1);
  11367. if (type == NULL)
  11368. return (NULL);
  11369. type->node = node;
  11370. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11371. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  11372. }
  11373. type->targetNamespace = ctxt->targetNamespace;
  11374. /*
  11375. * Handle attributes.
  11376. */
  11377. attr = node->properties;
  11378. while (attr != NULL) {
  11379. if (attr->ns == NULL) {
  11380. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  11381. /*
  11382. * Attribute "id".
  11383. */
  11384. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11385. } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
  11386. /*
  11387. * Attribute "mixed".
  11388. */
  11389. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11390. NULL, (xmlNodePtr) attr))
  11391. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11392. } else if (topLevel) {
  11393. /*
  11394. * Attributes of global complex type definitions.
  11395. */
  11396. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  11397. /* Pass. */
  11398. } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
  11399. /*
  11400. * Attribute "abstract".
  11401. */
  11402. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11403. NULL, (xmlNodePtr) attr))
  11404. type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
  11405. } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
  11406. /*
  11407. * Attribute "final".
  11408. */
  11409. attrValue = xmlSchemaGetNodeContent(ctxt,
  11410. (xmlNodePtr) attr);
  11411. if (xmlSchemaPValAttrBlockFinal(attrValue,
  11412. &(type->flags),
  11413. -1,
  11414. XML_SCHEMAS_TYPE_FINAL_EXTENSION,
  11415. XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
  11416. -1, -1, -1) != 0)
  11417. {
  11418. xmlSchemaPSimpleTypeErr(ctxt,
  11419. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11420. NULL, (xmlNodePtr) attr, NULL,
  11421. "(#all | List of (extension | restriction))",
  11422. attrValue, NULL, NULL, NULL);
  11423. } else
  11424. final = 1;
  11425. } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
  11426. /*
  11427. * Attribute "block".
  11428. */
  11429. attrValue = xmlSchemaGetNodeContent(ctxt,
  11430. (xmlNodePtr) attr);
  11431. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  11432. -1,
  11433. XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
  11434. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
  11435. -1, -1, -1) != 0) {
  11436. xmlSchemaPSimpleTypeErr(ctxt,
  11437. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11438. NULL, (xmlNodePtr) attr, NULL,
  11439. "(#all | List of (extension | restriction)) ",
  11440. attrValue, NULL, NULL, NULL);
  11441. } else
  11442. block = 1;
  11443. } else {
  11444. xmlSchemaPIllegalAttrErr(ctxt,
  11445. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11446. }
  11447. } else {
  11448. xmlSchemaPIllegalAttrErr(ctxt,
  11449. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11450. }
  11451. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11452. xmlSchemaPIllegalAttrErr(ctxt,
  11453. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11454. }
  11455. attr = attr->next;
  11456. }
  11457. if (! block) {
  11458. /*
  11459. * Apply default "block" values.
  11460. */
  11461. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  11462. type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  11463. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  11464. type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  11465. }
  11466. if (! final) {
  11467. /*
  11468. * Apply default "block" values.
  11469. */
  11470. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  11471. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  11472. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  11473. type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
  11474. }
  11475. /*
  11476. * And now for the children...
  11477. */
  11478. child = node->children;
  11479. if (IS_SCHEMA(child, "annotation")) {
  11480. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  11481. child = child->next;
  11482. }
  11483. ctxt->ctxtType = type;
  11484. if (IS_SCHEMA(child, "simpleContent")) {
  11485. /*
  11486. * <complexType><simpleContent>...
  11487. * 3.4.3 : 2.2
  11488. * Specifying mixed='true' when the <simpleContent>
  11489. * alternative is chosen has no effect
  11490. */
  11491. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  11492. type->flags ^= XML_SCHEMAS_TYPE_MIXED;
  11493. xmlSchemaParseSimpleContent(ctxt, schema, child,
  11494. &hasRestrictionOrExtension);
  11495. child = child->next;
  11496. } else if (IS_SCHEMA(child, "complexContent")) {
  11497. /*
  11498. * <complexType><complexContent>...
  11499. */
  11500. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  11501. xmlSchemaParseComplexContent(ctxt, schema, child,
  11502. &hasRestrictionOrExtension);
  11503. child = child->next;
  11504. } else {
  11505. /*
  11506. * E.g <complexType><sequence>... or <complexType><attribute>... etc.
  11507. *
  11508. * SPEC
  11509. * "...the third alternative (neither <simpleContent> nor
  11510. * <complexContent>) is chosen. This case is understood as shorthand
  11511. * for complex content restricting the `ur-type definition`, and the
  11512. * details of the mappings should be modified as necessary.
  11513. */
  11514. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  11515. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  11516. /*
  11517. * Parse model groups.
  11518. */
  11519. if (IS_SCHEMA(child, "all")) {
  11520. type->subtypes = (xmlSchemaTypePtr)
  11521. xmlSchemaParseModelGroup(ctxt, schema, child,
  11522. XML_SCHEMA_TYPE_ALL, 1);
  11523. child = child->next;
  11524. } else if (IS_SCHEMA(child, "choice")) {
  11525. type->subtypes = (xmlSchemaTypePtr)
  11526. xmlSchemaParseModelGroup(ctxt, schema, child,
  11527. XML_SCHEMA_TYPE_CHOICE, 1);
  11528. child = child->next;
  11529. } else if (IS_SCHEMA(child, "sequence")) {
  11530. type->subtypes = (xmlSchemaTypePtr)
  11531. xmlSchemaParseModelGroup(ctxt, schema, child,
  11532. XML_SCHEMA_TYPE_SEQUENCE, 1);
  11533. child = child->next;
  11534. } else if (IS_SCHEMA(child, "group")) {
  11535. type->subtypes = (xmlSchemaTypePtr)
  11536. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11537. /*
  11538. * Note that the reference will be resolved in
  11539. * xmlSchemaResolveTypeReferences();
  11540. */
  11541. child = child->next;
  11542. }
  11543. /*
  11544. * Parse attribute decls/refs.
  11545. */
  11546. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11547. (xmlSchemaItemListPtr *) &(type->attrUses),
  11548. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11549. return(NULL);
  11550. /*
  11551. * Parse attribute wildcard.
  11552. */
  11553. if (IS_SCHEMA(child, "anyAttribute")) {
  11554. type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11555. child = child->next;
  11556. }
  11557. }
  11558. if (child != NULL) {
  11559. xmlSchemaPContentErr(ctxt,
  11560. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11561. NULL, node, child,
  11562. NULL, "(annotation?, (simpleContent | complexContent | "
  11563. "((group | all | choice | sequence)?, ((attribute | "
  11564. "attributeGroup)*, anyAttribute?))))");
  11565. }
  11566. /*
  11567. * REDEFINE: SPEC src-redefine (5)
  11568. */
  11569. if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
  11570. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  11571. NULL, node, "This is a redefinition, thus the "
  11572. "<complexType> must have a <restriction> or <extension> "
  11573. "grand-child", NULL);
  11574. }
  11575. ctxt->ctxtType = ctxtType;
  11576. return (type);
  11577. }
  11578. /************************************************************************
  11579. * *
  11580. * Validating using Schemas *
  11581. * *
  11582. ************************************************************************/
  11583. /************************************************************************
  11584. * *
  11585. * Reading/Writing Schemas *
  11586. * *
  11587. ************************************************************************/
  11588. #if 0 /* Will be enabled if it is clear what options are needed. */
  11589. /**
  11590. * xmlSchemaParserCtxtSetOptions:
  11591. * @ctxt: a schema parser context
  11592. * @options: a combination of xmlSchemaParserOption
  11593. *
  11594. * Sets the options to be used during the parse.
  11595. *
  11596. * Returns 0 in case of success, -1 in case of an
  11597. * API error.
  11598. */
  11599. static int
  11600. xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
  11601. int options)
  11602. {
  11603. int i;
  11604. if (ctxt == NULL)
  11605. return (-1);
  11606. /*
  11607. * WARNING: Change the start value if adding to the
  11608. * xmlSchemaParseOption.
  11609. */
  11610. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  11611. if (options & 1<<i) {
  11612. return (-1);
  11613. }
  11614. }
  11615. ctxt->options = options;
  11616. return (0);
  11617. }
  11618. /**
  11619. * xmlSchemaValidCtxtGetOptions:
  11620. * @ctxt: a schema parser context
  11621. *
  11622. * Returns the option combination of the parser context.
  11623. */
  11624. static int
  11625. xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
  11626. {
  11627. if (ctxt == NULL)
  11628. return (-1);
  11629. else
  11630. return (ctxt->options);
  11631. }
  11632. #endif
  11633. /**
  11634. * xmlSchemaNewParserCtxt:
  11635. * @URL: the location of the schema
  11636. *
  11637. * Create an XML Schemas parse context for that file/resource expected
  11638. * to contain an XML Schemas file.
  11639. *
  11640. * Returns the parser context or NULL in case of error
  11641. */
  11642. xmlSchemaParserCtxtPtr
  11643. xmlSchemaNewParserCtxt(const char *URL)
  11644. {
  11645. xmlSchemaParserCtxtPtr ret;
  11646. if (URL == NULL)
  11647. return (NULL);
  11648. ret = xmlSchemaParserCtxtCreate();
  11649. if (ret == NULL)
  11650. return(NULL);
  11651. ret->dict = xmlDictCreate();
  11652. ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
  11653. return (ret);
  11654. }
  11655. /**
  11656. * xmlSchemaNewMemParserCtxt:
  11657. * @buffer: a pointer to a char array containing the schemas
  11658. * @size: the size of the array
  11659. *
  11660. * Create an XML Schemas parse context for that memory buffer expected
  11661. * to contain an XML Schemas file.
  11662. *
  11663. * Returns the parser context or NULL in case of error
  11664. */
  11665. xmlSchemaParserCtxtPtr
  11666. xmlSchemaNewMemParserCtxt(const char *buffer, int size)
  11667. {
  11668. xmlSchemaParserCtxtPtr ret;
  11669. if ((buffer == NULL) || (size <= 0))
  11670. return (NULL);
  11671. ret = xmlSchemaParserCtxtCreate();
  11672. if (ret == NULL)
  11673. return(NULL);
  11674. ret->buffer = buffer;
  11675. ret->size = size;
  11676. ret->dict = xmlDictCreate();
  11677. return (ret);
  11678. }
  11679. /**
  11680. * xmlSchemaNewDocParserCtxt:
  11681. * @doc: a preparsed document tree
  11682. *
  11683. * Create an XML Schemas parse context for that document.
  11684. * NB. The document may be modified during the parsing process.
  11685. *
  11686. * Returns the parser context or NULL in case of error
  11687. */
  11688. xmlSchemaParserCtxtPtr
  11689. xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
  11690. {
  11691. xmlSchemaParserCtxtPtr ret;
  11692. if (doc == NULL)
  11693. return (NULL);
  11694. ret = xmlSchemaParserCtxtCreate();
  11695. if (ret == NULL)
  11696. return(NULL);
  11697. ret->doc = doc;
  11698. ret->dict = xmlDictCreate();
  11699. /* The application has responsibility for the document */
  11700. ret->preserve = 1;
  11701. return (ret);
  11702. }
  11703. /**
  11704. * xmlSchemaFreeParserCtxt:
  11705. * @ctxt: the schema parser context
  11706. *
  11707. * Free the resources associated to the schema parser context
  11708. */
  11709. void
  11710. xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
  11711. {
  11712. if (ctxt == NULL)
  11713. return;
  11714. if (ctxt->doc != NULL && !ctxt->preserve)
  11715. xmlFreeDoc(ctxt->doc);
  11716. if (ctxt->vctxt != NULL) {
  11717. xmlSchemaFreeValidCtxt(ctxt->vctxt);
  11718. }
  11719. if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
  11720. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  11721. ctxt->constructor = NULL;
  11722. ctxt->ownsConstructor = 0;
  11723. }
  11724. if (ctxt->attrProhibs != NULL)
  11725. xmlSchemaItemListFree(ctxt->attrProhibs);
  11726. xmlDictFree(ctxt->dict);
  11727. xmlFree(ctxt);
  11728. }
  11729. /************************************************************************
  11730. * *
  11731. * Building the content models *
  11732. * *
  11733. ************************************************************************/
  11734. /**
  11735. * xmlSchemaBuildContentModelForSubstGroup:
  11736. *
  11737. * Returns 1 if nillable, 0 otherwise
  11738. */
  11739. static int
  11740. xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
  11741. xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
  11742. {
  11743. xmlAutomataStatePtr start, tmp;
  11744. xmlSchemaElementPtr elemDecl, member;
  11745. xmlSchemaSubstGroupPtr substGroup;
  11746. int i;
  11747. int ret = 0;
  11748. elemDecl = (xmlSchemaElementPtr) particle->children;
  11749. /*
  11750. * Wrap the substitution group with a CHOICE.
  11751. */
  11752. start = pctxt->state;
  11753. if (end == NULL)
  11754. end = xmlAutomataNewState(pctxt->am);
  11755. substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
  11756. if (substGroup == NULL) {
  11757. xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
  11758. XML_SCHEMAP_INTERNAL,
  11759. "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
  11760. "declaration is marked having a subst. group but none "
  11761. "available.\n", elemDecl->name, NULL);
  11762. return(0);
  11763. }
  11764. if (counter >= 0) {
  11765. /*
  11766. * NOTE that we put the declaration in, even if it's abstract.
  11767. * However, an error will be raised during *validation* if an element
  11768. * information item shall be validated against an abstract element
  11769. * declaration.
  11770. */
  11771. tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
  11772. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11773. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11774. /*
  11775. * Add subst. group members.
  11776. */
  11777. for (i = 0; i < substGroup->members->nbItems; i++) {
  11778. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11779. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11780. member->name, member->targetNamespace, member);
  11781. }
  11782. } else if (particle->maxOccurs == 1) {
  11783. /*
  11784. * NOTE that we put the declaration in, even if it's abstract,
  11785. */
  11786. xmlAutomataNewEpsilon(pctxt->am,
  11787. xmlAutomataNewTransition2(pctxt->am,
  11788. start, NULL,
  11789. elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
  11790. /*
  11791. * Add subst. group members.
  11792. */
  11793. for (i = 0; i < substGroup->members->nbItems; i++) {
  11794. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11795. /*
  11796. * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
  11797. * was incorrectly used instead of xmlAutomataNewTransition2()
  11798. * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
  11799. * section in xmlSchemaBuildAContentModel() ).
  11800. * TODO: Check if xmlAutomataNewOnceTrans2() was instead
  11801. * intended for the above "counter" section originally. I.e.,
  11802. * check xs:all with subst-groups.
  11803. *
  11804. * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
  11805. * member->name, member->targetNamespace,
  11806. * 1, 1, member);
  11807. */
  11808. tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
  11809. member->name, member->targetNamespace, member);
  11810. xmlAutomataNewEpsilon(pctxt->am, tmp, end);
  11811. }
  11812. } else {
  11813. xmlAutomataStatePtr hop;
  11814. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11815. UNBOUNDED : particle->maxOccurs - 1;
  11816. int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11817. counter =
  11818. xmlAutomataNewCounter(pctxt->am, minOccurs,
  11819. maxOccurs);
  11820. hop = xmlAutomataNewState(pctxt->am);
  11821. xmlAutomataNewEpsilon(pctxt->am,
  11822. xmlAutomataNewTransition2(pctxt->am,
  11823. start, NULL,
  11824. elemDecl->name, elemDecl->targetNamespace, elemDecl),
  11825. hop);
  11826. /*
  11827. * Add subst. group members.
  11828. */
  11829. for (i = 0; i < substGroup->members->nbItems; i++) {
  11830. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11831. xmlAutomataNewEpsilon(pctxt->am,
  11832. xmlAutomataNewTransition2(pctxt->am,
  11833. start, NULL,
  11834. member->name, member->targetNamespace, member),
  11835. hop);
  11836. }
  11837. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  11838. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  11839. }
  11840. if (particle->minOccurs == 0) {
  11841. xmlAutomataNewEpsilon(pctxt->am, start, end);
  11842. ret = 1;
  11843. }
  11844. pctxt->state = end;
  11845. return(ret);
  11846. }
  11847. /**
  11848. * xmlSchemaBuildContentModelForElement:
  11849. *
  11850. * Returns 1 if nillable, 0 otherwise
  11851. */
  11852. static int
  11853. xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
  11854. xmlSchemaParticlePtr particle)
  11855. {
  11856. int ret = 0;
  11857. if (((xmlSchemaElementPtr) particle->children)->flags &
  11858. XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  11859. /*
  11860. * Substitution groups.
  11861. */
  11862. ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
  11863. } else {
  11864. xmlSchemaElementPtr elemDecl;
  11865. xmlAutomataStatePtr start;
  11866. elemDecl = (xmlSchemaElementPtr) particle->children;
  11867. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  11868. return(0);
  11869. if (particle->maxOccurs == 1) {
  11870. start = ctxt->state;
  11871. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11872. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11873. } else if ((particle->maxOccurs >= UNBOUNDED) &&
  11874. (particle->minOccurs < 2)) {
  11875. /* Special case. */
  11876. start = ctxt->state;
  11877. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11878. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11879. ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
  11880. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11881. } else {
  11882. int counter;
  11883. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11884. UNBOUNDED : particle->maxOccurs - 1;
  11885. int minOccurs = particle->minOccurs < 1 ?
  11886. 0 : particle->minOccurs - 1;
  11887. start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  11888. counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
  11889. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11890. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11891. xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
  11892. ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
  11893. NULL, counter);
  11894. }
  11895. if (particle->minOccurs == 0) {
  11896. xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
  11897. ret = 1;
  11898. }
  11899. }
  11900. return(ret);
  11901. }
  11902. /**
  11903. * xmlSchemaBuildAContentModel:
  11904. * @ctxt: the schema parser context
  11905. * @particle: the particle component
  11906. * @name: the complex type's name whose content is being built
  11907. *
  11908. * Create the automaton for the {content type} of a complex type.
  11909. *
  11910. * Returns 1 if the content is nillable, 0 otherwise
  11911. */
  11912. static int
  11913. xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
  11914. xmlSchemaParticlePtr particle)
  11915. {
  11916. int ret = 0, tmp2;
  11917. if (particle == NULL) {
  11918. PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
  11919. return(1);
  11920. }
  11921. if (particle->children == NULL) {
  11922. /*
  11923. * Just return in this case. A missing "term" of the particle
  11924. * might arise due to an invalid "term" component.
  11925. */
  11926. return(1);
  11927. }
  11928. switch (particle->children->type) {
  11929. case XML_SCHEMA_TYPE_ANY: {
  11930. xmlAutomataStatePtr start, end;
  11931. xmlSchemaWildcardPtr wild;
  11932. xmlSchemaWildcardNsPtr ns;
  11933. wild = (xmlSchemaWildcardPtr) particle->children;
  11934. start = pctxt->state;
  11935. end = xmlAutomataNewState(pctxt->am);
  11936. if (particle->maxOccurs == 1) {
  11937. if (wild->any == 1) {
  11938. /*
  11939. * We need to add both transitions:
  11940. *
  11941. * 1. the {"*", "*"} for elements in a namespace.
  11942. */
  11943. pctxt->state =
  11944. xmlAutomataNewTransition2(pctxt->am,
  11945. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  11946. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11947. /*
  11948. * 2. the {"*"} for elements in no namespace.
  11949. */
  11950. pctxt->state =
  11951. xmlAutomataNewTransition2(pctxt->am,
  11952. start, NULL, BAD_CAST "*", NULL, wild);
  11953. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11954. } else if (wild->nsSet != NULL) {
  11955. ns = wild->nsSet;
  11956. do {
  11957. pctxt->state = start;
  11958. pctxt->state = xmlAutomataNewTransition2(pctxt->am,
  11959. pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
  11960. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11961. ns = ns->next;
  11962. } while (ns != NULL);
  11963. } else if (wild->negNsSet != NULL) {
  11964. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  11965. start, end, BAD_CAST "*", wild->negNsSet->value,
  11966. wild);
  11967. }
  11968. } else {
  11969. int counter;
  11970. xmlAutomataStatePtr hop;
  11971. int maxOccurs =
  11972. particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
  11973. particle->maxOccurs - 1;
  11974. int minOccurs =
  11975. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11976. counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  11977. hop = xmlAutomataNewState(pctxt->am);
  11978. if (wild->any == 1) {
  11979. pctxt->state =
  11980. xmlAutomataNewTransition2(pctxt->am,
  11981. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  11982. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  11983. pctxt->state =
  11984. xmlAutomataNewTransition2(pctxt->am,
  11985. start, NULL, BAD_CAST "*", NULL, wild);
  11986. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  11987. } else if (wild->nsSet != NULL) {
  11988. ns = wild->nsSet;
  11989. do {
  11990. pctxt->state =
  11991. xmlAutomataNewTransition2(pctxt->am,
  11992. start, NULL, BAD_CAST "*", ns->value, wild);
  11993. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  11994. ns = ns->next;
  11995. } while (ns != NULL);
  11996. } else if (wild->negNsSet != NULL) {
  11997. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  11998. start, hop, BAD_CAST "*", wild->negNsSet->value,
  11999. wild);
  12000. }
  12001. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  12002. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12003. }
  12004. if (particle->minOccurs == 0) {
  12005. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12006. ret = 1;
  12007. }
  12008. pctxt->state = end;
  12009. break;
  12010. }
  12011. case XML_SCHEMA_TYPE_ELEMENT:
  12012. ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
  12013. break;
  12014. case XML_SCHEMA_TYPE_SEQUENCE:{
  12015. xmlSchemaTreeItemPtr sub;
  12016. ret = 1;
  12017. /*
  12018. * If max and min occurrences are default (1) then
  12019. * simply iterate over the particles of the <sequence>.
  12020. */
  12021. if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
  12022. sub = particle->children->children;
  12023. while (sub != NULL) {
  12024. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12025. (xmlSchemaParticlePtr) sub);
  12026. if (tmp2 != 1) ret = 0;
  12027. sub = sub->next;
  12028. }
  12029. } else {
  12030. xmlAutomataStatePtr oldstate = pctxt->state;
  12031. if (particle->maxOccurs >= UNBOUNDED) {
  12032. if (particle->minOccurs > 1) {
  12033. xmlAutomataStatePtr tmp;
  12034. int counter;
  12035. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12036. oldstate, NULL);
  12037. oldstate = pctxt->state;
  12038. counter = xmlAutomataNewCounter(pctxt->am,
  12039. particle->minOccurs - 1, UNBOUNDED);
  12040. sub = particle->children->children;
  12041. while (sub != NULL) {
  12042. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12043. (xmlSchemaParticlePtr) sub);
  12044. if (tmp2 != 1) ret = 0;
  12045. sub = sub->next;
  12046. }
  12047. tmp = pctxt->state;
  12048. xmlAutomataNewCountedTrans(pctxt->am, tmp,
  12049. oldstate, counter);
  12050. pctxt->state =
  12051. xmlAutomataNewCounterTrans(pctxt->am, tmp,
  12052. NULL, counter);
  12053. if (ret == 1)
  12054. xmlAutomataNewEpsilon(pctxt->am,
  12055. oldstate, pctxt->state);
  12056. } else {
  12057. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12058. oldstate, NULL);
  12059. oldstate = pctxt->state;
  12060. sub = particle->children->children;
  12061. while (sub != NULL) {
  12062. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12063. (xmlSchemaParticlePtr) sub);
  12064. if (tmp2 != 1) ret = 0;
  12065. sub = sub->next;
  12066. }
  12067. xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
  12068. oldstate);
  12069. /*
  12070. * epsilon needed to block previous trans from
  12071. * being allowed to enter back from another
  12072. * construct
  12073. */
  12074. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12075. pctxt->state, NULL);
  12076. if (particle->minOccurs == 0) {
  12077. xmlAutomataNewEpsilon(pctxt->am,
  12078. oldstate, pctxt->state);
  12079. ret = 1;
  12080. }
  12081. }
  12082. } else if ((particle->maxOccurs > 1)
  12083. || (particle->minOccurs > 1)) {
  12084. xmlAutomataStatePtr tmp;
  12085. int counter;
  12086. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12087. oldstate, NULL);
  12088. oldstate = pctxt->state;
  12089. counter = xmlAutomataNewCounter(pctxt->am,
  12090. particle->minOccurs - 1,
  12091. particle->maxOccurs - 1);
  12092. sub = particle->children->children;
  12093. while (sub != NULL) {
  12094. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12095. (xmlSchemaParticlePtr) sub);
  12096. if (tmp2 != 1) ret = 0;
  12097. sub = sub->next;
  12098. }
  12099. tmp = pctxt->state;
  12100. xmlAutomataNewCountedTrans(pctxt->am,
  12101. tmp, oldstate, counter);
  12102. pctxt->state =
  12103. xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
  12104. counter);
  12105. if ((particle->minOccurs == 0) || (ret == 1)) {
  12106. xmlAutomataNewEpsilon(pctxt->am,
  12107. oldstate, pctxt->state);
  12108. ret = 1;
  12109. }
  12110. } else {
  12111. sub = particle->children->children;
  12112. while (sub != NULL) {
  12113. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12114. (xmlSchemaParticlePtr) sub);
  12115. if (tmp2 != 1) ret = 0;
  12116. sub = sub->next;
  12117. }
  12118. /*
  12119. * epsilon needed to block previous trans from
  12120. * being allowed to enter back from another
  12121. * construct
  12122. */
  12123. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12124. pctxt->state, NULL);
  12125. if (particle->minOccurs == 0) {
  12126. xmlAutomataNewEpsilon(pctxt->am, oldstate,
  12127. pctxt->state);
  12128. ret = 1;
  12129. }
  12130. }
  12131. }
  12132. break;
  12133. }
  12134. case XML_SCHEMA_TYPE_CHOICE:{
  12135. xmlSchemaTreeItemPtr sub;
  12136. xmlAutomataStatePtr start, end;
  12137. ret = 0;
  12138. start = pctxt->state;
  12139. end = xmlAutomataNewState(pctxt->am);
  12140. /*
  12141. * iterate over the subtypes and remerge the end with an
  12142. * epsilon transition
  12143. */
  12144. if (particle->maxOccurs == 1) {
  12145. sub = particle->children->children;
  12146. while (sub != NULL) {
  12147. pctxt->state = start;
  12148. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12149. (xmlSchemaParticlePtr) sub);
  12150. if (tmp2 == 1) ret = 1;
  12151. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12152. sub = sub->next;
  12153. }
  12154. } else {
  12155. int counter;
  12156. xmlAutomataStatePtr hop, base;
  12157. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12158. UNBOUNDED : particle->maxOccurs - 1;
  12159. int minOccurs =
  12160. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12161. /*
  12162. * use a counter to keep track of the number of transitions
  12163. * which went through the choice.
  12164. */
  12165. counter =
  12166. xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12167. hop = xmlAutomataNewState(pctxt->am);
  12168. base = xmlAutomataNewState(pctxt->am);
  12169. sub = particle->children->children;
  12170. while (sub != NULL) {
  12171. pctxt->state = base;
  12172. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12173. (xmlSchemaParticlePtr) sub);
  12174. if (tmp2 == 1) ret = 1;
  12175. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12176. sub = sub->next;
  12177. }
  12178. xmlAutomataNewEpsilon(pctxt->am, start, base);
  12179. xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
  12180. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12181. if (ret == 1)
  12182. xmlAutomataNewEpsilon(pctxt->am, base, end);
  12183. }
  12184. if (particle->minOccurs == 0) {
  12185. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12186. ret = 1;
  12187. }
  12188. pctxt->state = end;
  12189. break;
  12190. }
  12191. case XML_SCHEMA_TYPE_ALL:{
  12192. xmlAutomataStatePtr start, tmp;
  12193. xmlSchemaParticlePtr sub;
  12194. xmlSchemaElementPtr elemDecl;
  12195. ret = 1;
  12196. sub = (xmlSchemaParticlePtr) particle->children->children;
  12197. if (sub == NULL)
  12198. break;
  12199. ret = 0;
  12200. start = pctxt->state;
  12201. tmp = xmlAutomataNewState(pctxt->am);
  12202. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
  12203. pctxt->state = tmp;
  12204. while (sub != NULL) {
  12205. pctxt->state = tmp;
  12206. elemDecl = (xmlSchemaElementPtr) sub->children;
  12207. if (elemDecl == NULL) {
  12208. PERROR_INT("xmlSchemaBuildAContentModel",
  12209. "<element> particle has no term");
  12210. return(ret);
  12211. };
  12212. /*
  12213. * NOTE: The {max occurs} of all the particles in the
  12214. * {particles} of the group must be 0 or 1; this is
  12215. * already ensured during the parse of the content of
  12216. * <all>.
  12217. */
  12218. if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  12219. int counter;
  12220. /*
  12221. * This is an abstract group, we need to share
  12222. * the same counter for all the element transitions
  12223. * derived from the group
  12224. */
  12225. counter = xmlAutomataNewCounter(pctxt->am,
  12226. sub->minOccurs, sub->maxOccurs);
  12227. xmlSchemaBuildContentModelForSubstGroup(pctxt,
  12228. sub, counter, pctxt->state);
  12229. } else {
  12230. if ((sub->minOccurs == 1) &&
  12231. (sub->maxOccurs == 1)) {
  12232. xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
  12233. pctxt->state,
  12234. elemDecl->name,
  12235. elemDecl->targetNamespace,
  12236. 1, 1, elemDecl);
  12237. } else if ((sub->minOccurs == 0) &&
  12238. (sub->maxOccurs == 1)) {
  12239. xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
  12240. pctxt->state,
  12241. elemDecl->name,
  12242. elemDecl->targetNamespace,
  12243. 0,
  12244. 1,
  12245. elemDecl);
  12246. }
  12247. }
  12248. sub = (xmlSchemaParticlePtr) sub->next;
  12249. }
  12250. pctxt->state =
  12251. xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
  12252. if (particle->minOccurs == 0) {
  12253. xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
  12254. ret = 1;
  12255. }
  12256. break;
  12257. }
  12258. case XML_SCHEMA_TYPE_GROUP:
  12259. /*
  12260. * If we hit a model group definition, then this means that
  12261. * it was empty, thus was not substituted for the containing
  12262. * model group. Just do nothing in this case.
  12263. * TODO: But the group should be substituted and not occur at
  12264. * all in the content model at this point. Fix this.
  12265. */
  12266. ret = 1;
  12267. break;
  12268. default:
  12269. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  12270. "xmlSchemaBuildAContentModel",
  12271. "found unexpected term of type '%s' in content model",
  12272. WXS_ITEM_TYPE_NAME(particle->children), NULL);
  12273. return(ret);
  12274. }
  12275. return(ret);
  12276. }
  12277. /**
  12278. * xmlSchemaBuildContentModel:
  12279. * @ctxt: the schema parser context
  12280. * @type: the complex type definition
  12281. * @name: the element name
  12282. *
  12283. * Builds the content model of the complex type.
  12284. */
  12285. static void
  12286. xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
  12287. xmlSchemaParserCtxtPtr ctxt)
  12288. {
  12289. if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
  12290. (type->contModel != NULL) ||
  12291. ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
  12292. (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
  12293. return;
  12294. ctxt->am = NULL;
  12295. ctxt->am = xmlNewAutomata();
  12296. if (ctxt->am == NULL) {
  12297. xmlGenericError(xmlGenericErrorContext,
  12298. "Cannot create automata for complex type %s\n", type->name);
  12299. return;
  12300. }
  12301. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  12302. /*
  12303. * Build the automaton.
  12304. */
  12305. xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
  12306. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  12307. type->contModel = xmlAutomataCompile(ctxt->am);
  12308. if (type->contModel == NULL) {
  12309. xmlSchemaPCustomErr(ctxt,
  12310. XML_SCHEMAP_INTERNAL,
  12311. WXS_BASIC_CAST type, type->node,
  12312. "Failed to compile the content model", NULL);
  12313. } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
  12314. xmlSchemaPCustomErr(ctxt,
  12315. XML_SCHEMAP_NOT_DETERMINISTIC,
  12316. /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
  12317. WXS_BASIC_CAST type, type->node,
  12318. "The content model is not determinist", NULL);
  12319. } else {
  12320. }
  12321. ctxt->state = NULL;
  12322. xmlFreeAutomata(ctxt->am);
  12323. ctxt->am = NULL;
  12324. }
  12325. /**
  12326. * xmlSchemaResolveElementReferences:
  12327. * @elem: the schema element context
  12328. * @ctxt: the schema parser context
  12329. *
  12330. * Resolves the references of an element declaration
  12331. * or particle, which has an element declaration as it's
  12332. * term.
  12333. */
  12334. static void
  12335. xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
  12336. xmlSchemaParserCtxtPtr ctxt)
  12337. {
  12338. if ((ctxt == NULL) || (elemDecl == NULL) ||
  12339. ((elemDecl != NULL) &&
  12340. (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
  12341. return;
  12342. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
  12343. if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
  12344. xmlSchemaTypePtr type;
  12345. /* (type definition) ... otherwise the type definition `resolved`
  12346. * to by the `actual value` of the type [attribute] ...
  12347. */
  12348. type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
  12349. elemDecl->namedTypeNs);
  12350. if (type == NULL) {
  12351. xmlSchemaPResCompAttrErr(ctxt,
  12352. XML_SCHEMAP_SRC_RESOLVE,
  12353. WXS_BASIC_CAST elemDecl, elemDecl->node,
  12354. "type", elemDecl->namedType, elemDecl->namedTypeNs,
  12355. XML_SCHEMA_TYPE_BASIC, "type definition");
  12356. } else
  12357. elemDecl->subtypes = type;
  12358. }
  12359. if (elemDecl->substGroup != NULL) {
  12360. xmlSchemaElementPtr substHead;
  12361. /*
  12362. * FIXME TODO: Do we need a new field in _xmlSchemaElement for
  12363. * substitutionGroup?
  12364. */
  12365. substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
  12366. elemDecl->substGroupNs);
  12367. if (substHead == NULL) {
  12368. xmlSchemaPResCompAttrErr(ctxt,
  12369. XML_SCHEMAP_SRC_RESOLVE,
  12370. WXS_BASIC_CAST elemDecl, NULL,
  12371. "substitutionGroup", elemDecl->substGroup,
  12372. elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
  12373. } else {
  12374. xmlSchemaResolveElementReferences(substHead, ctxt);
  12375. /*
  12376. * Set the "substitution group affiliation".
  12377. * NOTE that now we use the "refDecl" field for this.
  12378. */
  12379. WXS_SUBST_HEAD(elemDecl) = substHead;
  12380. /*
  12381. * The type definitions is set to:
  12382. * SPEC "...the {type definition} of the element
  12383. * declaration `resolved` to by the `actual value`
  12384. * of the substitutionGroup [attribute], if present"
  12385. */
  12386. if (elemDecl->subtypes == NULL) {
  12387. if (substHead->subtypes == NULL) {
  12388. /*
  12389. * This can happen with self-referencing substitution
  12390. * groups. The cycle will be detected later, but we have
  12391. * to set subtypes to avoid null-pointer dereferences.
  12392. */
  12393. elemDecl->subtypes = xmlSchemaGetBuiltInType(
  12394. XML_SCHEMAS_ANYTYPE);
  12395. } else {
  12396. elemDecl->subtypes = substHead->subtypes;
  12397. }
  12398. }
  12399. }
  12400. }
  12401. /*
  12402. * SPEC "The definition of anyType serves as the default type definition
  12403. * for element declarations whose XML representation does not specify one."
  12404. */
  12405. if ((elemDecl->subtypes == NULL) &&
  12406. (elemDecl->namedType == NULL) &&
  12407. (elemDecl->substGroup == NULL))
  12408. elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  12409. }
  12410. /**
  12411. * xmlSchemaResolveUnionMemberTypes:
  12412. * @ctxt: the schema parser context
  12413. * @type: the schema simple type definition
  12414. *
  12415. * Checks and builds the "member type definitions" property of the union
  12416. * simple type. This handles part (1), part (2) is done in
  12417. * xmlSchemaFinishMemberTypeDefinitionsProperty()
  12418. *
  12419. * Returns -1 in case of an internal error, 0 otherwise.
  12420. */
  12421. static int
  12422. xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
  12423. xmlSchemaTypePtr type)
  12424. {
  12425. xmlSchemaTypeLinkPtr link, lastLink, newLink;
  12426. xmlSchemaTypePtr memberType;
  12427. /*
  12428. * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
  12429. * define the explicit members as the type definitions `resolved`
  12430. * to by the items in the `actual value` of the memberTypes [attribute],
  12431. * if any, followed by the type definitions corresponding to the
  12432. * <simpleType>s among the [children] of <union>, if any."
  12433. */
  12434. /*
  12435. * Resolve references.
  12436. */
  12437. link = type->memberTypes;
  12438. lastLink = NULL;
  12439. while (link != NULL) {
  12440. const xmlChar *name, *nsName;
  12441. name = ((xmlSchemaQNameRefPtr) link->type)->name;
  12442. nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
  12443. memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
  12444. if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
  12445. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  12446. WXS_BASIC_CAST type, type->node, "memberTypes",
  12447. name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
  12448. /*
  12449. * Remove the member type link.
  12450. */
  12451. if (lastLink == NULL)
  12452. type->memberTypes = link->next;
  12453. else
  12454. lastLink->next = link->next;
  12455. newLink = link;
  12456. link = link->next;
  12457. xmlFree(newLink);
  12458. } else {
  12459. link->type = memberType;
  12460. lastLink = link;
  12461. link = link->next;
  12462. }
  12463. }
  12464. /*
  12465. * Add local simple types,
  12466. */
  12467. memberType = type->subtypes;
  12468. while (memberType != NULL) {
  12469. link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
  12470. if (link == NULL) {
  12471. xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
  12472. return (-1);
  12473. }
  12474. link->type = memberType;
  12475. link->next = NULL;
  12476. if (lastLink == NULL)
  12477. type->memberTypes = link;
  12478. else
  12479. lastLink->next = link;
  12480. lastLink = link;
  12481. memberType = memberType->next;
  12482. }
  12483. return (0);
  12484. }
  12485. /**
  12486. * xmlSchemaIsDerivedFromBuiltInType:
  12487. * @ctxt: the schema parser context
  12488. * @type: the type definition
  12489. * @valType: the value type
  12490. *
  12491. *
  12492. * Returns 1 if the type has the given value type, or
  12493. * is derived from such a type.
  12494. */
  12495. static int
  12496. xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12497. {
  12498. if (type == NULL)
  12499. return (0);
  12500. if (WXS_IS_COMPLEX(type))
  12501. return (0);
  12502. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12503. if (type->builtInType == valType)
  12504. return(1);
  12505. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12506. (type->builtInType == XML_SCHEMAS_ANYTYPE))
  12507. return (0);
  12508. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12509. }
  12510. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12511. }
  12512. #if 0
  12513. /**
  12514. * xmlSchemaIsDerivedFromBuiltInType:
  12515. * @ctxt: the schema parser context
  12516. * @type: the type definition
  12517. * @valType: the value type
  12518. *
  12519. *
  12520. * Returns 1 if the type has the given value type, or
  12521. * is derived from such a type.
  12522. */
  12523. static int
  12524. xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12525. {
  12526. if (type == NULL)
  12527. return (0);
  12528. if (WXS_IS_COMPLEX(type))
  12529. return (0);
  12530. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12531. if (type->builtInType == valType)
  12532. return(1);
  12533. return (0);
  12534. } else
  12535. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12536. return (0);
  12537. }
  12538. static xmlSchemaTypePtr
  12539. xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
  12540. {
  12541. if (type == NULL)
  12542. return (NULL);
  12543. if (WXS_IS_COMPLEX(type))
  12544. return (NULL);
  12545. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12546. return(type);
  12547. return(xmlSchemaQueryBuiltInType(type->subtypes));
  12548. }
  12549. #endif
  12550. /**
  12551. * xmlSchemaGetPrimitiveType:
  12552. * @type: the simpleType definition
  12553. *
  12554. * Returns the primitive type of the given type or
  12555. * NULL in case of error.
  12556. */
  12557. static xmlSchemaTypePtr
  12558. xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
  12559. {
  12560. while (type != NULL) {
  12561. /*
  12562. * Note that anySimpleType is actually not a primitive type
  12563. * but we need that here.
  12564. */
  12565. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12566. (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
  12567. return (type);
  12568. type = type->baseType;
  12569. }
  12570. return (NULL);
  12571. }
  12572. #if 0
  12573. /**
  12574. * xmlSchemaGetBuiltInTypeAncestor:
  12575. * @type: the simpleType definition
  12576. *
  12577. * Returns the primitive type of the given type or
  12578. * NULL in case of error.
  12579. */
  12580. static xmlSchemaTypePtr
  12581. xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
  12582. {
  12583. if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
  12584. return (0);
  12585. while (type != NULL) {
  12586. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12587. return (type);
  12588. type = type->baseType;
  12589. }
  12590. return (NULL);
  12591. }
  12592. #endif
  12593. /**
  12594. * xmlSchemaCloneWildcardNsConstraints:
  12595. * @ctxt: the schema parser context
  12596. * @dest: the destination wildcard
  12597. * @source: the source wildcard
  12598. *
  12599. * Clones the namespace constraints of source
  12600. * and assigns them to dest.
  12601. * Returns -1 on internal error, 0 otherwise.
  12602. */
  12603. static int
  12604. xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
  12605. xmlSchemaWildcardPtr dest,
  12606. xmlSchemaWildcardPtr source)
  12607. {
  12608. xmlSchemaWildcardNsPtr cur, tmp, last;
  12609. if ((source == NULL) || (dest == NULL))
  12610. return(-1);
  12611. dest->any = source->any;
  12612. cur = source->nsSet;
  12613. last = NULL;
  12614. while (cur != NULL) {
  12615. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12616. if (tmp == NULL)
  12617. return(-1);
  12618. tmp->value = cur->value;
  12619. if (last == NULL)
  12620. dest->nsSet = tmp;
  12621. else
  12622. last->next = tmp;
  12623. last = tmp;
  12624. cur = cur->next;
  12625. }
  12626. if (dest->negNsSet != NULL)
  12627. xmlSchemaFreeWildcardNsSet(dest->negNsSet);
  12628. if (source->negNsSet != NULL) {
  12629. dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12630. if (dest->negNsSet == NULL)
  12631. return(-1);
  12632. dest->negNsSet->value = source->negNsSet->value;
  12633. } else
  12634. dest->negNsSet = NULL;
  12635. return(0);
  12636. }
  12637. /**
  12638. * xmlSchemaUnionWildcards:
  12639. * @ctxt: the schema parser context
  12640. * @completeWild: the first wildcard
  12641. * @curWild: the second wildcard
  12642. *
  12643. * Unions the namespace constraints of the given wildcards.
  12644. * @completeWild will hold the resulting union.
  12645. * Returns a positive error code on failure, -1 in case of an
  12646. * internal error, 0 otherwise.
  12647. */
  12648. static int
  12649. xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
  12650. xmlSchemaWildcardPtr completeWild,
  12651. xmlSchemaWildcardPtr curWild)
  12652. {
  12653. xmlSchemaWildcardNsPtr cur, curB, tmp;
  12654. /*
  12655. * 1 If O1 and O2 are the same value, then that value must be the
  12656. * value.
  12657. */
  12658. if ((completeWild->any == curWild->any) &&
  12659. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12660. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12661. if ((completeWild->negNsSet == NULL) ||
  12662. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12663. if (completeWild->nsSet != NULL) {
  12664. int found = 0;
  12665. /*
  12666. * Check equality of sets.
  12667. */
  12668. cur = completeWild->nsSet;
  12669. while (cur != NULL) {
  12670. found = 0;
  12671. curB = curWild->nsSet;
  12672. while (curB != NULL) {
  12673. if (cur->value == curB->value) {
  12674. found = 1;
  12675. break;
  12676. }
  12677. curB = curB->next;
  12678. }
  12679. if (!found)
  12680. break;
  12681. cur = cur->next;
  12682. }
  12683. if (found)
  12684. return(0);
  12685. } else
  12686. return(0);
  12687. }
  12688. }
  12689. /*
  12690. * 2 If either O1 or O2 is any, then any must be the value
  12691. */
  12692. if (completeWild->any != curWild->any) {
  12693. if (completeWild->any == 0) {
  12694. completeWild->any = 1;
  12695. if (completeWild->nsSet != NULL) {
  12696. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12697. completeWild->nsSet = NULL;
  12698. }
  12699. if (completeWild->negNsSet != NULL) {
  12700. xmlFree(completeWild->negNsSet);
  12701. completeWild->negNsSet = NULL;
  12702. }
  12703. }
  12704. return (0);
  12705. }
  12706. /*
  12707. * 3 If both O1 and O2 are sets of (namespace names or `absent`),
  12708. * then the union of those sets must be the value.
  12709. */
  12710. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12711. int found;
  12712. xmlSchemaWildcardNsPtr start;
  12713. cur = curWild->nsSet;
  12714. start = completeWild->nsSet;
  12715. while (cur != NULL) {
  12716. found = 0;
  12717. curB = start;
  12718. while (curB != NULL) {
  12719. if (cur->value == curB->value) {
  12720. found = 1;
  12721. break;
  12722. }
  12723. curB = curB->next;
  12724. }
  12725. if (!found) {
  12726. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12727. if (tmp == NULL)
  12728. return (-1);
  12729. tmp->value = cur->value;
  12730. tmp->next = completeWild->nsSet;
  12731. completeWild->nsSet = tmp;
  12732. }
  12733. cur = cur->next;
  12734. }
  12735. return(0);
  12736. }
  12737. /*
  12738. * 4 If the two are negations of different values (namespace names
  12739. * or `absent`), then a pair of not and `absent` must be the value.
  12740. */
  12741. if ((completeWild->negNsSet != NULL) &&
  12742. (curWild->negNsSet != NULL) &&
  12743. (completeWild->negNsSet->value != curWild->negNsSet->value)) {
  12744. completeWild->negNsSet->value = NULL;
  12745. return(0);
  12746. }
  12747. /*
  12748. * 5.
  12749. */
  12750. if (((completeWild->negNsSet != NULL) &&
  12751. (completeWild->negNsSet->value != NULL) &&
  12752. (curWild->nsSet != NULL)) ||
  12753. ((curWild->negNsSet != NULL) &&
  12754. (curWild->negNsSet->value != NULL) &&
  12755. (completeWild->nsSet != NULL))) {
  12756. int nsFound, absentFound = 0;
  12757. if (completeWild->nsSet != NULL) {
  12758. cur = completeWild->nsSet;
  12759. curB = curWild->negNsSet;
  12760. } else {
  12761. cur = curWild->nsSet;
  12762. curB = completeWild->negNsSet;
  12763. }
  12764. nsFound = 0;
  12765. while (cur != NULL) {
  12766. if (cur->value == NULL)
  12767. absentFound = 1;
  12768. else if (cur->value == curB->value)
  12769. nsFound = 1;
  12770. if (nsFound && absentFound)
  12771. break;
  12772. cur = cur->next;
  12773. }
  12774. if (nsFound && absentFound) {
  12775. /*
  12776. * 5.1 If the set S includes both the negated namespace
  12777. * name and `absent`, then any must be the value.
  12778. */
  12779. completeWild->any = 1;
  12780. if (completeWild->nsSet != NULL) {
  12781. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12782. completeWild->nsSet = NULL;
  12783. }
  12784. if (completeWild->negNsSet != NULL) {
  12785. xmlFree(completeWild->negNsSet);
  12786. completeWild->negNsSet = NULL;
  12787. }
  12788. } else if (nsFound && (!absentFound)) {
  12789. /*
  12790. * 5.2 If the set S includes the negated namespace name
  12791. * but not `absent`, then a pair of not and `absent` must
  12792. * be the value.
  12793. */
  12794. if (completeWild->nsSet != NULL) {
  12795. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12796. completeWild->nsSet = NULL;
  12797. }
  12798. if (completeWild->negNsSet == NULL) {
  12799. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12800. if (completeWild->negNsSet == NULL)
  12801. return (-1);
  12802. }
  12803. completeWild->negNsSet->value = NULL;
  12804. } else if ((!nsFound) && absentFound) {
  12805. /*
  12806. * 5.3 If the set S includes `absent` but not the negated
  12807. * namespace name, then the union is not expressible.
  12808. */
  12809. xmlSchemaPErr(ctxt, completeWild->node,
  12810. XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
  12811. "The union of the wildcard is not expressible.\n",
  12812. NULL, NULL);
  12813. return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
  12814. } else if ((!nsFound) && (!absentFound)) {
  12815. /*
  12816. * 5.4 If the set S does not include either the negated namespace
  12817. * name or `absent`, then whichever of O1 or O2 is a pair of not
  12818. * and a namespace name must be the value.
  12819. */
  12820. if (completeWild->negNsSet == NULL) {
  12821. if (completeWild->nsSet != NULL) {
  12822. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12823. completeWild->nsSet = NULL;
  12824. }
  12825. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12826. if (completeWild->negNsSet == NULL)
  12827. return (-1);
  12828. completeWild->negNsSet->value = curWild->negNsSet->value;
  12829. }
  12830. }
  12831. return (0);
  12832. }
  12833. /*
  12834. * 6.
  12835. */
  12836. if (((completeWild->negNsSet != NULL) &&
  12837. (completeWild->negNsSet->value == NULL) &&
  12838. (curWild->nsSet != NULL)) ||
  12839. ((curWild->negNsSet != NULL) &&
  12840. (curWild->negNsSet->value == NULL) &&
  12841. (completeWild->nsSet != NULL))) {
  12842. if (completeWild->nsSet != NULL) {
  12843. cur = completeWild->nsSet;
  12844. } else {
  12845. cur = curWild->nsSet;
  12846. }
  12847. while (cur != NULL) {
  12848. if (cur->value == NULL) {
  12849. /*
  12850. * 6.1 If the set S includes `absent`, then any must be the
  12851. * value.
  12852. */
  12853. completeWild->any = 1;
  12854. if (completeWild->nsSet != NULL) {
  12855. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12856. completeWild->nsSet = NULL;
  12857. }
  12858. if (completeWild->negNsSet != NULL) {
  12859. xmlFree(completeWild->negNsSet);
  12860. completeWild->negNsSet = NULL;
  12861. }
  12862. return (0);
  12863. }
  12864. cur = cur->next;
  12865. }
  12866. if (completeWild->negNsSet == NULL) {
  12867. /*
  12868. * 6.2 If the set S does not include `absent`, then a pair of not
  12869. * and `absent` must be the value.
  12870. */
  12871. if (completeWild->nsSet != NULL) {
  12872. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12873. completeWild->nsSet = NULL;
  12874. }
  12875. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12876. if (completeWild->negNsSet == NULL)
  12877. return (-1);
  12878. completeWild->negNsSet->value = NULL;
  12879. }
  12880. return (0);
  12881. }
  12882. return (0);
  12883. }
  12884. /**
  12885. * xmlSchemaIntersectWildcards:
  12886. * @ctxt: the schema parser context
  12887. * @completeWild: the first wildcard
  12888. * @curWild: the second wildcard
  12889. *
  12890. * Intersects the namespace constraints of the given wildcards.
  12891. * @completeWild will hold the resulting intersection.
  12892. * Returns a positive error code on failure, -1 in case of an
  12893. * internal error, 0 otherwise.
  12894. */
  12895. static int
  12896. xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
  12897. xmlSchemaWildcardPtr completeWild,
  12898. xmlSchemaWildcardPtr curWild)
  12899. {
  12900. xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
  12901. /*
  12902. * 1 If O1 and O2 are the same value, then that value must be the
  12903. * value.
  12904. */
  12905. if ((completeWild->any == curWild->any) &&
  12906. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12907. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12908. if ((completeWild->negNsSet == NULL) ||
  12909. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12910. if (completeWild->nsSet != NULL) {
  12911. int found = 0;
  12912. /*
  12913. * Check equality of sets.
  12914. */
  12915. cur = completeWild->nsSet;
  12916. while (cur != NULL) {
  12917. found = 0;
  12918. curB = curWild->nsSet;
  12919. while (curB != NULL) {
  12920. if (cur->value == curB->value) {
  12921. found = 1;
  12922. break;
  12923. }
  12924. curB = curB->next;
  12925. }
  12926. if (!found)
  12927. break;
  12928. cur = cur->next;
  12929. }
  12930. if (found)
  12931. return(0);
  12932. } else
  12933. return(0);
  12934. }
  12935. }
  12936. /*
  12937. * 2 If either O1 or O2 is any, then the other must be the value.
  12938. */
  12939. if ((completeWild->any != curWild->any) && (completeWild->any)) {
  12940. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  12941. return(-1);
  12942. return(0);
  12943. }
  12944. /*
  12945. * 3 If either O1 or O2 is a pair of not and a value (a namespace
  12946. * name or `absent`) and the other is a set of (namespace names or
  12947. * `absent`), then that set, minus the negated value if it was in
  12948. * the set, minus `absent` if it was in the set, must be the value.
  12949. */
  12950. if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
  12951. ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
  12952. const xmlChar *neg;
  12953. if (completeWild->nsSet == NULL) {
  12954. neg = completeWild->negNsSet->value;
  12955. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  12956. return(-1);
  12957. } else
  12958. neg = curWild->negNsSet->value;
  12959. /*
  12960. * Remove absent and negated.
  12961. */
  12962. prev = NULL;
  12963. cur = completeWild->nsSet;
  12964. while (cur != NULL) {
  12965. if (cur->value == NULL) {
  12966. if (prev == NULL)
  12967. completeWild->nsSet = cur->next;
  12968. else
  12969. prev->next = cur->next;
  12970. xmlFree(cur);
  12971. break;
  12972. }
  12973. prev = cur;
  12974. cur = cur->next;
  12975. }
  12976. if (neg != NULL) {
  12977. prev = NULL;
  12978. cur = completeWild->nsSet;
  12979. while (cur != NULL) {
  12980. if (cur->value == neg) {
  12981. if (prev == NULL)
  12982. completeWild->nsSet = cur->next;
  12983. else
  12984. prev->next = cur->next;
  12985. xmlFree(cur);
  12986. break;
  12987. }
  12988. prev = cur;
  12989. cur = cur->next;
  12990. }
  12991. }
  12992. return(0);
  12993. }
  12994. /*
  12995. * 4 If both O1 and O2 are sets of (namespace names or `absent`),
  12996. * then the intersection of those sets must be the value.
  12997. */
  12998. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12999. int found;
  13000. cur = completeWild->nsSet;
  13001. prev = NULL;
  13002. while (cur != NULL) {
  13003. found = 0;
  13004. curB = curWild->nsSet;
  13005. while (curB != NULL) {
  13006. if (cur->value == curB->value) {
  13007. found = 1;
  13008. break;
  13009. }
  13010. curB = curB->next;
  13011. }
  13012. if (!found) {
  13013. if (prev == NULL)
  13014. completeWild->nsSet = cur->next;
  13015. else
  13016. prev->next = cur->next;
  13017. tmp = cur->next;
  13018. xmlFree(cur);
  13019. cur = tmp;
  13020. continue;
  13021. }
  13022. prev = cur;
  13023. cur = cur->next;
  13024. }
  13025. return(0);
  13026. }
  13027. /* 5 If the two are negations of different namespace names,
  13028. * then the intersection is not expressible
  13029. */
  13030. if ((completeWild->negNsSet != NULL) &&
  13031. (curWild->negNsSet != NULL) &&
  13032. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13033. (completeWild->negNsSet->value != NULL) &&
  13034. (curWild->negNsSet->value != NULL)) {
  13035. xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
  13036. "The intersection of the wildcard is not expressible.\n",
  13037. NULL, NULL);
  13038. return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
  13039. }
  13040. /*
  13041. * 6 If the one is a negation of a namespace name and the other
  13042. * is a negation of `absent`, then the one which is the negation
  13043. * of a namespace name must be the value.
  13044. */
  13045. if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
  13046. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13047. (completeWild->negNsSet->value == NULL)) {
  13048. completeWild->negNsSet->value = curWild->negNsSet->value;
  13049. }
  13050. return(0);
  13051. }
  13052. /**
  13053. * xmlSchemaIsWildcardNsConstraintSubset:
  13054. * @ctxt: the schema parser context
  13055. * @sub: the first wildcard
  13056. * @super: the second wildcard
  13057. *
  13058. * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
  13059. *
  13060. * Returns 0 if the namespace constraint of @sub is an intensional
  13061. * subset of @super, 1 otherwise.
  13062. */
  13063. static int
  13064. xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
  13065. xmlSchemaWildcardPtr super)
  13066. {
  13067. /*
  13068. * 1 super must be any.
  13069. */
  13070. if (super->any)
  13071. return (0);
  13072. /*
  13073. * 2.1 sub must be a pair of not and a namespace name or `absent`.
  13074. * 2.2 super must be a pair of not and the same value.
  13075. */
  13076. if ((sub->negNsSet != NULL) &&
  13077. (super->negNsSet != NULL) &&
  13078. (sub->negNsSet->value == super->negNsSet->value))
  13079. return (0);
  13080. /*
  13081. * 3.1 sub must be a set whose members are either namespace names or `absent`.
  13082. */
  13083. if (sub->nsSet != NULL) {
  13084. /*
  13085. * 3.2.1 super must be the same set or a superset thereof.
  13086. */
  13087. if (super->nsSet != NULL) {
  13088. xmlSchemaWildcardNsPtr cur, curB;
  13089. int found = 0;
  13090. cur = sub->nsSet;
  13091. while (cur != NULL) {
  13092. found = 0;
  13093. curB = super->nsSet;
  13094. while (curB != NULL) {
  13095. if (cur->value == curB->value) {
  13096. found = 1;
  13097. break;
  13098. }
  13099. curB = curB->next;
  13100. }
  13101. if (!found)
  13102. return (1);
  13103. cur = cur->next;
  13104. }
  13105. if (found)
  13106. return (0);
  13107. } else if (super->negNsSet != NULL) {
  13108. xmlSchemaWildcardNsPtr cur;
  13109. /*
  13110. * 3.2.2 super must be a pair of not and a namespace name or
  13111. * `absent` and that value must not be in sub's set.
  13112. */
  13113. cur = sub->nsSet;
  13114. while (cur != NULL) {
  13115. if (cur->value == super->negNsSet->value)
  13116. return (1);
  13117. cur = cur->next;
  13118. }
  13119. return (0);
  13120. }
  13121. }
  13122. return (1);
  13123. }
  13124. static int
  13125. xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
  13126. int *fixed,
  13127. const xmlChar **value,
  13128. xmlSchemaValPtr *val)
  13129. {
  13130. *fixed = 0;
  13131. *value = NULL;
  13132. if (val != 0)
  13133. *val = NULL;
  13134. if (attruse->defValue != NULL) {
  13135. *value = attruse->defValue;
  13136. if (val != NULL)
  13137. *val = attruse->defVal;
  13138. if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
  13139. *fixed = 1;
  13140. return(1);
  13141. } else if ((attruse->attrDecl != NULL) &&
  13142. (attruse->attrDecl->defValue != NULL)) {
  13143. *value = attruse->attrDecl->defValue;
  13144. if (val != NULL)
  13145. *val = attruse->attrDecl->defVal;
  13146. if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
  13147. *fixed = 1;
  13148. return(1);
  13149. }
  13150. return(0);
  13151. }
  13152. /**
  13153. * xmlSchemaCheckCVCWildcardNamespace:
  13154. * @wild: the wildcard
  13155. * @ns: the namespace
  13156. *
  13157. * Validation Rule: Wildcard allows Namespace Name
  13158. * (cvc-wildcard-namespace)
  13159. *
  13160. * Returns 0 if the given namespace matches the wildcard,
  13161. * 1 otherwise and -1 on API errors.
  13162. */
  13163. static int
  13164. xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
  13165. const xmlChar* ns)
  13166. {
  13167. if (wild == NULL)
  13168. return(-1);
  13169. if (wild->any)
  13170. return(0);
  13171. else if (wild->nsSet != NULL) {
  13172. xmlSchemaWildcardNsPtr cur;
  13173. cur = wild->nsSet;
  13174. while (cur != NULL) {
  13175. if (xmlStrEqual(cur->value, ns))
  13176. return(0);
  13177. cur = cur->next;
  13178. }
  13179. } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
  13180. (!xmlStrEqual(wild->negNsSet->value, ns)))
  13181. return(0);
  13182. return(1);
  13183. }
  13184. #define XML_SCHEMA_ACTION_DERIVE 0
  13185. #define XML_SCHEMA_ACTION_REDEFINE 1
  13186. #define WXS_ACTION_STR(a) \
  13187. ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
  13188. /*
  13189. * Schema Component Constraint:
  13190. * Derivation Valid (Restriction, Complex)
  13191. * derivation-ok-restriction (2) - (4)
  13192. *
  13193. * ATTENTION:
  13194. * In XML Schema 1.1 this will be:
  13195. * Validation Rule:
  13196. * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
  13197. *
  13198. */
  13199. static int
  13200. xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
  13201. int action,
  13202. xmlSchemaBasicItemPtr item,
  13203. xmlSchemaBasicItemPtr baseItem,
  13204. xmlSchemaItemListPtr uses,
  13205. xmlSchemaItemListPtr baseUses,
  13206. xmlSchemaWildcardPtr wild,
  13207. xmlSchemaWildcardPtr baseWild)
  13208. {
  13209. xmlSchemaAttributeUsePtr cur = NULL, bcur;
  13210. int i, j, found; /* err = 0; */
  13211. const xmlChar *bEffValue;
  13212. int effFixed;
  13213. if (uses != NULL) {
  13214. for (i = 0; i < uses->nbItems; i++) {
  13215. cur = uses->items[i];
  13216. found = 0;
  13217. if (baseUses == NULL)
  13218. goto not_found;
  13219. for (j = 0; j < baseUses->nbItems; j++) {
  13220. bcur = baseUses->items[j];
  13221. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13222. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13223. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13224. WXS_ATTRUSE_DECL_TNS(bcur)))
  13225. {
  13226. /*
  13227. * (2.1) "If there is an attribute use in the {attribute
  13228. * uses} of the {base type definition} (call this B) whose
  13229. * {attribute declaration} has the same {name} and {target
  13230. * namespace}, then all of the following must be true:"
  13231. */
  13232. found = 1;
  13233. if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  13234. (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
  13235. {
  13236. xmlChar *str = NULL;
  13237. /*
  13238. * (2.1.1) "one of the following must be true:"
  13239. * (2.1.1.1) "B's {required} is false."
  13240. * (2.1.1.2) "R's {required} is true."
  13241. */
  13242. xmlSchemaPAttrUseErr4(pctxt,
  13243. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
  13244. WXS_ITEM_NODE(item), item, cur,
  13245. "The 'optional' attribute use is inconsistent "
  13246. "with the corresponding 'required' attribute use of "
  13247. "the %s %s",
  13248. WXS_ACTION_STR(action),
  13249. xmlSchemaGetComponentDesignation(&str, baseItem),
  13250. NULL, NULL);
  13251. FREE_AND_NULL(str);
  13252. /* err = pctxt->err; */
  13253. } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  13254. WXS_ATTRUSE_TYPEDEF(cur),
  13255. WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
  13256. {
  13257. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  13258. /*
  13259. * SPEC (2.1.2) "R's {attribute declaration}'s
  13260. * {type definition} must be validly derived from
  13261. * B's {type definition} given the empty set as
  13262. * defined in Type Derivation OK (Simple) ($3.14.6)."
  13263. */
  13264. xmlSchemaPAttrUseErr4(pctxt,
  13265. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
  13266. WXS_ITEM_NODE(item), item, cur,
  13267. "The attribute declaration's %s "
  13268. "is not validly derived from "
  13269. "the corresponding %s of the "
  13270. "attribute declaration in the %s %s",
  13271. xmlSchemaGetComponentDesignation(&strA,
  13272. WXS_ATTRUSE_TYPEDEF(cur)),
  13273. xmlSchemaGetComponentDesignation(&strB,
  13274. WXS_ATTRUSE_TYPEDEF(bcur)),
  13275. WXS_ACTION_STR(action),
  13276. xmlSchemaGetComponentDesignation(&strC, baseItem));
  13277. /* xmlSchemaGetComponentDesignation(&str, baseItem), */
  13278. FREE_AND_NULL(strA);
  13279. FREE_AND_NULL(strB);
  13280. FREE_AND_NULL(strC);
  13281. /* err = pctxt->err; */
  13282. } else {
  13283. /*
  13284. * 2.1.3 [Definition:] Let the effective value
  13285. * constraint of an attribute use be its {value
  13286. * constraint}, if present, otherwise its {attribute
  13287. * declaration}'s {value constraint} .
  13288. */
  13289. xmlSchemaGetEffectiveValueConstraint(bcur,
  13290. &effFixed, &bEffValue, NULL);
  13291. /*
  13292. * 2.1.3 ... one of the following must be true
  13293. *
  13294. * 2.1.3.1 B's `effective value constraint` is
  13295. * `absent` or default.
  13296. */
  13297. if ((bEffValue != NULL) &&
  13298. (effFixed == 1)) {
  13299. const xmlChar *rEffValue = NULL;
  13300. xmlSchemaGetEffectiveValueConstraint(bcur,
  13301. &effFixed, &rEffValue, NULL);
  13302. /*
  13303. * 2.1.3.2 R's `effective value constraint` is
  13304. * fixed with the same string as B's.
  13305. * MAYBE TODO: Compare the computed values.
  13306. * Hmm, it says "same string" so
  13307. * string-equality might really be sufficient.
  13308. */
  13309. if ((effFixed == 0) ||
  13310. (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
  13311. {
  13312. xmlChar *str = NULL;
  13313. xmlSchemaPAttrUseErr4(pctxt,
  13314. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
  13315. WXS_ITEM_NODE(item), item, cur,
  13316. "The effective value constraint of the "
  13317. "attribute use is inconsistent with "
  13318. "its correspondent in the %s %s",
  13319. WXS_ACTION_STR(action),
  13320. xmlSchemaGetComponentDesignation(&str,
  13321. baseItem),
  13322. NULL, NULL);
  13323. FREE_AND_NULL(str);
  13324. /* err = pctxt->err; */
  13325. }
  13326. }
  13327. }
  13328. break;
  13329. }
  13330. }
  13331. not_found:
  13332. if (!found) {
  13333. /*
  13334. * (2.2) "otherwise the {base type definition} must have an
  13335. * {attribute wildcard} and the {target namespace} of the
  13336. * R's {attribute declaration} must be `valid` with respect
  13337. * to that wildcard, as defined in Wildcard allows Namespace
  13338. * Name ($3.10.4)."
  13339. */
  13340. if ((baseWild == NULL) ||
  13341. (xmlSchemaCheckCVCWildcardNamespace(baseWild,
  13342. (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
  13343. {
  13344. xmlChar *str = NULL;
  13345. xmlSchemaPAttrUseErr4(pctxt,
  13346. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
  13347. WXS_ITEM_NODE(item), item, cur,
  13348. "Neither a matching attribute use, "
  13349. "nor a matching wildcard exists in the %s %s",
  13350. WXS_ACTION_STR(action),
  13351. xmlSchemaGetComponentDesignation(&str, baseItem),
  13352. NULL, NULL);
  13353. FREE_AND_NULL(str);
  13354. /* err = pctxt->err; */
  13355. }
  13356. }
  13357. }
  13358. }
  13359. /*
  13360. * SPEC derivation-ok-restriction (3):
  13361. * (3) "For each attribute use in the {attribute uses} of the {base type
  13362. * definition} whose {required} is true, there must be an attribute
  13363. * use with an {attribute declaration} with the same {name} and
  13364. * {target namespace} as its {attribute declaration} in the {attribute
  13365. * uses} of the complex type definition itself whose {required} is true.
  13366. */
  13367. if (baseUses != NULL) {
  13368. for (j = 0; j < baseUses->nbItems; j++) {
  13369. bcur = baseUses->items[j];
  13370. if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
  13371. continue;
  13372. found = 0;
  13373. if (uses != NULL) {
  13374. for (i = 0; i < uses->nbItems; i++) {
  13375. cur = uses->items[i];
  13376. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13377. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13378. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13379. WXS_ATTRUSE_DECL_TNS(bcur))) {
  13380. found = 1;
  13381. break;
  13382. }
  13383. }
  13384. }
  13385. if (!found) {
  13386. xmlChar *strA = NULL, *strB = NULL;
  13387. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13388. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
  13389. NULL, item,
  13390. "A matching attribute use for the "
  13391. "'required' %s of the %s %s is missing",
  13392. xmlSchemaGetComponentDesignation(&strA, bcur),
  13393. WXS_ACTION_STR(action),
  13394. xmlSchemaGetComponentDesignation(&strB, baseItem),
  13395. NULL);
  13396. FREE_AND_NULL(strA);
  13397. FREE_AND_NULL(strB);
  13398. }
  13399. }
  13400. }
  13401. /*
  13402. * derivation-ok-restriction (4)
  13403. */
  13404. if (wild != NULL) {
  13405. /*
  13406. * (4) "If there is an {attribute wildcard}, all of the
  13407. * following must be true:"
  13408. */
  13409. if (baseWild == NULL) {
  13410. xmlChar *str = NULL;
  13411. /*
  13412. * (4.1) "The {base type definition} must also have one."
  13413. */
  13414. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13415. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
  13416. NULL, item,
  13417. "The %s has an attribute wildcard, "
  13418. "but the %s %s '%s' does not have one",
  13419. WXS_ITEM_TYPE_NAME(item),
  13420. WXS_ACTION_STR(action),
  13421. WXS_ITEM_TYPE_NAME(baseItem),
  13422. xmlSchemaGetComponentQName(&str, baseItem));
  13423. FREE_AND_NULL(str);
  13424. return(pctxt->err);
  13425. } else if ((baseWild->any == 0) &&
  13426. xmlSchemaCheckCOSNSSubset(wild, baseWild))
  13427. {
  13428. xmlChar *str = NULL;
  13429. /*
  13430. * (4.2) "The complex type definition's {attribute wildcard}'s
  13431. * {namespace constraint} must be a subset of the {base type
  13432. * definition}'s {attribute wildcard}'s {namespace constraint},
  13433. * as defined by Wildcard Subset ($3.10.6)."
  13434. */
  13435. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13436. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
  13437. NULL, item,
  13438. "The attribute wildcard is not a valid "
  13439. "subset of the wildcard in the %s %s '%s'",
  13440. WXS_ACTION_STR(action),
  13441. WXS_ITEM_TYPE_NAME(baseItem),
  13442. xmlSchemaGetComponentQName(&str, baseItem),
  13443. NULL);
  13444. FREE_AND_NULL(str);
  13445. return(pctxt->err);
  13446. }
  13447. /* 4.3 Unless the {base type definition} is the `ur-type
  13448. * definition`, the complex type definition's {attribute
  13449. * wildcard}'s {process contents} must be identical to or
  13450. * stronger than the {base type definition}'s {attribute
  13451. * wildcard}'s {process contents}, where strict is stronger
  13452. * than lax is stronger than skip.
  13453. */
  13454. if ((! WXS_IS_ANYTYPE(baseItem)) &&
  13455. (wild->processContents < baseWild->processContents)) {
  13456. xmlChar *str = NULL;
  13457. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13458. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
  13459. NULL, baseItem,
  13460. "The {process contents} of the attribute wildcard is "
  13461. "weaker than the one in the %s %s '%s'",
  13462. WXS_ACTION_STR(action),
  13463. WXS_ITEM_TYPE_NAME(baseItem),
  13464. xmlSchemaGetComponentQName(&str, baseItem),
  13465. NULL);
  13466. FREE_AND_NULL(str)
  13467. return(pctxt->err);
  13468. }
  13469. }
  13470. return(0);
  13471. }
  13472. static int
  13473. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  13474. xmlSchemaBasicItemPtr item,
  13475. xmlSchemaWildcardPtr *completeWild,
  13476. xmlSchemaItemListPtr list,
  13477. xmlSchemaItemListPtr prohibs);
  13478. /**
  13479. * xmlSchemaFixupTypeAttributeUses:
  13480. * @ctxt: the schema parser context
  13481. * @type: the complex type definition
  13482. *
  13483. *
  13484. * Builds the wildcard and the attribute uses on the given complex type.
  13485. * Returns -1 if an internal error occurs, 0 otherwise.
  13486. *
  13487. * ATTENTION TODO: Experimentally this uses pointer comparisons for
  13488. * strings, so recheck this if we start to hardcode some schemata, since
  13489. * they might not be in the same dict.
  13490. * NOTE: It is allowed to "extend" the xs:anyType type.
  13491. */
  13492. static int
  13493. xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
  13494. xmlSchemaTypePtr type)
  13495. {
  13496. xmlSchemaTypePtr baseType = NULL;
  13497. xmlSchemaAttributeUsePtr use;
  13498. xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
  13499. if (type->baseType == NULL) {
  13500. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13501. "no base type");
  13502. return (-1);
  13503. }
  13504. baseType = type->baseType;
  13505. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13506. if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
  13507. return(-1);
  13508. uses = type->attrUses;
  13509. baseUses = baseType->attrUses;
  13510. /*
  13511. * Expand attribute group references. And build the 'complete'
  13512. * wildcard, i.e. intersect multiple wildcards.
  13513. * Move attribute prohibitions into a separate list.
  13514. */
  13515. if (uses != NULL) {
  13516. if (WXS_IS_RESTRICTION(type)) {
  13517. /*
  13518. * This one will transfer all attr. prohibitions
  13519. * into pctxt->attrProhibs.
  13520. */
  13521. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13522. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13523. pctxt->attrProhibs) == -1)
  13524. {
  13525. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13526. "failed to expand attributes");
  13527. return(-1);
  13528. }
  13529. if (pctxt->attrProhibs->nbItems != 0)
  13530. prohibs = pctxt->attrProhibs;
  13531. } else {
  13532. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13533. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13534. NULL) == -1)
  13535. {
  13536. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13537. "failed to expand attributes");
  13538. return(-1);
  13539. }
  13540. }
  13541. }
  13542. /*
  13543. * Inherit the attribute uses of the base type.
  13544. */
  13545. if (baseUses != NULL) {
  13546. int i, j;
  13547. xmlSchemaAttributeUseProhibPtr pro;
  13548. if (WXS_IS_RESTRICTION(type)) {
  13549. int usesCount;
  13550. xmlSchemaAttributeUsePtr tmp;
  13551. if (uses != NULL)
  13552. usesCount = uses->nbItems;
  13553. else
  13554. usesCount = 0;
  13555. /* Restriction. */
  13556. for (i = 0; i < baseUses->nbItems; i++) {
  13557. use = baseUses->items[i];
  13558. if (prohibs) {
  13559. /*
  13560. * Filter out prohibited uses.
  13561. */
  13562. for (j = 0; j < prohibs->nbItems; j++) {
  13563. pro = prohibs->items[j];
  13564. if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
  13565. (WXS_ATTRUSE_DECL_TNS(use) ==
  13566. pro->targetNamespace))
  13567. {
  13568. goto inherit_next;
  13569. }
  13570. }
  13571. }
  13572. if (usesCount) {
  13573. /*
  13574. * Filter out existing uses.
  13575. */
  13576. for (j = 0; j < usesCount; j++) {
  13577. tmp = uses->items[j];
  13578. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  13579. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  13580. (WXS_ATTRUSE_DECL_TNS(use) ==
  13581. WXS_ATTRUSE_DECL_TNS(tmp)))
  13582. {
  13583. goto inherit_next;
  13584. }
  13585. }
  13586. }
  13587. if (uses == NULL) {
  13588. type->attrUses = xmlSchemaItemListCreate();
  13589. if (type->attrUses == NULL)
  13590. goto exit_failure;
  13591. uses = type->attrUses;
  13592. }
  13593. xmlSchemaItemListAddSize(uses, 2, use);
  13594. inherit_next: {}
  13595. }
  13596. } else {
  13597. /* Extension. */
  13598. for (i = 0; i < baseUses->nbItems; i++) {
  13599. use = baseUses->items[i];
  13600. if (uses == NULL) {
  13601. type->attrUses = xmlSchemaItemListCreate();
  13602. if (type->attrUses == NULL)
  13603. goto exit_failure;
  13604. uses = type->attrUses;
  13605. }
  13606. xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
  13607. }
  13608. }
  13609. }
  13610. /*
  13611. * Shrink attr. uses.
  13612. */
  13613. if (uses) {
  13614. if (uses->nbItems == 0) {
  13615. xmlSchemaItemListFree(uses);
  13616. type->attrUses = NULL;
  13617. }
  13618. /*
  13619. * TODO: We could shrink the size of the array
  13620. * to fit the actual number of items.
  13621. */
  13622. }
  13623. /*
  13624. * Compute the complete wildcard.
  13625. */
  13626. if (WXS_IS_EXTENSION(type)) {
  13627. if (baseType->attributeWildcard != NULL) {
  13628. /*
  13629. * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
  13630. * the appropriate case among the following:"
  13631. */
  13632. if (type->attributeWildcard != NULL) {
  13633. /*
  13634. * Union the complete wildcard with the base wildcard.
  13635. * SPEC {attribute wildcard}
  13636. * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
  13637. * and {annotation} are those of the `complete wildcard`,
  13638. * and whose {namespace constraint} is the intensional union
  13639. * of the {namespace constraint} of the `complete wildcard`
  13640. * and of the `base wildcard`, as defined in Attribute
  13641. * Wildcard Union ($3.10.6)."
  13642. */
  13643. if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
  13644. baseType->attributeWildcard) == -1)
  13645. goto exit_failure;
  13646. } else {
  13647. /*
  13648. * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
  13649. * then the `base wildcard`."
  13650. */
  13651. type->attributeWildcard = baseType->attributeWildcard;
  13652. }
  13653. } else {
  13654. /*
  13655. * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
  13656. * `complete wildcard`"
  13657. * NOOP
  13658. */
  13659. }
  13660. } else {
  13661. /*
  13662. * SPEC {attribute wildcard}
  13663. * (3.1) "If the <restriction> alternative is chosen, then the
  13664. * `complete wildcard`;"
  13665. * NOOP
  13666. */
  13667. }
  13668. return (0);
  13669. exit_failure:
  13670. return(-1);
  13671. }
  13672. /**
  13673. * xmlSchemaTypeFinalContains:
  13674. * @schema: the schema
  13675. * @type: the type definition
  13676. * @final: the final
  13677. *
  13678. * Evaluates if a type definition contains the given "final".
  13679. * This does take "finalDefault" into account as well.
  13680. *
  13681. * Returns 1 if the type does contain the given "final",
  13682. * 0 otherwise.
  13683. */
  13684. static int
  13685. xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
  13686. {
  13687. if (type == NULL)
  13688. return (0);
  13689. if (type->flags & final)
  13690. return (1);
  13691. else
  13692. return (0);
  13693. }
  13694. /**
  13695. * xmlSchemaGetUnionSimpleTypeMemberTypes:
  13696. * @type: the Union Simple Type
  13697. *
  13698. * Returns a list of member types of @type if existing,
  13699. * returns NULL otherwise.
  13700. */
  13701. static xmlSchemaTypeLinkPtr
  13702. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
  13703. {
  13704. while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
  13705. if (type->memberTypes != NULL)
  13706. return (type->memberTypes);
  13707. else
  13708. type = type->baseType;
  13709. }
  13710. return (NULL);
  13711. }
  13712. #if 0
  13713. /**
  13714. * xmlSchemaGetParticleTotalRangeMin:
  13715. * @particle: the particle
  13716. *
  13717. * Schema Component Constraint: Effective Total Range
  13718. * (all and sequence) + (choice)
  13719. *
  13720. * Returns the minimum Effective Total Range.
  13721. */
  13722. static int
  13723. xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
  13724. {
  13725. if ((particle->children == NULL) ||
  13726. (particle->minOccurs == 0))
  13727. return (0);
  13728. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13729. int min = -1, cur;
  13730. xmlSchemaParticlePtr part =
  13731. (xmlSchemaParticlePtr) particle->children->children;
  13732. if (part == NULL)
  13733. return (0);
  13734. while (part != NULL) {
  13735. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13736. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13737. cur = part->minOccurs;
  13738. else
  13739. cur = xmlSchemaGetParticleTotalRangeMin(part);
  13740. if (cur == 0)
  13741. return (0);
  13742. if ((min > cur) || (min == -1))
  13743. min = cur;
  13744. part = (xmlSchemaParticlePtr) part->next;
  13745. }
  13746. return (particle->minOccurs * min);
  13747. } else {
  13748. /* <all> and <sequence> */
  13749. int sum = 0;
  13750. xmlSchemaParticlePtr part =
  13751. (xmlSchemaParticlePtr) particle->children->children;
  13752. if (part == NULL)
  13753. return (0);
  13754. do {
  13755. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13756. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13757. sum += part->minOccurs;
  13758. else
  13759. sum += xmlSchemaGetParticleTotalRangeMin(part);
  13760. part = (xmlSchemaParticlePtr) part->next;
  13761. } while (part != NULL);
  13762. return (particle->minOccurs * sum);
  13763. }
  13764. }
  13765. /**
  13766. * xmlSchemaGetParticleTotalRangeMax:
  13767. * @particle: the particle
  13768. *
  13769. * Schema Component Constraint: Effective Total Range
  13770. * (all and sequence) + (choice)
  13771. *
  13772. * Returns the maximum Effective Total Range.
  13773. */
  13774. static int
  13775. xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
  13776. {
  13777. if ((particle->children == NULL) ||
  13778. (particle->children->children == NULL))
  13779. return (0);
  13780. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13781. int max = -1, cur;
  13782. xmlSchemaParticlePtr part =
  13783. (xmlSchemaParticlePtr) particle->children->children;
  13784. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13785. if (part->children == NULL)
  13786. continue;
  13787. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13788. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13789. cur = part->maxOccurs;
  13790. else
  13791. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13792. if (cur == UNBOUNDED)
  13793. return (UNBOUNDED);
  13794. if ((max < cur) || (max == -1))
  13795. max = cur;
  13796. }
  13797. /* TODO: Handle overflows? */
  13798. return (particle->maxOccurs * max);
  13799. } else {
  13800. /* <all> and <sequence> */
  13801. int sum = 0, cur;
  13802. xmlSchemaParticlePtr part =
  13803. (xmlSchemaParticlePtr) particle->children->children;
  13804. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13805. if (part->children == NULL)
  13806. continue;
  13807. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13808. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13809. cur = part->maxOccurs;
  13810. else
  13811. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13812. if (cur == UNBOUNDED)
  13813. return (UNBOUNDED);
  13814. if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
  13815. return (UNBOUNDED);
  13816. sum += cur;
  13817. }
  13818. /* TODO: Handle overflows? */
  13819. return (particle->maxOccurs * sum);
  13820. }
  13821. }
  13822. #endif
  13823. /**
  13824. * xmlSchemaGetParticleEmptiable:
  13825. * @particle: the particle
  13826. *
  13827. * Returns 1 if emptiable, 0 otherwise.
  13828. */
  13829. static int
  13830. xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
  13831. {
  13832. xmlSchemaParticlePtr part;
  13833. int emptiable;
  13834. if ((particle->children == NULL) || (particle->minOccurs == 0))
  13835. return (1);
  13836. part = (xmlSchemaParticlePtr) particle->children->children;
  13837. if (part == NULL)
  13838. return (1);
  13839. while (part != NULL) {
  13840. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13841. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13842. emptiable = (part->minOccurs == 0);
  13843. else
  13844. emptiable = xmlSchemaGetParticleEmptiable(part);
  13845. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13846. if (emptiable)
  13847. return (1);
  13848. } else {
  13849. /* <all> and <sequence> */
  13850. if (!emptiable)
  13851. return (0);
  13852. }
  13853. part = (xmlSchemaParticlePtr) part->next;
  13854. }
  13855. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
  13856. return (0);
  13857. else
  13858. return (1);
  13859. }
  13860. /**
  13861. * xmlSchemaIsParticleEmptiable:
  13862. * @particle: the particle
  13863. *
  13864. * Schema Component Constraint: Particle Emptiable
  13865. * Checks whether the given particle is emptiable.
  13866. *
  13867. * Returns 1 if emptiable, 0 otherwise.
  13868. */
  13869. static int
  13870. xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
  13871. {
  13872. /*
  13873. * SPEC (1) "Its {min occurs} is 0."
  13874. */
  13875. if ((particle == NULL) || (particle->minOccurs == 0) ||
  13876. (particle->children == NULL))
  13877. return (1);
  13878. /*
  13879. * SPEC (2) "Its {term} is a group and the minimum part of the
  13880. * effective total range of that group, [...] is 0."
  13881. */
  13882. if (WXS_IS_MODEL_GROUP(particle->children))
  13883. return (xmlSchemaGetParticleEmptiable(particle));
  13884. return (0);
  13885. }
  13886. /**
  13887. * xmlSchemaCheckCOSSTDerivedOK:
  13888. * @actxt: a context
  13889. * @type: the derived simple type definition
  13890. * @baseType: the base type definition
  13891. * @subset: the subset of ('restriction', etc.)
  13892. *
  13893. * Schema Component Constraint:
  13894. * Type Derivation OK (Simple) (cos-st-derived-OK)
  13895. *
  13896. * Checks whether @type can be validly
  13897. * derived from @baseType.
  13898. *
  13899. * Returns 0 on success, an positive error code otherwise.
  13900. */
  13901. static int
  13902. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  13903. xmlSchemaTypePtr type,
  13904. xmlSchemaTypePtr baseType,
  13905. int subset)
  13906. {
  13907. /*
  13908. * 1 They are the same type definition.
  13909. * TODO: The identity check might have to be more complex than this.
  13910. */
  13911. if (type == baseType)
  13912. return (0);
  13913. /*
  13914. * 2.1 restriction is not in the subset, or in the {final}
  13915. * of its own {base type definition};
  13916. *
  13917. * NOTE that this will be used also via "xsi:type".
  13918. *
  13919. * TODO: Revise this, it looks strange. How can the "type"
  13920. * not be fixed or *in* fixing?
  13921. */
  13922. if (WXS_IS_TYPE_NOT_FIXED(type))
  13923. if (xmlSchemaTypeFixup(type, actxt) == -1)
  13924. return(-1);
  13925. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13926. if (xmlSchemaTypeFixup(baseType, actxt) == -1)
  13927. return(-1);
  13928. if ((subset & SUBSET_RESTRICTION) ||
  13929. (xmlSchemaTypeFinalContains(type->baseType,
  13930. XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
  13931. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
  13932. }
  13933. /* 2.2 */
  13934. if (type->baseType == baseType) {
  13935. /*
  13936. * 2.2.1 D's `base type definition` is B.
  13937. */
  13938. return (0);
  13939. }
  13940. /*
  13941. * 2.2.2 D's `base type definition` is not the `ur-type definition`
  13942. * and is validly derived from B given the subset, as defined by this
  13943. * constraint.
  13944. */
  13945. if ((! WXS_IS_ANYTYPE(type->baseType)) &&
  13946. (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  13947. baseType, subset) == 0)) {
  13948. return (0);
  13949. }
  13950. /*
  13951. * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
  13952. * definition`.
  13953. */
  13954. if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
  13955. (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
  13956. return (0);
  13957. }
  13958. /*
  13959. * 2.2.4 B's {variety} is union and D is validly derived from a type
  13960. * definition in B's {member type definitions} given the subset, as
  13961. * defined by this constraint.
  13962. *
  13963. * NOTE: This seems not to involve built-in types, since there is no
  13964. * built-in Union Simple Type.
  13965. */
  13966. if (WXS_IS_UNION(baseType)) {
  13967. xmlSchemaTypeLinkPtr cur;
  13968. cur = baseType->memberTypes;
  13969. while (cur != NULL) {
  13970. if (WXS_IS_TYPE_NOT_FIXED(cur->type))
  13971. if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
  13972. return(-1);
  13973. if (xmlSchemaCheckCOSSTDerivedOK(actxt,
  13974. type, cur->type, subset) == 0)
  13975. {
  13976. /*
  13977. * It just has to be validly derived from at least one
  13978. * member-type.
  13979. */
  13980. return (0);
  13981. }
  13982. cur = cur->next;
  13983. }
  13984. }
  13985. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
  13986. }
  13987. /**
  13988. * xmlSchemaCheckTypeDefCircularInternal:
  13989. * @pctxt: the schema parser context
  13990. * @ctxtType: the type definition
  13991. * @ancestor: an ancestor of @ctxtType
  13992. *
  13993. * Checks st-props-correct (2) + ct-props-correct (3).
  13994. * Circular type definitions are not allowed.
  13995. *
  13996. * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
  13997. * circular, 0 otherwise.
  13998. */
  13999. static int
  14000. xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
  14001. xmlSchemaTypePtr ctxtType,
  14002. xmlSchemaTypePtr ancestor)
  14003. {
  14004. int ret;
  14005. if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
  14006. return (0);
  14007. if (ctxtType == ancestor) {
  14008. xmlSchemaPCustomErr(pctxt,
  14009. XML_SCHEMAP_ST_PROPS_CORRECT_2,
  14010. WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
  14011. "The definition is circular", NULL);
  14012. return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
  14013. }
  14014. if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
  14015. /*
  14016. * Avoid infinite recursion on circular types not yet checked.
  14017. */
  14018. return (0);
  14019. }
  14020. ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
  14021. ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
  14022. ancestor->baseType);
  14023. ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14024. return (ret);
  14025. }
  14026. /**
  14027. * xmlSchemaCheckTypeDefCircular:
  14028. * @item: the complex/simple type definition
  14029. * @ctxt: the parser context
  14030. * @name: the name
  14031. *
  14032. * Checks for circular type definitions.
  14033. */
  14034. static void
  14035. xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
  14036. xmlSchemaParserCtxtPtr ctxt)
  14037. {
  14038. if ((item == NULL) ||
  14039. (item->type == XML_SCHEMA_TYPE_BASIC) ||
  14040. (item->baseType == NULL))
  14041. return;
  14042. xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
  14043. item->baseType);
  14044. }
  14045. /*
  14046. * Simple Type Definition Representation OK (src-simple-type) 4
  14047. *
  14048. * "4 Circular union type definition is disallowed. That is, if the
  14049. * <union> alternative is chosen, there must not be any entries in the
  14050. * memberTypes [attribute] at any depth which resolve to the component
  14051. * corresponding to the <simpleType>."
  14052. *
  14053. * Note that this should work on the *representation* of a component,
  14054. * thus assumes any union types in the member types not being yet
  14055. * substituted. At this stage we need the variety of the types
  14056. * to be already computed.
  14057. */
  14058. static int
  14059. xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
  14060. xmlSchemaTypePtr ctxType,
  14061. xmlSchemaTypeLinkPtr members)
  14062. {
  14063. xmlSchemaTypeLinkPtr member;
  14064. xmlSchemaTypePtr memberType;
  14065. member = members;
  14066. while (member != NULL) {
  14067. memberType = member->type;
  14068. while ((memberType != NULL) &&
  14069. (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
  14070. if (memberType == ctxType) {
  14071. xmlSchemaPCustomErr(pctxt,
  14072. XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
  14073. WXS_BASIC_CAST ctxType, NULL,
  14074. "The union type definition is circular", NULL);
  14075. return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
  14076. }
  14077. if ((WXS_IS_UNION(memberType)) &&
  14078. ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
  14079. {
  14080. int res;
  14081. memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
  14082. res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
  14083. ctxType,
  14084. xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
  14085. memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14086. if (res != 0)
  14087. return(res);
  14088. }
  14089. memberType = memberType->baseType;
  14090. }
  14091. member = member->next;
  14092. }
  14093. return(0);
  14094. }
  14095. static int
  14096. xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
  14097. xmlSchemaTypePtr type)
  14098. {
  14099. if (! WXS_IS_UNION(type))
  14100. return(0);
  14101. return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
  14102. type->memberTypes));
  14103. }
  14104. /**
  14105. * xmlSchemaResolveTypeReferences:
  14106. * @item: the complex/simple type definition
  14107. * @ctxt: the parser context
  14108. * @name: the name
  14109. *
  14110. * Resolves type definition references
  14111. */
  14112. static void
  14113. xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
  14114. xmlSchemaParserCtxtPtr ctxt)
  14115. {
  14116. if (typeDef == NULL)
  14117. return;
  14118. /*
  14119. * Resolve the base type.
  14120. */
  14121. if (typeDef->baseType == NULL) {
  14122. typeDef->baseType = xmlSchemaGetType(ctxt->schema,
  14123. typeDef->base, typeDef->baseNs);
  14124. if (typeDef->baseType == NULL) {
  14125. xmlSchemaPResCompAttrErr(ctxt,
  14126. XML_SCHEMAP_SRC_RESOLVE,
  14127. WXS_BASIC_CAST typeDef, typeDef->node,
  14128. "base", typeDef->base, typeDef->baseNs,
  14129. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14130. return;
  14131. }
  14132. }
  14133. if (WXS_IS_SIMPLE(typeDef)) {
  14134. if (WXS_IS_UNION(typeDef)) {
  14135. /*
  14136. * Resolve the memberTypes.
  14137. */
  14138. xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
  14139. return;
  14140. } else if (WXS_IS_LIST(typeDef)) {
  14141. /*
  14142. * Resolve the itemType.
  14143. */
  14144. if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
  14145. typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
  14146. typeDef->base, typeDef->baseNs);
  14147. if ((typeDef->subtypes == NULL) ||
  14148. (! WXS_IS_SIMPLE(typeDef->subtypes)))
  14149. {
  14150. typeDef->subtypes = NULL;
  14151. xmlSchemaPResCompAttrErr(ctxt,
  14152. XML_SCHEMAP_SRC_RESOLVE,
  14153. WXS_BASIC_CAST typeDef, typeDef->node,
  14154. "itemType", typeDef->base, typeDef->baseNs,
  14155. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14156. }
  14157. }
  14158. return;
  14159. }
  14160. }
  14161. /*
  14162. * The ball of letters below means, that if we have a particle
  14163. * which has a QName-helper component as its {term}, we want
  14164. * to resolve it...
  14165. */
  14166. else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
  14167. ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
  14168. XML_SCHEMA_TYPE_PARTICLE) &&
  14169. (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
  14170. ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
  14171. XML_SCHEMA_EXTRA_QNAMEREF))
  14172. {
  14173. xmlSchemaQNameRefPtr ref =
  14174. WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
  14175. xmlSchemaModelGroupDefPtr groupDef;
  14176. /*
  14177. * URGENT TODO: Test this.
  14178. */
  14179. WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
  14180. /*
  14181. * Resolve the MG definition reference.
  14182. */
  14183. groupDef =
  14184. WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
  14185. ref->itemType, ref->name, ref->targetNamespace);
  14186. if (groupDef == NULL) {
  14187. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  14188. NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
  14189. "ref", ref->name, ref->targetNamespace, ref->itemType,
  14190. NULL);
  14191. /* Remove the particle. */
  14192. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14193. } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
  14194. /* Remove the particle. */
  14195. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14196. else {
  14197. /*
  14198. * Assign the MG definition's {model group} to the
  14199. * particle's {term}.
  14200. */
  14201. WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
  14202. if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
  14203. /*
  14204. * SPEC cos-all-limited (1.2)
  14205. * "1.2 the {term} property of a particle with
  14206. * {max occurs}=1 which is part of a pair which constitutes
  14207. * the {content type} of a complex type definition."
  14208. */
  14209. if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
  14210. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  14211. /* TODO: error code */
  14212. XML_SCHEMAP_COS_ALL_LIMITED,
  14213. WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
  14214. "The particle's {max occurs} must be 1, since the "
  14215. "reference resolves to an 'all' model group",
  14216. NULL, NULL);
  14217. }
  14218. }
  14219. }
  14220. }
  14221. }
  14222. /**
  14223. * xmlSchemaCheckSTPropsCorrect:
  14224. * @ctxt: the schema parser context
  14225. * @type: the simple type definition
  14226. *
  14227. * Checks st-props-correct.
  14228. *
  14229. * Returns 0 if the properties are correct,
  14230. * if not, a positive error code and -1 on internal
  14231. * errors.
  14232. */
  14233. static int
  14234. xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  14235. xmlSchemaTypePtr type)
  14236. {
  14237. xmlSchemaTypePtr baseType = type->baseType;
  14238. xmlChar *str = NULL;
  14239. /* STATE: error funcs converted. */
  14240. /*
  14241. * Schema Component Constraint: Simple Type Definition Properties Correct
  14242. *
  14243. * NOTE: This is somehow redundant, since we actually built a simple type
  14244. * to have all the needed information; this acts as an self test.
  14245. */
  14246. /* Base type: If the datatype has been `derived` by `restriction`
  14247. * then the Simple Type Definition component from which it is `derived`,
  14248. * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
  14249. */
  14250. if (baseType == NULL) {
  14251. /*
  14252. * TODO: Think about: "modulo the impact of Missing
  14253. * Sub-components ($5.3)."
  14254. */
  14255. xmlSchemaPCustomErr(ctxt,
  14256. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14257. WXS_BASIC_CAST type, NULL,
  14258. "No base type existent", NULL);
  14259. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14260. }
  14261. if (! WXS_IS_SIMPLE(baseType)) {
  14262. xmlSchemaPCustomErr(ctxt,
  14263. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14264. WXS_BASIC_CAST type, NULL,
  14265. "The base type '%s' is not a simple type",
  14266. xmlSchemaGetComponentQName(&str, baseType));
  14267. FREE_AND_NULL(str)
  14268. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14269. }
  14270. if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
  14271. (WXS_IS_RESTRICTION(type) == 0) &&
  14272. ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
  14273. (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
  14274. xmlSchemaPCustomErr(ctxt,
  14275. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14276. WXS_BASIC_CAST type, NULL,
  14277. "A type, derived by list or union, must have "
  14278. "the simple ur-type definition as base type, not '%s'",
  14279. xmlSchemaGetComponentQName(&str, baseType));
  14280. FREE_AND_NULL(str)
  14281. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14282. }
  14283. /*
  14284. * Variety: One of {atomic, list, union}.
  14285. */
  14286. if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
  14287. (! WXS_IS_LIST(type))) {
  14288. xmlSchemaPCustomErr(ctxt,
  14289. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14290. WXS_BASIC_CAST type, NULL,
  14291. "The variety is absent", NULL);
  14292. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14293. }
  14294. /* TODO: Finish this. Hmm, is this finished? */
  14295. /*
  14296. * 3 The {final} of the {base type definition} must not contain restriction.
  14297. */
  14298. if (xmlSchemaTypeFinalContains(baseType,
  14299. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14300. xmlSchemaPCustomErr(ctxt,
  14301. XML_SCHEMAP_ST_PROPS_CORRECT_3,
  14302. WXS_BASIC_CAST type, NULL,
  14303. "The 'final' of its base type '%s' must not contain "
  14304. "'restriction'",
  14305. xmlSchemaGetComponentQName(&str, baseType));
  14306. FREE_AND_NULL(str)
  14307. return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
  14308. }
  14309. /*
  14310. * 2 All simple type definitions must be derived ultimately from the `simple
  14311. * ur-type definition` (so circular definitions are disallowed). That is, it
  14312. * must be possible to reach a built-in primitive datatype or the `simple
  14313. * ur-type definition` by repeatedly following the {base type definition}.
  14314. *
  14315. * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
  14316. */
  14317. return (0);
  14318. }
  14319. /**
  14320. * xmlSchemaCheckCOSSTRestricts:
  14321. * @ctxt: the schema parser context
  14322. * @type: the simple type definition
  14323. *
  14324. * Schema Component Constraint:
  14325. * Derivation Valid (Restriction, Simple) (cos-st-restricts)
  14326. * Checks if the given @type (simpleType) is derived validly by restriction.
  14327. * STATUS:
  14328. *
  14329. * Returns -1 on internal errors, 0 if the type is validly derived,
  14330. * a positive error code otherwise.
  14331. */
  14332. static int
  14333. xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
  14334. xmlSchemaTypePtr type)
  14335. {
  14336. xmlChar *str = NULL;
  14337. if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
  14338. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14339. "given type is not a user-derived simpleType");
  14340. return (-1);
  14341. }
  14342. if (WXS_IS_ATOMIC(type)) {
  14343. xmlSchemaTypePtr primitive;
  14344. /*
  14345. * 1.1 The {base type definition} must be an atomic simple
  14346. * type definition or a built-in primitive datatype.
  14347. */
  14348. if (! WXS_IS_ATOMIC(type->baseType)) {
  14349. xmlSchemaPCustomErr(pctxt,
  14350. XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
  14351. WXS_BASIC_CAST type, NULL,
  14352. "The base type '%s' is not an atomic simple type",
  14353. xmlSchemaGetComponentQName(&str, type->baseType));
  14354. FREE_AND_NULL(str)
  14355. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
  14356. }
  14357. /* 1.2 The {final} of the {base type definition} must not contain
  14358. * restriction.
  14359. */
  14360. /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
  14361. if (xmlSchemaTypeFinalContains(type->baseType,
  14362. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14363. xmlSchemaPCustomErr(pctxt,
  14364. XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
  14365. WXS_BASIC_CAST type, NULL,
  14366. "The final of its base type '%s' must not contain 'restriction'",
  14367. xmlSchemaGetComponentQName(&str, type->baseType));
  14368. FREE_AND_NULL(str)
  14369. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
  14370. }
  14371. /*
  14372. * 1.3.1 DF must be an allowed constraining facet for the {primitive
  14373. * type definition}, as specified in the appropriate subsection of 3.2
  14374. * Primitive datatypes.
  14375. */
  14376. if (type->facets != NULL) {
  14377. xmlSchemaFacetPtr facet;
  14378. int ok = 1;
  14379. primitive = xmlSchemaGetPrimitiveType(type);
  14380. if (primitive == NULL) {
  14381. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14382. "failed to get primitive type");
  14383. return (-1);
  14384. }
  14385. facet = type->facets;
  14386. do {
  14387. if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
  14388. ok = 0;
  14389. xmlSchemaPIllegalFacetAtomicErr(pctxt,
  14390. XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
  14391. type, primitive, facet);
  14392. }
  14393. facet = facet->next;
  14394. } while (facet != NULL);
  14395. if (ok == 0)
  14396. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
  14397. }
  14398. /*
  14399. * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
  14400. * of the {base type definition} (call this BF),then the DF's {value}
  14401. * must be a valid restriction of BF's {value} as defined in
  14402. * [XML Schemas: Datatypes]."
  14403. *
  14404. * NOTE (1.3.2) Facet derivation constraints are currently handled in
  14405. * xmlSchemaDeriveAndValidateFacets()
  14406. */
  14407. } else if (WXS_IS_LIST(type)) {
  14408. xmlSchemaTypePtr itemType = NULL;
  14409. itemType = type->subtypes;
  14410. if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
  14411. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14412. "failed to evaluate the item type");
  14413. return (-1);
  14414. }
  14415. if (WXS_IS_TYPE_NOT_FIXED(itemType))
  14416. xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
  14417. /*
  14418. * 2.1 The {item type definition} must have a {variety} of atomic or
  14419. * union (in which case all the {member type definitions}
  14420. * must be atomic).
  14421. */
  14422. if ((! WXS_IS_ATOMIC(itemType)) &&
  14423. (! WXS_IS_UNION(itemType))) {
  14424. xmlSchemaPCustomErr(pctxt,
  14425. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14426. WXS_BASIC_CAST type, NULL,
  14427. "The item type '%s' does not have a variety of atomic or union",
  14428. xmlSchemaGetComponentQName(&str, itemType));
  14429. FREE_AND_NULL(str)
  14430. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14431. } else if (WXS_IS_UNION(itemType)) {
  14432. xmlSchemaTypeLinkPtr member;
  14433. member = itemType->memberTypes;
  14434. while (member != NULL) {
  14435. if (! WXS_IS_ATOMIC(member->type)) {
  14436. xmlSchemaPCustomErr(pctxt,
  14437. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14438. WXS_BASIC_CAST type, NULL,
  14439. "The item type is a union type, but the "
  14440. "member type '%s' of this item type is not atomic",
  14441. xmlSchemaGetComponentQName(&str, member->type));
  14442. FREE_AND_NULL(str)
  14443. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14444. }
  14445. member = member->next;
  14446. }
  14447. }
  14448. if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
  14449. xmlSchemaFacetPtr facet;
  14450. /*
  14451. * This is the case if we have: <simpleType><list ..
  14452. */
  14453. /*
  14454. * 2.3.1
  14455. * 2.3.1.1 The {final} of the {item type definition} must not
  14456. * contain list.
  14457. */
  14458. if (xmlSchemaTypeFinalContains(itemType,
  14459. XML_SCHEMAS_TYPE_FINAL_LIST)) {
  14460. xmlSchemaPCustomErr(pctxt,
  14461. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
  14462. WXS_BASIC_CAST type, NULL,
  14463. "The final of its item type '%s' must not contain 'list'",
  14464. xmlSchemaGetComponentQName(&str, itemType));
  14465. FREE_AND_NULL(str)
  14466. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
  14467. }
  14468. /*
  14469. * 2.3.1.2 The {facets} must only contain the whiteSpace
  14470. * facet component.
  14471. * OPTIMIZE TODO: the S4S already disallows any facet
  14472. * to be specified.
  14473. */
  14474. if (type->facets != NULL) {
  14475. facet = type->facets;
  14476. do {
  14477. if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
  14478. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14479. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
  14480. type, facet);
  14481. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
  14482. }
  14483. facet = facet->next;
  14484. } while (facet != NULL);
  14485. }
  14486. /*
  14487. * MAYBE TODO: (Hmm, not really) Datatypes states:
  14488. * A `list` datatype can be `derived` from an `atomic` datatype
  14489. * whose `lexical space` allows space (such as string or anyURI)or
  14490. * a `union` datatype any of whose {member type definitions}'s
  14491. * `lexical space` allows space.
  14492. */
  14493. } else {
  14494. /*
  14495. * This is the case if we have: <simpleType><restriction ...
  14496. * I.e. the variety of "list" is inherited.
  14497. */
  14498. /*
  14499. * 2.3.2
  14500. * 2.3.2.1 The {base type definition} must have a {variety} of list.
  14501. */
  14502. if (! WXS_IS_LIST(type->baseType)) {
  14503. xmlSchemaPCustomErr(pctxt,
  14504. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
  14505. WXS_BASIC_CAST type, NULL,
  14506. "The base type '%s' must be a list type",
  14507. xmlSchemaGetComponentQName(&str, type->baseType));
  14508. FREE_AND_NULL(str)
  14509. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
  14510. }
  14511. /*
  14512. * 2.3.2.2 The {final} of the {base type definition} must not
  14513. * contain restriction.
  14514. */
  14515. if (xmlSchemaTypeFinalContains(type->baseType,
  14516. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14517. xmlSchemaPCustomErr(pctxt,
  14518. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
  14519. WXS_BASIC_CAST type, NULL,
  14520. "The 'final' of the base type '%s' must not contain 'restriction'",
  14521. xmlSchemaGetComponentQName(&str, type->baseType));
  14522. FREE_AND_NULL(str)
  14523. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
  14524. }
  14525. /*
  14526. * 2.3.2.3 The {item type definition} must be validly derived
  14527. * from the {base type definition}'s {item type definition} given
  14528. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
  14529. */
  14530. {
  14531. xmlSchemaTypePtr baseItemType;
  14532. baseItemType = type->baseType->subtypes;
  14533. if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
  14534. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14535. "failed to eval the item type of a base type");
  14536. return (-1);
  14537. }
  14538. if ((itemType != baseItemType) &&
  14539. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
  14540. baseItemType, 0) != 0)) {
  14541. xmlChar *strBIT = NULL, *strBT = NULL;
  14542. xmlSchemaPCustomErrExt(pctxt,
  14543. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
  14544. WXS_BASIC_CAST type, NULL,
  14545. "The item type '%s' is not validly derived from "
  14546. "the item type '%s' of the base type '%s'",
  14547. xmlSchemaGetComponentQName(&str, itemType),
  14548. xmlSchemaGetComponentQName(&strBIT, baseItemType),
  14549. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14550. FREE_AND_NULL(str)
  14551. FREE_AND_NULL(strBIT)
  14552. FREE_AND_NULL(strBT)
  14553. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
  14554. }
  14555. }
  14556. if (type->facets != NULL) {
  14557. xmlSchemaFacetPtr facet;
  14558. int ok = 1;
  14559. /*
  14560. * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
  14561. * and enumeration facet components are allowed among the {facets}.
  14562. */
  14563. facet = type->facets;
  14564. do {
  14565. switch (facet->type) {
  14566. case XML_SCHEMA_FACET_LENGTH:
  14567. case XML_SCHEMA_FACET_MINLENGTH:
  14568. case XML_SCHEMA_FACET_MAXLENGTH:
  14569. case XML_SCHEMA_FACET_WHITESPACE:
  14570. /*
  14571. * TODO: 2.5.1.2 List datatypes
  14572. * The value of `whiteSpace` is fixed to the value collapse.
  14573. */
  14574. case XML_SCHEMA_FACET_PATTERN:
  14575. case XML_SCHEMA_FACET_ENUMERATION:
  14576. break;
  14577. default: {
  14578. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14579. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
  14580. type, facet);
  14581. /*
  14582. * We could return, but it's nicer to report all
  14583. * invalid facets.
  14584. */
  14585. ok = 0;
  14586. }
  14587. }
  14588. facet = facet->next;
  14589. } while (facet != NULL);
  14590. if (ok == 0)
  14591. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
  14592. /*
  14593. * SPEC (2.3.2.5) (same as 1.3.2)
  14594. *
  14595. * NOTE (2.3.2.5) This is currently done in
  14596. * xmlSchemaDeriveAndValidateFacets()
  14597. */
  14598. }
  14599. }
  14600. } else if (WXS_IS_UNION(type)) {
  14601. /*
  14602. * 3.1 The {member type definitions} must all have {variety} of
  14603. * atomic or list.
  14604. */
  14605. xmlSchemaTypeLinkPtr member;
  14606. member = type->memberTypes;
  14607. while (member != NULL) {
  14608. if (WXS_IS_TYPE_NOT_FIXED(member->type))
  14609. xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
  14610. if ((! WXS_IS_ATOMIC(member->type)) &&
  14611. (! WXS_IS_LIST(member->type))) {
  14612. xmlSchemaPCustomErr(pctxt,
  14613. XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
  14614. WXS_BASIC_CAST type, NULL,
  14615. "The member type '%s' is neither an atomic, nor a list type",
  14616. xmlSchemaGetComponentQName(&str, member->type));
  14617. FREE_AND_NULL(str)
  14618. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
  14619. }
  14620. member = member->next;
  14621. }
  14622. /*
  14623. * 3.3.1 If the {base type definition} is the `simple ur-type
  14624. * definition`
  14625. */
  14626. if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
  14627. /*
  14628. * 3.3.1.1 All of the {member type definitions} must have a
  14629. * {final} which does not contain union.
  14630. */
  14631. member = type->memberTypes;
  14632. while (member != NULL) {
  14633. if (xmlSchemaTypeFinalContains(member->type,
  14634. XML_SCHEMAS_TYPE_FINAL_UNION)) {
  14635. xmlSchemaPCustomErr(pctxt,
  14636. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
  14637. WXS_BASIC_CAST type, NULL,
  14638. "The 'final' of member type '%s' contains 'union'",
  14639. xmlSchemaGetComponentQName(&str, member->type));
  14640. FREE_AND_NULL(str)
  14641. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
  14642. }
  14643. member = member->next;
  14644. }
  14645. /*
  14646. * 3.3.1.2 The {facets} must be empty.
  14647. */
  14648. if (type->facetSet != NULL) {
  14649. xmlSchemaPCustomErr(pctxt,
  14650. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
  14651. WXS_BASIC_CAST type, NULL,
  14652. "No facets allowed", NULL);
  14653. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
  14654. }
  14655. } else {
  14656. /*
  14657. * 3.3.2.1 The {base type definition} must have a {variety} of union.
  14658. * I.e. the variety of "list" is inherited.
  14659. */
  14660. if (! WXS_IS_UNION(type->baseType)) {
  14661. xmlSchemaPCustomErr(pctxt,
  14662. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
  14663. WXS_BASIC_CAST type, NULL,
  14664. "The base type '%s' is not a union type",
  14665. xmlSchemaGetComponentQName(&str, type->baseType));
  14666. FREE_AND_NULL(str)
  14667. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
  14668. }
  14669. /*
  14670. * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
  14671. */
  14672. if (xmlSchemaTypeFinalContains(type->baseType,
  14673. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14674. xmlSchemaPCustomErr(pctxt,
  14675. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
  14676. WXS_BASIC_CAST type, NULL,
  14677. "The 'final' of its base type '%s' must not contain 'restriction'",
  14678. xmlSchemaGetComponentQName(&str, type->baseType));
  14679. FREE_AND_NULL(str)
  14680. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
  14681. }
  14682. /*
  14683. * 3.3.2.3 The {member type definitions}, in order, must be validly
  14684. * derived from the corresponding type definitions in the {base
  14685. * type definition}'s {member type definitions} given the empty set,
  14686. * as defined in Type Derivation OK (Simple) ($3.14.6).
  14687. */
  14688. {
  14689. xmlSchemaTypeLinkPtr baseMember;
  14690. /*
  14691. * OPTIMIZE: if the type is restricting, it has no local defined
  14692. * member types and inherits the member types of the base type;
  14693. * thus a check for equality can be skipped.
  14694. */
  14695. /*
  14696. * Even worse: I cannot see a scenario where a restricting
  14697. * union simple type can have other member types as the member
  14698. * types of it's base type. This check seems not necessary with
  14699. * respect to the derivation process in libxml2.
  14700. * But necessary if constructing types with an API.
  14701. */
  14702. if (type->memberTypes != NULL) {
  14703. member = type->memberTypes;
  14704. baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
  14705. if ((member == NULL) && (baseMember != NULL)) {
  14706. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14707. "different number of member types in base");
  14708. }
  14709. while (member != NULL) {
  14710. if (baseMember == NULL) {
  14711. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14712. "different number of member types in base");
  14713. } else if ((member->type != baseMember->type) &&
  14714. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  14715. member->type, baseMember->type, 0) != 0)) {
  14716. xmlChar *strBMT = NULL, *strBT = NULL;
  14717. xmlSchemaPCustomErrExt(pctxt,
  14718. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
  14719. WXS_BASIC_CAST type, NULL,
  14720. "The member type %s is not validly "
  14721. "derived from its corresponding member "
  14722. "type %s of the base type %s",
  14723. xmlSchemaGetComponentQName(&str, member->type),
  14724. xmlSchemaGetComponentQName(&strBMT, baseMember->type),
  14725. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14726. FREE_AND_NULL(str)
  14727. FREE_AND_NULL(strBMT)
  14728. FREE_AND_NULL(strBT)
  14729. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
  14730. }
  14731. member = member->next;
  14732. if (baseMember != NULL)
  14733. baseMember = baseMember->next;
  14734. }
  14735. }
  14736. }
  14737. /*
  14738. * 3.3.2.4 Only pattern and enumeration facet components are
  14739. * allowed among the {facets}.
  14740. */
  14741. if (type->facets != NULL) {
  14742. xmlSchemaFacetPtr facet;
  14743. int ok = 1;
  14744. facet = type->facets;
  14745. do {
  14746. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  14747. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  14748. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14749. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
  14750. type, facet);
  14751. ok = 0;
  14752. }
  14753. facet = facet->next;
  14754. } while (facet != NULL);
  14755. if (ok == 0)
  14756. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
  14757. }
  14758. /*
  14759. * SPEC (3.3.2.5) (same as 1.3.2)
  14760. *
  14761. * NOTE (3.3.2.5) This is currently done in
  14762. * xmlSchemaDeriveAndValidateFacets()
  14763. */
  14764. }
  14765. }
  14766. return (0);
  14767. }
  14768. /**
  14769. * xmlSchemaCheckSRCSimpleType:
  14770. * @ctxt: the schema parser context
  14771. * @type: the simple type definition
  14772. *
  14773. * Checks crc-simple-type constraints.
  14774. *
  14775. * Returns 0 if the constraints are satisfied,
  14776. * if not a positive error code and -1 on internal
  14777. * errors.
  14778. */
  14779. #if 0
  14780. static int
  14781. xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
  14782. xmlSchemaTypePtr type)
  14783. {
  14784. /*
  14785. * src-simple-type.1 The corresponding simple type definition, if any,
  14786. * must satisfy the conditions set out in Constraints on Simple Type
  14787. * Definition Schema Components ($3.14.6).
  14788. */
  14789. if (WXS_IS_RESTRICTION(type)) {
  14790. /*
  14791. * src-simple-type.2 "If the <restriction> alternative is chosen,
  14792. * either it must have a base [attribute] or a <simpleType> among its
  14793. * [children], but not both."
  14794. * NOTE: This is checked in the parse function of <restriction>.
  14795. */
  14796. /*
  14797. *
  14798. */
  14799. } else if (WXS_IS_LIST(type)) {
  14800. /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
  14801. * an itemType [attribute] or a <simpleType> among its [children],
  14802. * but not both."
  14803. *
  14804. * NOTE: This is checked in the parse function of <list>.
  14805. */
  14806. } else if (WXS_IS_UNION(type)) {
  14807. /*
  14808. * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
  14809. */
  14810. }
  14811. return (0);
  14812. }
  14813. #endif
  14814. static int
  14815. xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
  14816. {
  14817. if (ctxt->vctxt == NULL) {
  14818. ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
  14819. if (ctxt->vctxt == NULL) {
  14820. xmlSchemaPErr(ctxt, NULL,
  14821. XML_SCHEMAP_INTERNAL,
  14822. "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
  14823. "failed to create a temp. validation context.\n",
  14824. NULL, NULL);
  14825. return (-1);
  14826. }
  14827. /* TODO: Pass user data. */
  14828. xmlSchemaSetValidErrors(ctxt->vctxt,
  14829. ctxt->error, ctxt->warning, ctxt->errCtxt);
  14830. xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
  14831. ctxt->serror, ctxt->errCtxt);
  14832. }
  14833. return (0);
  14834. }
  14835. static int
  14836. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  14837. xmlNodePtr node,
  14838. xmlSchemaTypePtr type,
  14839. const xmlChar *value,
  14840. xmlSchemaValPtr *retVal,
  14841. int fireErrors,
  14842. int normalize,
  14843. int isNormalized);
  14844. /**
  14845. * xmlSchemaParseCheckCOSValidDefault:
  14846. * @pctxt: the schema parser context
  14847. * @type: the simple type definition
  14848. * @value: the default value
  14849. * @node: an optional node (the holder of the value)
  14850. *
  14851. * Schema Component Constraint: Element Default Valid (Immediate)
  14852. * (cos-valid-default)
  14853. * This will be used by the parser only. For the validator there's
  14854. * an other version.
  14855. *
  14856. * Returns 0 if the constraints are satisfied,
  14857. * if not, a positive error code and -1 on internal
  14858. * errors.
  14859. */
  14860. static int
  14861. xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  14862. xmlNodePtr node,
  14863. xmlSchemaTypePtr type,
  14864. const xmlChar *value,
  14865. xmlSchemaValPtr *val)
  14866. {
  14867. int ret = 0;
  14868. /*
  14869. * cos-valid-default:
  14870. * Schema Component Constraint: Element Default Valid (Immediate)
  14871. * For a string to be a valid default with respect to a type
  14872. * definition the appropriate case among the following must be true:
  14873. */
  14874. if WXS_IS_COMPLEX(type) {
  14875. /*
  14876. * Complex type.
  14877. *
  14878. * SPEC (2.1) "its {content type} must be a simple type definition
  14879. * or mixed."
  14880. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  14881. * type}'s particle must be `emptiable` as defined by
  14882. * Particle Emptiable ($3.9.6)."
  14883. */
  14884. if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
  14885. ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
  14886. /* NOTE that this covers (2.2.2) as well. */
  14887. xmlSchemaPCustomErr(pctxt,
  14888. XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
  14889. WXS_BASIC_CAST type, type->node,
  14890. "For a string to be a valid default, the type definition "
  14891. "must be a simple type or a complex type with mixed content "
  14892. "and a particle emptiable", NULL);
  14893. return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
  14894. }
  14895. }
  14896. /*
  14897. * 1 If the type definition is a simple type definition, then the string
  14898. * must be `valid` with respect to that definition as defined by String
  14899. * Valid ($3.14.4).
  14900. *
  14901. * AND
  14902. *
  14903. * 2.2.1 If the {content type} is a simple type definition, then the
  14904. * string must be `valid` with respect to that simple type definition
  14905. * as defined by String Valid ($3.14.4).
  14906. */
  14907. if (WXS_IS_SIMPLE(type))
  14908. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14909. type, value, val, 1, 1, 0);
  14910. else if (WXS_HAS_SIMPLE_CONTENT(type))
  14911. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14912. type->contentTypeDef, value, val, 1, 1, 0);
  14913. else
  14914. return (ret);
  14915. if (ret < 0) {
  14916. PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
  14917. "calling xmlSchemaVCheckCVCSimpleType()");
  14918. }
  14919. return (ret);
  14920. }
  14921. /**
  14922. * xmlSchemaCheckCTPropsCorrect:
  14923. * @ctxt: the schema parser context
  14924. * @type: the complex type definition
  14925. *
  14926. *.(4.6) Constraints on Complex Type Definition Schema Components
  14927. * Schema Component Constraint:
  14928. * Complex Type Definition Properties Correct (ct-props-correct)
  14929. * STATUS: (seems) complete
  14930. *
  14931. * Returns 0 if the constraints are satisfied, a positive
  14932. * error code if not and -1 if an internal error occurred.
  14933. */
  14934. static int
  14935. xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  14936. xmlSchemaTypePtr type)
  14937. {
  14938. /*
  14939. * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
  14940. *
  14941. * SPEC (1) "The values of the properties of a complex type definition must
  14942. * be as described in the property tableau in The Complex Type Definition
  14943. * Schema Component ($3.4.1), modulo the impact of Missing
  14944. * Sub-components ($5.3)."
  14945. */
  14946. if ((type->baseType != NULL) &&
  14947. (WXS_IS_SIMPLE(type->baseType)) &&
  14948. (WXS_IS_EXTENSION(type) == 0)) {
  14949. /*
  14950. * SPEC (2) "If the {base type definition} is a simple type definition,
  14951. * the {derivation method} must be extension."
  14952. */
  14953. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14954. XML_SCHEMAP_SRC_CT_1,
  14955. NULL, WXS_BASIC_CAST type,
  14956. "If the base type is a simple type, the derivation method must be "
  14957. "'extension'", NULL, NULL);
  14958. return (XML_SCHEMAP_SRC_CT_1);
  14959. }
  14960. /*
  14961. * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
  14962. * definition`. That is, it must be possible to reach the `ur-type
  14963. * definition` by repeatedly following the {base type definition}."
  14964. *
  14965. * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
  14966. */
  14967. /*
  14968. * NOTE that (4) and (5) need the following:
  14969. * - attribute uses need to be already inherited (apply attr. prohibitions)
  14970. * - attribute group references need to be expanded already
  14971. * - simple types need to be typefixed already
  14972. */
  14973. if (type->attrUses &&
  14974. (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
  14975. {
  14976. xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
  14977. xmlSchemaAttributeUsePtr use, tmp;
  14978. int i, j, hasId = 0;
  14979. for (i = uses->nbItems -1; i >= 0; i--) {
  14980. use = uses->items[i];
  14981. /*
  14982. * SPEC ct-props-correct
  14983. * (4) "Two distinct attribute declarations in the
  14984. * {attribute uses} must not have identical {name}s and
  14985. * {target namespace}s."
  14986. */
  14987. if (i > 0) {
  14988. for (j = i -1; j >= 0; j--) {
  14989. tmp = uses->items[j];
  14990. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  14991. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  14992. (WXS_ATTRUSE_DECL_TNS(use) ==
  14993. WXS_ATTRUSE_DECL_TNS(tmp)))
  14994. {
  14995. xmlChar *str = NULL;
  14996. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14997. XML_SCHEMAP_AG_PROPS_CORRECT,
  14998. NULL, WXS_BASIC_CAST type,
  14999. "Duplicate %s",
  15000. xmlSchemaGetComponentDesignation(&str, use),
  15001. NULL);
  15002. FREE_AND_NULL(str);
  15003. /*
  15004. * Remove the duplicate.
  15005. */
  15006. if (xmlSchemaItemListRemove(uses, i) == -1)
  15007. goto exit_failure;
  15008. goto next_use;
  15009. }
  15010. }
  15011. }
  15012. /*
  15013. * SPEC ct-props-correct
  15014. * (5) "Two distinct attribute declarations in the
  15015. * {attribute uses} must not have {type definition}s which
  15016. * are or are derived from ID."
  15017. */
  15018. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  15019. if (xmlSchemaIsDerivedFromBuiltInType(
  15020. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  15021. {
  15022. if (hasId) {
  15023. xmlChar *str = NULL;
  15024. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15025. XML_SCHEMAP_AG_PROPS_CORRECT,
  15026. NULL, WXS_BASIC_CAST type,
  15027. "There must not exist more than one attribute "
  15028. "declaration of type 'xs:ID' "
  15029. "(or derived from 'xs:ID'). The %s violates this "
  15030. "constraint",
  15031. xmlSchemaGetComponentDesignation(&str, use),
  15032. NULL);
  15033. FREE_AND_NULL(str);
  15034. if (xmlSchemaItemListRemove(uses, i) == -1)
  15035. goto exit_failure;
  15036. }
  15037. hasId = 1;
  15038. }
  15039. }
  15040. next_use: {}
  15041. }
  15042. }
  15043. return (0);
  15044. exit_failure:
  15045. return(-1);
  15046. }
  15047. static int
  15048. xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
  15049. xmlSchemaTypePtr typeB)
  15050. {
  15051. /*
  15052. * TODO: This should implement component-identity
  15053. * in the future.
  15054. */
  15055. if ((typeA == NULL) || (typeB == NULL))
  15056. return (0);
  15057. return (typeA == typeB);
  15058. }
  15059. /**
  15060. * xmlSchemaCheckCOSCTDerivedOK:
  15061. * @ctxt: the schema parser context
  15062. * @type: the to-be derived complex type definition
  15063. * @baseType: the base complex type definition
  15064. * @set: the given set
  15065. *
  15066. * Schema Component Constraint:
  15067. * Type Derivation OK (Complex) (cos-ct-derived-ok)
  15068. *
  15069. * STATUS: completed
  15070. *
  15071. * Returns 0 if the constraints are satisfied, or 1
  15072. * if not.
  15073. */
  15074. static int
  15075. xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15076. xmlSchemaTypePtr type,
  15077. xmlSchemaTypePtr baseType,
  15078. int set)
  15079. {
  15080. int equal = xmlSchemaAreEqualTypes(type, baseType);
  15081. /* TODO: Error codes. */
  15082. /*
  15083. * SPEC "For a complex type definition (call it D, for derived)
  15084. * to be validly derived from a type definition (call this
  15085. * B, for base) given a subset of {extension, restriction}
  15086. * all of the following must be true:"
  15087. */
  15088. if (! equal) {
  15089. /*
  15090. * SPEC (1) "If B and D are not the same type definition, then the
  15091. * {derivation method} of D must not be in the subset."
  15092. */
  15093. if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
  15094. ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
  15095. return (1);
  15096. } else {
  15097. /*
  15098. * SPEC (2.1) "B and D must be the same type definition."
  15099. */
  15100. return (0);
  15101. }
  15102. /*
  15103. * SPEC (2.2) "B must be D's {base type definition}."
  15104. */
  15105. if (type->baseType == baseType)
  15106. return (0);
  15107. /*
  15108. * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
  15109. * definition`."
  15110. */
  15111. if (WXS_IS_ANYTYPE(type->baseType))
  15112. return (1);
  15113. if (WXS_IS_COMPLEX(type->baseType)) {
  15114. /*
  15115. * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
  15116. * must be validly derived from B given the subset as defined by this
  15117. * constraint."
  15118. */
  15119. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
  15120. baseType, set));
  15121. } else {
  15122. /*
  15123. * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
  15124. * must be validly derived from B given the subset as defined in Type
  15125. * Derivation OK (Simple) ($3.14.6).
  15126. */
  15127. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  15128. baseType, set));
  15129. }
  15130. }
  15131. /**
  15132. * xmlSchemaCheckCOSDerivedOK:
  15133. * @type: the derived simple type definition
  15134. * @baseType: the base type definition
  15135. *
  15136. * Calls:
  15137. * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
  15138. *
  15139. * Checks whether @type can be validly derived from @baseType.
  15140. *
  15141. * Returns 0 on success, an positive error code otherwise.
  15142. */
  15143. static int
  15144. xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15145. xmlSchemaTypePtr type,
  15146. xmlSchemaTypePtr baseType,
  15147. int set)
  15148. {
  15149. if (WXS_IS_SIMPLE(type))
  15150. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
  15151. else
  15152. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
  15153. }
  15154. /**
  15155. * xmlSchemaCheckCOSCTExtends:
  15156. * @ctxt: the schema parser context
  15157. * @type: the complex type definition
  15158. *
  15159. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15160. * Schema Component Constraint:
  15161. * Derivation Valid (Extension) (cos-ct-extends)
  15162. *
  15163. * STATUS:
  15164. * missing:
  15165. * (1.5)
  15166. * (1.4.3.2.2.2) "Particle Valid (Extension)"
  15167. *
  15168. * Returns 0 if the constraints are satisfied, a positive
  15169. * error code if not and -1 if an internal error occurred.
  15170. */
  15171. static int
  15172. xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  15173. xmlSchemaTypePtr type)
  15174. {
  15175. xmlSchemaTypePtr base = type->baseType;
  15176. /*
  15177. * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
  15178. * temporarily only.
  15179. */
  15180. /*
  15181. * SPEC (1) "If the {base type definition} is a complex type definition,
  15182. * then all of the following must be true:"
  15183. */
  15184. if (WXS_IS_COMPLEX(base)) {
  15185. /*
  15186. * SPEC (1.1) "The {final} of the {base type definition} must not
  15187. * contain extension."
  15188. */
  15189. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15190. xmlSchemaPCustomErr(ctxt,
  15191. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15192. WXS_BASIC_CAST type, NULL,
  15193. "The 'final' of the base type definition "
  15194. "contains 'extension'", NULL);
  15195. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15196. }
  15197. /*
  15198. * ATTENTION: The constrains (1.2) and (1.3) are not applied,
  15199. * since they are automatically satisfied through the
  15200. * inheriting mechanism.
  15201. * Note that even if redefining components, the inheriting mechanism
  15202. * is used.
  15203. */
  15204. #if 0
  15205. /*
  15206. * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
  15207. * uses}
  15208. * of the complex type definition itself, that is, for every attribute
  15209. * use in the {attribute uses} of the {base type definition}, there
  15210. * must be an attribute use in the {attribute uses} of the complex
  15211. * type definition itself whose {attribute declaration} has the same
  15212. * {name}, {target namespace} and {type definition} as its attribute
  15213. * declaration"
  15214. */
  15215. if (base->attrUses != NULL) {
  15216. int i, j, found;
  15217. xmlSchemaAttributeUsePtr use, buse;
  15218. for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
  15219. buse = (WXS_LIST_CAST base->attrUses)->items[i];
  15220. found = 0;
  15221. if (type->attrUses != NULL) {
  15222. use = (WXS_LIST_CAST type->attrUses)->items[j];
  15223. for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
  15224. {
  15225. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15226. WXS_ATTRUSE_DECL_NAME(buse)) &&
  15227. (WXS_ATTRUSE_DECL_TNS(use) ==
  15228. WXS_ATTRUSE_DECL_TNS(buse)) &&
  15229. (WXS_ATTRUSE_TYPEDEF(use) ==
  15230. WXS_ATTRUSE_TYPEDEF(buse))
  15231. {
  15232. found = 1;
  15233. break;
  15234. }
  15235. }
  15236. }
  15237. if (! found) {
  15238. xmlChar *str = NULL;
  15239. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15240. XML_SCHEMAP_COS_CT_EXTENDS_1_2,
  15241. NULL, WXS_BASIC_CAST type,
  15242. /*
  15243. * TODO: The report does not indicate that also the
  15244. * type needs to be the same.
  15245. */
  15246. "This type is missing a matching correspondent "
  15247. "for its {base type}'s %s in its {attribute uses}",
  15248. xmlSchemaGetComponentDesignation(&str,
  15249. buse->children),
  15250. NULL);
  15251. FREE_AND_NULL(str)
  15252. }
  15253. }
  15254. }
  15255. /*
  15256. * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
  15257. * definition must also have one, and the base type definition's
  15258. * {attribute wildcard}'s {namespace constraint} must be a subset
  15259. * of the complex type definition's {attribute wildcard}'s {namespace
  15260. * constraint}, as defined by Wildcard Subset ($3.10.6)."
  15261. */
  15262. /*
  15263. * MAYBE TODO: Enable if ever needed. But this will be needed only
  15264. * if created the type via a schema construction API.
  15265. */
  15266. if (base->attributeWildcard != NULL) {
  15267. if (type->attributeWildcard == NULL) {
  15268. xmlChar *str = NULL;
  15269. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15270. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15271. NULL, type,
  15272. "The base %s has an attribute wildcard, "
  15273. "but this type is missing an attribute wildcard",
  15274. xmlSchemaGetComponentDesignation(&str, base));
  15275. FREE_AND_NULL(str)
  15276. } else if (xmlSchemaCheckCOSNSSubset(
  15277. base->attributeWildcard, type->attributeWildcard))
  15278. {
  15279. xmlChar *str = NULL;
  15280. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15281. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15282. NULL, type,
  15283. "The attribute wildcard is not a valid "
  15284. "superset of the one in the base %s",
  15285. xmlSchemaGetComponentDesignation(&str, base));
  15286. FREE_AND_NULL(str)
  15287. }
  15288. }
  15289. #endif
  15290. /*
  15291. * SPEC (1.4) "One of the following must be true:"
  15292. */
  15293. if ((type->contentTypeDef != NULL) &&
  15294. (type->contentTypeDef == base->contentTypeDef)) {
  15295. /*
  15296. * SPEC (1.4.1) "The {content type} of the {base type definition}
  15297. * and the {content type} of the complex type definition itself
  15298. * must be the same simple type definition"
  15299. * PASS
  15300. */
  15301. } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
  15302. (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
  15303. /*
  15304. * SPEC (1.4.2) "The {content type} of both the {base type
  15305. * definition} and the complex type definition itself must
  15306. * be empty."
  15307. * PASS
  15308. */
  15309. } else {
  15310. /*
  15311. * SPEC (1.4.3) "All of the following must be true:"
  15312. */
  15313. if (type->subtypes == NULL) {
  15314. /*
  15315. * SPEC 1.4.3.1 The {content type} of the complex type
  15316. * definition itself must specify a particle.
  15317. */
  15318. xmlSchemaPCustomErr(ctxt,
  15319. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15320. WXS_BASIC_CAST type, NULL,
  15321. "The content type must specify a particle", NULL);
  15322. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15323. }
  15324. /*
  15325. * SPEC (1.4.3.2) "One of the following must be true:"
  15326. */
  15327. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15328. /*
  15329. * SPEC (1.4.3.2.1) "The {content type} of the {base type
  15330. * definition} must be empty.
  15331. * PASS
  15332. */
  15333. } else {
  15334. /*
  15335. * SPEC (1.4.3.2.2) "All of the following must be true:"
  15336. */
  15337. if ((type->contentType != base->contentType) ||
  15338. ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
  15339. (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
  15340. /*
  15341. * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
  15342. * or both must be element-only."
  15343. */
  15344. xmlSchemaPCustomErr(ctxt,
  15345. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15346. WXS_BASIC_CAST type, NULL,
  15347. "The content type of both, the type and its base "
  15348. "type, must either 'mixed' or 'element-only'", NULL);
  15349. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15350. }
  15351. /*
  15352. * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
  15353. * complex type definition must be a `valid extension`
  15354. * of the {base type definition}'s particle, as defined
  15355. * in Particle Valid (Extension) ($3.9.6)."
  15356. *
  15357. * NOTE that we won't check "Particle Valid (Extension)",
  15358. * since it is ensured by the derivation process in
  15359. * xmlSchemaTypeFixup(). We need to implement this when heading
  15360. * for a construction API
  15361. * TODO: !! This is needed to be checked if redefining a type !!
  15362. */
  15363. }
  15364. /*
  15365. * URGENT TODO (1.5)
  15366. */
  15367. }
  15368. } else {
  15369. /*
  15370. * SPEC (2) "If the {base type definition} is a simple type definition,
  15371. * then all of the following must be true:"
  15372. */
  15373. if (type->contentTypeDef != base) {
  15374. /*
  15375. * SPEC (2.1) "The {content type} must be the same simple type
  15376. * definition."
  15377. */
  15378. xmlSchemaPCustomErr(ctxt,
  15379. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15380. WXS_BASIC_CAST type, NULL,
  15381. "The content type must be the simple base type", NULL);
  15382. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15383. }
  15384. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15385. /*
  15386. * SPEC (2.2) "The {final} of the {base type definition} must not
  15387. * contain extension"
  15388. * NOTE that this is the same as (1.1).
  15389. */
  15390. xmlSchemaPCustomErr(ctxt,
  15391. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15392. WXS_BASIC_CAST type, NULL,
  15393. "The 'final' of the base type definition "
  15394. "contains 'extension'", NULL);
  15395. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15396. }
  15397. }
  15398. return (0);
  15399. }
  15400. /**
  15401. * xmlSchemaCheckDerivationOKRestriction:
  15402. * @ctxt: the schema parser context
  15403. * @type: the complex type definition
  15404. *
  15405. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15406. * Schema Component Constraint:
  15407. * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
  15408. *
  15409. * STATUS:
  15410. * missing:
  15411. * (5.4.2) ???
  15412. *
  15413. * ATTENTION:
  15414. * In XML Schema 1.1 this will be:
  15415. * Validation Rule: Checking complex type subsumption
  15416. *
  15417. * Returns 0 if the constraints are satisfied, a positive
  15418. * error code if not and -1 if an internal error occurred.
  15419. */
  15420. static int
  15421. xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  15422. xmlSchemaTypePtr type)
  15423. {
  15424. xmlSchemaTypePtr base;
  15425. /*
  15426. * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
  15427. * temporarily only.
  15428. */
  15429. base = type->baseType;
  15430. if (! WXS_IS_COMPLEX(base)) {
  15431. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15432. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15433. type->node, WXS_BASIC_CAST type,
  15434. "The base type must be a complex type", NULL, NULL);
  15435. return(ctxt->err);
  15436. }
  15437. if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
  15438. /*
  15439. * SPEC (1) "The {base type definition} must be a complex type
  15440. * definition whose {final} does not contain restriction."
  15441. */
  15442. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15443. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15444. type->node, WXS_BASIC_CAST type,
  15445. "The 'final' of the base type definition "
  15446. "contains 'restriction'", NULL, NULL);
  15447. return (ctxt->err);
  15448. }
  15449. /*
  15450. * SPEC (2), (3) and (4)
  15451. * Those are handled in a separate function, since the
  15452. * same constraints are needed for redefinition of
  15453. * attribute groups as well.
  15454. */
  15455. if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
  15456. XML_SCHEMA_ACTION_DERIVE,
  15457. WXS_BASIC_CAST type, WXS_BASIC_CAST base,
  15458. type->attrUses, base->attrUses,
  15459. type->attributeWildcard,
  15460. base->attributeWildcard) == -1)
  15461. {
  15462. return(-1);
  15463. }
  15464. /*
  15465. * SPEC (5) "One of the following must be true:"
  15466. */
  15467. if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
  15468. /*
  15469. * SPEC (5.1) "The {base type definition} must be the
  15470. * `ur-type definition`."
  15471. * PASS
  15472. */
  15473. } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15474. (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15475. /*
  15476. * SPEC (5.2.1) "The {content type} of the complex type definition
  15477. * must be a simple type definition"
  15478. *
  15479. * SPEC (5.2.2) "One of the following must be true:"
  15480. */
  15481. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15482. (base->contentType == XML_SCHEMA_CONTENT_BASIC))
  15483. {
  15484. int err;
  15485. /*
  15486. * SPEC (5.2.2.1) "The {content type} of the {base type
  15487. * definition} must be a simple type definition from which
  15488. * the {content type} is validly derived given the empty
  15489. * set as defined in Type Derivation OK (Simple) ($3.14.6)."
  15490. *
  15491. * ATTENTION TODO: This seems not needed if the type implicitly
  15492. * derived from the base type.
  15493. *
  15494. */
  15495. err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
  15496. type->contentTypeDef, base->contentTypeDef, 0);
  15497. if (err != 0) {
  15498. xmlChar *strA = NULL, *strB = NULL;
  15499. if (err == -1)
  15500. return(-1);
  15501. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15502. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15503. NULL, WXS_BASIC_CAST type,
  15504. "The {content type} %s is not validly derived from the "
  15505. "base type's {content type} %s",
  15506. xmlSchemaGetComponentDesignation(&strA,
  15507. type->contentTypeDef),
  15508. xmlSchemaGetComponentDesignation(&strB,
  15509. base->contentTypeDef));
  15510. FREE_AND_NULL(strA);
  15511. FREE_AND_NULL(strB);
  15512. return(ctxt->err);
  15513. }
  15514. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15515. (xmlSchemaIsParticleEmptiable(
  15516. (xmlSchemaParticlePtr) base->subtypes))) {
  15517. /*
  15518. * SPEC (5.2.2.2) "The {base type definition} must be mixed
  15519. * and have a particle which is `emptiable` as defined in
  15520. * Particle Emptiable ($3.9.6)."
  15521. * PASS
  15522. */
  15523. } else {
  15524. xmlSchemaPCustomErr(ctxt,
  15525. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15526. WXS_BASIC_CAST type, NULL,
  15527. "The content type of the base type must be either "
  15528. "a simple type or 'mixed' and an emptiable particle", NULL);
  15529. return (ctxt->err);
  15530. }
  15531. } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15532. /*
  15533. * SPEC (5.3.1) "The {content type} of the complex type itself must
  15534. * be empty"
  15535. */
  15536. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15537. /*
  15538. * SPEC (5.3.2.1) "The {content type} of the {base type
  15539. * definition} must also be empty."
  15540. * PASS
  15541. */
  15542. } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15543. (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
  15544. xmlSchemaIsParticleEmptiable(
  15545. (xmlSchemaParticlePtr) base->subtypes)) {
  15546. /*
  15547. * SPEC (5.3.2.2) "The {content type} of the {base type
  15548. * definition} must be elementOnly or mixed and have a particle
  15549. * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
  15550. * PASS
  15551. */
  15552. } else {
  15553. xmlSchemaPCustomErr(ctxt,
  15554. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15555. WXS_BASIC_CAST type, NULL,
  15556. "The content type of the base type must be either "
  15557. "empty or 'mixed' (or 'elements-only') and an emptiable "
  15558. "particle", NULL);
  15559. return (ctxt->err);
  15560. }
  15561. } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15562. WXS_HAS_MIXED_CONTENT(type)) {
  15563. /*
  15564. * SPEC (5.4.1.1) "The {content type} of the complex type definition
  15565. * itself must be element-only"
  15566. */
  15567. if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
  15568. /*
  15569. * SPEC (5.4.1.2) "The {content type} of the complex type
  15570. * definition itself and of the {base type definition} must be
  15571. * mixed"
  15572. */
  15573. xmlSchemaPCustomErr(ctxt,
  15574. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15575. WXS_BASIC_CAST type, NULL,
  15576. "If the content type is 'mixed', then the content type of the "
  15577. "base type must also be 'mixed'", NULL);
  15578. return (ctxt->err);
  15579. }
  15580. /*
  15581. * SPEC (5.4.2) "The particle of the complex type definition itself
  15582. * must be a `valid restriction` of the particle of the {content
  15583. * type} of the {base type definition} as defined in Particle Valid
  15584. * (Restriction) ($3.9.6).
  15585. *
  15586. * URGENT TODO: (5.4.2)
  15587. */
  15588. } else {
  15589. xmlSchemaPCustomErr(ctxt,
  15590. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15591. WXS_BASIC_CAST type, NULL,
  15592. "The type is not a valid restriction of its base type", NULL);
  15593. return (ctxt->err);
  15594. }
  15595. return (0);
  15596. }
  15597. /**
  15598. * xmlSchemaCheckCTComponent:
  15599. * @ctxt: the schema parser context
  15600. * @type: the complex type definition
  15601. *
  15602. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15603. *
  15604. * Returns 0 if the constraints are satisfied, a positive
  15605. * error code if not and -1 if an internal error occurred.
  15606. */
  15607. static int
  15608. xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  15609. xmlSchemaTypePtr type)
  15610. {
  15611. int ret;
  15612. /*
  15613. * Complex Type Definition Properties Correct
  15614. */
  15615. ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
  15616. if (ret != 0)
  15617. return (ret);
  15618. if (WXS_IS_EXTENSION(type))
  15619. ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
  15620. else
  15621. ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
  15622. return (ret);
  15623. }
  15624. /**
  15625. * xmlSchemaCheckSRCCT:
  15626. * @ctxt: the schema parser context
  15627. * @type: the complex type definition
  15628. *
  15629. * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
  15630. * Schema Representation Constraint:
  15631. * Complex Type Definition Representation OK (src-ct)
  15632. *
  15633. * Returns 0 if the constraints are satisfied, a positive
  15634. * error code if not and -1 if an internal error occurred.
  15635. */
  15636. static int
  15637. xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  15638. xmlSchemaTypePtr type)
  15639. {
  15640. xmlSchemaTypePtr base;
  15641. int ret = 0;
  15642. /*
  15643. * TODO: Adjust the error codes here, as I used
  15644. * XML_SCHEMAP_SRC_CT_1 only yet.
  15645. */
  15646. base = type->baseType;
  15647. if (! WXS_HAS_SIMPLE_CONTENT(type)) {
  15648. /*
  15649. * 1 If the <complexContent> alternative is chosen, the type definition
  15650. * `resolved` to by the `actual value` of the base [attribute]
  15651. * must be a complex type definition;
  15652. */
  15653. if (! WXS_IS_COMPLEX(base)) {
  15654. xmlChar *str = NULL;
  15655. xmlSchemaPCustomErr(ctxt,
  15656. XML_SCHEMAP_SRC_CT_1,
  15657. WXS_BASIC_CAST type, type->node,
  15658. "If using <complexContent>, the base type is expected to be "
  15659. "a complex type. The base type '%s' is a simple type",
  15660. xmlSchemaFormatQName(&str, base->targetNamespace,
  15661. base->name));
  15662. FREE_AND_NULL(str)
  15663. return (XML_SCHEMAP_SRC_CT_1);
  15664. }
  15665. } else {
  15666. /*
  15667. * SPEC
  15668. * 2 If the <simpleContent> alternative is chosen, all of the
  15669. * following must be true:
  15670. * 2.1 The type definition `resolved` to by the `actual value` of the
  15671. * base [attribute] must be one of the following:
  15672. */
  15673. if (WXS_IS_SIMPLE(base)) {
  15674. if (WXS_IS_EXTENSION(type) == 0) {
  15675. xmlChar *str = NULL;
  15676. /*
  15677. * 2.1.3 only if the <extension> alternative is also
  15678. * chosen, a simple type definition.
  15679. */
  15680. /* TODO: Change error code to ..._SRC_CT_2_1_3. */
  15681. xmlSchemaPCustomErr(ctxt,
  15682. XML_SCHEMAP_SRC_CT_1,
  15683. WXS_BASIC_CAST type, NULL,
  15684. "If using <simpleContent> and <restriction>, the base "
  15685. "type must be a complex type. The base type '%s' is "
  15686. "a simple type",
  15687. xmlSchemaFormatQName(&str, base->targetNamespace,
  15688. base->name));
  15689. FREE_AND_NULL(str)
  15690. return (XML_SCHEMAP_SRC_CT_1);
  15691. }
  15692. } else {
  15693. /* Base type is a complex type. */
  15694. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15695. (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15696. /*
  15697. * 2.1.1 a complex type definition whose {content type} is a
  15698. * simple type definition;
  15699. * PASS
  15700. */
  15701. if (base->contentTypeDef == NULL) {
  15702. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
  15703. WXS_BASIC_CAST type, NULL,
  15704. "Internal error: xmlSchemaCheckSRCCT, "
  15705. "'%s', base type has no content type",
  15706. type->name);
  15707. return (-1);
  15708. }
  15709. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15710. (WXS_IS_RESTRICTION(type))) {
  15711. /*
  15712. * 2.1.2 only if the <restriction> alternative is also
  15713. * chosen, a complex type definition whose {content type}
  15714. * is mixed and a particle emptiable.
  15715. */
  15716. if (! xmlSchemaIsParticleEmptiable(
  15717. (xmlSchemaParticlePtr) base->subtypes)) {
  15718. ret = XML_SCHEMAP_SRC_CT_1;
  15719. } else
  15720. /*
  15721. * Attention: at this point the <simpleType> child is in
  15722. * ->contentTypeDef (put there during parsing).
  15723. */
  15724. if (type->contentTypeDef == NULL) {
  15725. xmlChar *str = NULL;
  15726. /*
  15727. * 2.2 If clause 2.1.2 above is satisfied, then there
  15728. * must be a <simpleType> among the [children] of
  15729. * <restriction>.
  15730. */
  15731. /* TODO: Change error code to ..._SRC_CT_2_2. */
  15732. xmlSchemaPCustomErr(ctxt,
  15733. XML_SCHEMAP_SRC_CT_1,
  15734. WXS_BASIC_CAST type, NULL,
  15735. "A <simpleType> is expected among the children "
  15736. "of <restriction>, if <simpleContent> is used and "
  15737. "the base type '%s' is a complex type",
  15738. xmlSchemaFormatQName(&str, base->targetNamespace,
  15739. base->name));
  15740. FREE_AND_NULL(str)
  15741. return (XML_SCHEMAP_SRC_CT_1);
  15742. }
  15743. } else {
  15744. ret = XML_SCHEMAP_SRC_CT_1;
  15745. }
  15746. }
  15747. if (ret > 0) {
  15748. xmlChar *str = NULL;
  15749. if (WXS_IS_RESTRICTION(type)) {
  15750. xmlSchemaPCustomErr(ctxt,
  15751. XML_SCHEMAP_SRC_CT_1,
  15752. WXS_BASIC_CAST type, NULL,
  15753. "If <simpleContent> and <restriction> is used, the "
  15754. "base type must be a simple type or a complex type with "
  15755. "mixed content and particle emptiable. The base type "
  15756. "'%s' is none of those",
  15757. xmlSchemaFormatQName(&str, base->targetNamespace,
  15758. base->name));
  15759. } else {
  15760. xmlSchemaPCustomErr(ctxt,
  15761. XML_SCHEMAP_SRC_CT_1,
  15762. WXS_BASIC_CAST type, NULL,
  15763. "If <simpleContent> and <extension> is used, the "
  15764. "base type must be a simple type. The base type '%s' "
  15765. "is a complex type",
  15766. xmlSchemaFormatQName(&str, base->targetNamespace,
  15767. base->name));
  15768. }
  15769. FREE_AND_NULL(str)
  15770. }
  15771. }
  15772. /*
  15773. * SPEC (3) "The corresponding complex type definition component must
  15774. * satisfy the conditions set out in Constraints on Complex Type
  15775. * Definition Schema Components ($3.4.6);"
  15776. * NOTE (3) will be done in xmlSchemaTypeFixup().
  15777. */
  15778. /*
  15779. * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
  15780. * above for {attribute wildcard} is satisfied, the intensional
  15781. * intersection must be expressible, as defined in Attribute Wildcard
  15782. * Intersection ($3.10.6).
  15783. * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
  15784. */
  15785. return (ret);
  15786. }
  15787. #ifdef ENABLE_PARTICLE_RESTRICTION
  15788. /**
  15789. * xmlSchemaCheckParticleRangeOK:
  15790. * @ctxt: the schema parser context
  15791. * @type: the complex type definition
  15792. *
  15793. * (3.9.6) Constraints on Particle Schema Components
  15794. * Schema Component Constraint:
  15795. * Occurrence Range OK (range-ok)
  15796. *
  15797. * STATUS: complete
  15798. *
  15799. * Returns 0 if the constraints are satisfied, a positive
  15800. * error code if not and -1 if an internal error occurred.
  15801. */
  15802. static int
  15803. xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  15804. int bmin, int bmax)
  15805. {
  15806. if (rmin < bmin)
  15807. return (1);
  15808. if ((bmax != UNBOUNDED) &&
  15809. (rmax > bmax))
  15810. return (1);
  15811. return (0);
  15812. }
  15813. /**
  15814. * xmlSchemaCheckRCaseNameAndTypeOK:
  15815. * @ctxt: the schema parser context
  15816. * @r: the restricting element declaration particle
  15817. * @b: the base element declaration particle
  15818. *
  15819. * (3.9.6) Constraints on Particle Schema Components
  15820. * Schema Component Constraint:
  15821. * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
  15822. * (rcase-NameAndTypeOK)
  15823. *
  15824. * STATUS:
  15825. * MISSING (3.2.3)
  15826. * CLARIFY: (3.2.2)
  15827. *
  15828. * Returns 0 if the constraints are satisfied, a positive
  15829. * error code if not and -1 if an internal error occurred.
  15830. */
  15831. static int
  15832. xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  15833. xmlSchemaParticlePtr r,
  15834. xmlSchemaParticlePtr b)
  15835. {
  15836. xmlSchemaElementPtr elemR, elemB;
  15837. /* TODO: Error codes (rcase-NameAndTypeOK). */
  15838. elemR = (xmlSchemaElementPtr) r->children;
  15839. elemB = (xmlSchemaElementPtr) b->children;
  15840. /*
  15841. * SPEC (1) "The declarations' {name}s and {target namespace}s are
  15842. * the same."
  15843. */
  15844. if ((elemR != elemB) &&
  15845. ((! xmlStrEqual(elemR->name, elemB->name)) ||
  15846. (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
  15847. return (1);
  15848. /*
  15849. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15850. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15851. */
  15852. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15853. b->minOccurs, b->maxOccurs) != 0)
  15854. return (1);
  15855. /*
  15856. * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
  15857. * {scope} are global."
  15858. */
  15859. if (elemR == elemB)
  15860. return (0);
  15861. /*
  15862. * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
  15863. */
  15864. if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
  15865. (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
  15866. return (1);
  15867. /*
  15868. * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
  15869. * or is not fixed, or R's declaration's {value constraint} is fixed
  15870. * with the same value."
  15871. */
  15872. if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
  15873. ((elemR->value == NULL) ||
  15874. ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
  15875. /* TODO: Equality of the initial value or normalized or canonical? */
  15876. (! xmlStrEqual(elemR->value, elemB->value))))
  15877. return (1);
  15878. /*
  15879. * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
  15880. * definitions} is a subset of B's declaration's {identity-constraint
  15881. * definitions}, if any."
  15882. */
  15883. if (elemB->idcs != NULL) {
  15884. /* TODO */
  15885. }
  15886. /*
  15887. * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
  15888. * superset of B's declaration's {disallowed substitutions}."
  15889. */
  15890. if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
  15891. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
  15892. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
  15893. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
  15894. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
  15895. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
  15896. return (1);
  15897. /*
  15898. * SPEC (3.2.5) "R's {type definition} is validly derived given
  15899. * {extension, list, union} from B's {type definition}"
  15900. *
  15901. * BADSPEC TODO: What's the point of adding "list" and "union" to the
  15902. * set, if the corresponding constraints handle "restriction" and
  15903. * "extension" only?
  15904. *
  15905. */
  15906. {
  15907. int set = 0;
  15908. set |= SUBSET_EXTENSION;
  15909. set |= SUBSET_LIST;
  15910. set |= SUBSET_UNION;
  15911. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
  15912. elemB->subtypes, set) != 0)
  15913. return (1);
  15914. }
  15915. return (0);
  15916. }
  15917. /**
  15918. * xmlSchemaCheckRCaseNSCompat:
  15919. * @ctxt: the schema parser context
  15920. * @r: the restricting element declaration particle
  15921. * @b: the base wildcard particle
  15922. *
  15923. * (3.9.6) Constraints on Particle Schema Components
  15924. * Schema Component Constraint:
  15925. * Particle Derivation OK (Elt:Any -- NSCompat)
  15926. * (rcase-NSCompat)
  15927. *
  15928. * STATUS: complete
  15929. *
  15930. * Returns 0 if the constraints are satisfied, a positive
  15931. * error code if not and -1 if an internal error occurred.
  15932. */
  15933. static int
  15934. xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  15935. xmlSchemaParticlePtr r,
  15936. xmlSchemaParticlePtr b)
  15937. {
  15938. /* TODO:Error codes (rcase-NSCompat). */
  15939. /*
  15940. * SPEC "For an element declaration particle to be a `valid restriction`
  15941. * of a wildcard particle all of the following must be true:"
  15942. *
  15943. * SPEC (1) "The element declaration's {target namespace} is `valid`
  15944. * with respect to the wildcard's {namespace constraint} as defined by
  15945. * Wildcard allows Namespace Name ($3.10.4)."
  15946. */
  15947. if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
  15948. ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
  15949. return (1);
  15950. /*
  15951. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15952. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15953. */
  15954. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15955. b->minOccurs, b->maxOccurs) != 0)
  15956. return (1);
  15957. return (0);
  15958. }
  15959. /**
  15960. * xmlSchemaCheckRCaseRecurseAsIfGroup:
  15961. * @ctxt: the schema parser context
  15962. * @r: the restricting element declaration particle
  15963. * @b: the base model group particle
  15964. *
  15965. * (3.9.6) Constraints on Particle Schema Components
  15966. * Schema Component Constraint:
  15967. * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
  15968. * (rcase-RecurseAsIfGroup)
  15969. *
  15970. * STATUS: TODO
  15971. *
  15972. * Returns 0 if the constraints are satisfied, a positive
  15973. * error code if not and -1 if an internal error occurred.
  15974. */
  15975. static int
  15976. xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  15977. xmlSchemaParticlePtr r,
  15978. xmlSchemaParticlePtr b)
  15979. {
  15980. /* TODO: Error codes (rcase-RecurseAsIfGroup). */
  15981. TODO
  15982. return (0);
  15983. }
  15984. /**
  15985. * xmlSchemaCheckRCaseNSSubset:
  15986. * @ctxt: the schema parser context
  15987. * @r: the restricting wildcard particle
  15988. * @b: the base wildcard particle
  15989. *
  15990. * (3.9.6) Constraints on Particle Schema Components
  15991. * Schema Component Constraint:
  15992. * Particle Derivation OK (Any:Any -- NSSubset)
  15993. * (rcase-NSSubset)
  15994. *
  15995. * STATUS: complete
  15996. *
  15997. * Returns 0 if the constraints are satisfied, a positive
  15998. * error code if not and -1 if an internal error occurred.
  15999. */
  16000. static int
  16001. xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  16002. xmlSchemaParticlePtr r,
  16003. xmlSchemaParticlePtr b,
  16004. int isAnyTypeBase)
  16005. {
  16006. /* TODO: Error codes (rcase-NSSubset). */
  16007. /*
  16008. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16009. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16010. */
  16011. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16012. b->minOccurs, b->maxOccurs))
  16013. return (1);
  16014. /*
  16015. * SPEC (2) "R's {namespace constraint} must be an intensional subset
  16016. * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
  16017. */
  16018. if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
  16019. (xmlSchemaWildcardPtr) b->children))
  16020. return (1);
  16021. /*
  16022. * SPEC (3) "Unless B is the content model wildcard of the `ur-type
  16023. * definition`, R's {process contents} must be identical to or stronger
  16024. * than B's {process contents}, where strict is stronger than lax is
  16025. * stronger than skip."
  16026. */
  16027. if (! isAnyTypeBase) {
  16028. if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
  16029. ((xmlSchemaWildcardPtr) b->children)->processContents)
  16030. return (1);
  16031. }
  16032. return (0);
  16033. }
  16034. /**
  16035. * xmlSchemaCheckCOSParticleRestrict:
  16036. * @ctxt: the schema parser context
  16037. * @type: the complex type definition
  16038. *
  16039. * (3.9.6) Constraints on Particle Schema Components
  16040. * Schema Component Constraint:
  16041. * Particle Valid (Restriction) (cos-particle-restrict)
  16042. *
  16043. * STATUS: TODO
  16044. *
  16045. * Returns 0 if the constraints are satisfied, a positive
  16046. * error code if not and -1 if an internal error occurred.
  16047. */
  16048. static int
  16049. xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  16050. xmlSchemaParticlePtr r,
  16051. xmlSchemaParticlePtr b)
  16052. {
  16053. int ret = 0;
  16054. /*part = WXS_TYPE_PARTICLE(type);
  16055. basePart = WXS_TYPE_PARTICLE(base);
  16056. */
  16057. TODO
  16058. /*
  16059. * SPEC (1) "They are the same particle."
  16060. */
  16061. if (r == b)
  16062. return (0);
  16063. return (0);
  16064. }
  16065. #if 0
  16066. /**
  16067. * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
  16068. * @ctxt: the schema parser context
  16069. * @r: the model group particle
  16070. * @b: the base wildcard particle
  16071. *
  16072. * (3.9.6) Constraints on Particle Schema Components
  16073. * Schema Component Constraint:
  16074. * Particle Derivation OK (All/Choice/Sequence:Any --
  16075. * NSRecurseCheckCardinality)
  16076. * (rcase-NSRecurseCheckCardinality)
  16077. *
  16078. * STATUS: TODO: subst-groups
  16079. *
  16080. * Returns 0 if the constraints are satisfied, a positive
  16081. * error code if not and -1 if an internal error occurred.
  16082. */
  16083. static int
  16084. xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  16085. xmlSchemaParticlePtr r,
  16086. xmlSchemaParticlePtr b)
  16087. {
  16088. xmlSchemaParticlePtr part;
  16089. /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
  16090. if ((r->children == NULL) || (r->children->children == NULL))
  16091. return (-1);
  16092. /*
  16093. * SPEC "For a group particle to be a `valid restriction` of a
  16094. * wildcard particle..."
  16095. *
  16096. * SPEC (1) "Every member of the {particles} of the group is a `valid
  16097. * restriction` of the wildcard as defined by
  16098. * Particle Valid (Restriction) ($3.9.6)."
  16099. */
  16100. part = (xmlSchemaParticlePtr) r->children->children;
  16101. do {
  16102. if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
  16103. return (1);
  16104. part = (xmlSchemaParticlePtr) part->next;
  16105. } while (part != NULL);
  16106. /*
  16107. * SPEC (2) "The effective total range of the group [...] is a
  16108. * valid restriction of B's occurrence range as defined by
  16109. * Occurrence Range OK ($3.9.6)."
  16110. */
  16111. if (xmlSchemaCheckParticleRangeOK(
  16112. xmlSchemaGetParticleTotalRangeMin(r),
  16113. xmlSchemaGetParticleTotalRangeMax(r),
  16114. b->minOccurs, b->maxOccurs) != 0)
  16115. return (1);
  16116. return (0);
  16117. }
  16118. #endif
  16119. /**
  16120. * xmlSchemaCheckRCaseRecurse:
  16121. * @ctxt: the schema parser context
  16122. * @r: the <all> or <sequence> model group particle
  16123. * @b: the base <all> or <sequence> model group particle
  16124. *
  16125. * (3.9.6) Constraints on Particle Schema Components
  16126. * Schema Component Constraint:
  16127. * Particle Derivation OK (All:All,Sequence:Sequence --
  16128. Recurse)
  16129. * (rcase-Recurse)
  16130. *
  16131. * STATUS: ?
  16132. * TODO: subst-groups
  16133. *
  16134. * Returns 0 if the constraints are satisfied, a positive
  16135. * error code if not and -1 if an internal error occurred.
  16136. */
  16137. static int
  16138. xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
  16139. xmlSchemaParticlePtr r,
  16140. xmlSchemaParticlePtr b)
  16141. {
  16142. /* xmlSchemaParticlePtr part; */
  16143. /* TODO: Error codes (rcase-Recurse). */
  16144. if ((r->children == NULL) || (b->children == NULL) ||
  16145. (r->children->type != b->children->type))
  16146. return (-1);
  16147. /*
  16148. * SPEC "For an all or sequence group particle to be a `valid
  16149. * restriction` of another group particle with the same {compositor}..."
  16150. *
  16151. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16152. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16153. */
  16154. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16155. b->minOccurs, b->maxOccurs))
  16156. return (1);
  16157. return (0);
  16158. }
  16159. #endif
  16160. #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
  16161. xmlSchemaPCustomErrExt(pctxt, \
  16162. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16163. WXS_BASIC_CAST fac1, fac1->node, \
  16164. "It is an error for both '%s' and '%s' to be specified on the "\
  16165. "same type definition", \
  16166. BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
  16167. BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
  16168. #define FACET_RESTR_ERR(fac1, msg) \
  16169. xmlSchemaPCustomErr(pctxt, \
  16170. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16171. WXS_BASIC_CAST fac1, fac1->node, \
  16172. msg, NULL);
  16173. #define FACET_RESTR_FIXED_ERR(fac) \
  16174. xmlSchemaPCustomErr(pctxt, \
  16175. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16176. WXS_BASIC_CAST fac, fac->node, \
  16177. "The base type's facet is 'fixed', thus the value must not " \
  16178. "differ", NULL);
  16179. static void
  16180. xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
  16181. xmlSchemaFacetPtr facet1,
  16182. xmlSchemaFacetPtr facet2,
  16183. int lessGreater,
  16184. int orEqual,
  16185. int ofBase)
  16186. {
  16187. xmlChar *msg = NULL;
  16188. msg = xmlStrdup(BAD_CAST "'");
  16189. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
  16190. msg = xmlStrcat(msg, BAD_CAST "' has to be");
  16191. if (lessGreater == 0)
  16192. msg = xmlStrcat(msg, BAD_CAST " equal to");
  16193. if (lessGreater == 1)
  16194. msg = xmlStrcat(msg, BAD_CAST " greater than");
  16195. else
  16196. msg = xmlStrcat(msg, BAD_CAST " less than");
  16197. if (orEqual)
  16198. msg = xmlStrcat(msg, BAD_CAST " or equal to");
  16199. msg = xmlStrcat(msg, BAD_CAST " '");
  16200. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
  16201. if (ofBase)
  16202. msg = xmlStrcat(msg, BAD_CAST "' of the base type");
  16203. else
  16204. msg = xmlStrcat(msg, BAD_CAST "'");
  16205. xmlSchemaPCustomErr(pctxt,
  16206. XML_SCHEMAP_INVALID_FACET_VALUE,
  16207. WXS_BASIC_CAST facet1, NULL,
  16208. (const char *) msg, NULL);
  16209. if (msg != NULL)
  16210. xmlFree(msg);
  16211. }
  16212. /*
  16213. * xmlSchemaDeriveAndValidateFacets:
  16214. *
  16215. * Schema Component Constraint: Simple Type Restriction (Facets)
  16216. * (st-restrict-facets)
  16217. */
  16218. static int
  16219. xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
  16220. xmlSchemaTypePtr type)
  16221. {
  16222. xmlSchemaTypePtr base = type->baseType;
  16223. xmlSchemaFacetLinkPtr link, cur, last = NULL;
  16224. xmlSchemaFacetPtr facet, bfacet,
  16225. flength = NULL, ftotdig = NULL, ffracdig = NULL,
  16226. fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
  16227. fmininc = NULL, fmaxinc = NULL,
  16228. fminexc = NULL, fmaxexc = NULL,
  16229. bflength = NULL, bftotdig = NULL, bffracdig = NULL,
  16230. bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
  16231. bfmininc = NULL, bfmaxinc = NULL,
  16232. bfminexc = NULL, bfmaxexc = NULL;
  16233. int res; /* err = 0, fixedErr; */
  16234. /*
  16235. * SPEC st-restrict-facets 1:
  16236. * "The {variety} of R is the same as that of B."
  16237. */
  16238. /*
  16239. * SPEC st-restrict-facets 2:
  16240. * "If {variety} is atomic, the {primitive type definition}
  16241. * of R is the same as that of B."
  16242. *
  16243. * NOTE: we leave 1 & 2 out for now, since this will be
  16244. * satisfied by the derivation process.
  16245. * CONSTRUCTION TODO: Maybe needed if using a construction API.
  16246. */
  16247. /*
  16248. * SPEC st-restrict-facets 3:
  16249. * "The {facets} of R are the union of S and the {facets}
  16250. * of B, eliminating duplicates. To eliminate duplicates,
  16251. * when a facet of the same kind occurs in both S and the
  16252. * {facets} of B, the one in the {facets} of B is not
  16253. * included, with the exception of enumeration and pattern
  16254. * facets, for which multiple occurrences with distinct values
  16255. * are allowed."
  16256. */
  16257. if ((type->facetSet == NULL) && (base->facetSet == NULL))
  16258. return (0);
  16259. last = type->facetSet;
  16260. if (last != NULL)
  16261. while (last->next != NULL)
  16262. last = last->next;
  16263. for (cur = type->facetSet; cur != NULL; cur = cur->next) {
  16264. facet = cur->facet;
  16265. switch (facet->type) {
  16266. case XML_SCHEMA_FACET_LENGTH:
  16267. flength = facet; break;
  16268. case XML_SCHEMA_FACET_MINLENGTH:
  16269. fminlen = facet; break;
  16270. case XML_SCHEMA_FACET_MININCLUSIVE:
  16271. fmininc = facet; break;
  16272. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16273. fminexc = facet; break;
  16274. case XML_SCHEMA_FACET_MAXLENGTH:
  16275. fmaxlen = facet; break;
  16276. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16277. fmaxinc = facet; break;
  16278. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16279. fmaxexc = facet; break;
  16280. case XML_SCHEMA_FACET_TOTALDIGITS:
  16281. ftotdig = facet; break;
  16282. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16283. ffracdig = facet; break;
  16284. default:
  16285. break;
  16286. }
  16287. }
  16288. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16289. facet = cur->facet;
  16290. switch (facet->type) {
  16291. case XML_SCHEMA_FACET_LENGTH:
  16292. bflength = facet; break;
  16293. case XML_SCHEMA_FACET_MINLENGTH:
  16294. bfminlen = facet; break;
  16295. case XML_SCHEMA_FACET_MININCLUSIVE:
  16296. bfmininc = facet; break;
  16297. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16298. bfminexc = facet; break;
  16299. case XML_SCHEMA_FACET_MAXLENGTH:
  16300. bfmaxlen = facet; break;
  16301. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16302. bfmaxinc = facet; break;
  16303. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16304. bfmaxexc = facet; break;
  16305. case XML_SCHEMA_FACET_TOTALDIGITS:
  16306. bftotdig = facet; break;
  16307. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16308. bffracdig = facet; break;
  16309. default:
  16310. break;
  16311. }
  16312. }
  16313. /*
  16314. * length and minLength or maxLength (2.2) + (3.2)
  16315. */
  16316. if (flength && (fminlen || fmaxlen)) {
  16317. FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
  16318. "either of 'minLength' or 'maxLength' to be specified on "
  16319. "the same type definition")
  16320. }
  16321. /*
  16322. * Mutual exclusions in the same derivation step.
  16323. */
  16324. if ((fmaxinc) && (fmaxexc)) {
  16325. /*
  16326. * SCC "maxInclusive and maxExclusive"
  16327. */
  16328. FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
  16329. }
  16330. if ((fmininc) && (fminexc)) {
  16331. /*
  16332. * SCC "minInclusive and minExclusive"
  16333. */
  16334. FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
  16335. }
  16336. if (flength && bflength) {
  16337. /*
  16338. * SCC "length valid restriction"
  16339. * The values have to be equal.
  16340. */
  16341. res = xmlSchemaCompareValues(flength->val, bflength->val);
  16342. if (res == -2)
  16343. goto internal_error;
  16344. if (res != 0)
  16345. xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
  16346. if ((res != 0) && (bflength->fixed)) {
  16347. FACET_RESTR_FIXED_ERR(flength)
  16348. }
  16349. }
  16350. if (fminlen && bfminlen) {
  16351. /*
  16352. * SCC "minLength valid restriction"
  16353. * minLength >= BASE minLength
  16354. */
  16355. res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
  16356. if (res == -2)
  16357. goto internal_error;
  16358. if (res == -1)
  16359. xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
  16360. if ((res != 0) && (bfminlen->fixed)) {
  16361. FACET_RESTR_FIXED_ERR(fminlen)
  16362. }
  16363. }
  16364. if (fmaxlen && bfmaxlen) {
  16365. /*
  16366. * SCC "maxLength valid restriction"
  16367. * maxLength <= BASE minLength
  16368. */
  16369. res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
  16370. if (res == -2)
  16371. goto internal_error;
  16372. if (res == 1)
  16373. xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
  16374. if ((res != 0) && (bfmaxlen->fixed)) {
  16375. FACET_RESTR_FIXED_ERR(fmaxlen)
  16376. }
  16377. }
  16378. /*
  16379. * SCC "length and minLength or maxLength"
  16380. */
  16381. if (! flength)
  16382. flength = bflength;
  16383. if (flength) {
  16384. if (! fminlen)
  16385. fminlen = bfminlen;
  16386. if (fminlen) {
  16387. /* (1.1) length >= minLength */
  16388. res = xmlSchemaCompareValues(flength->val, fminlen->val);
  16389. if (res == -2)
  16390. goto internal_error;
  16391. if (res == -1)
  16392. xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
  16393. }
  16394. if (! fmaxlen)
  16395. fmaxlen = bfmaxlen;
  16396. if (fmaxlen) {
  16397. /* (2.1) length <= maxLength */
  16398. res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
  16399. if (res == -2)
  16400. goto internal_error;
  16401. if (res == 1)
  16402. xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
  16403. }
  16404. }
  16405. if (fmaxinc) {
  16406. /*
  16407. * "maxInclusive"
  16408. */
  16409. if (fmininc) {
  16410. /* SCC "maxInclusive >= minInclusive" */
  16411. res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
  16412. if (res == -2)
  16413. goto internal_error;
  16414. if (res == -1) {
  16415. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
  16416. }
  16417. }
  16418. /*
  16419. * SCC "maxInclusive valid restriction"
  16420. */
  16421. if (bfmaxinc) {
  16422. /* maxInclusive <= BASE maxInclusive */
  16423. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
  16424. if (res == -2)
  16425. goto internal_error;
  16426. if (res == 1)
  16427. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
  16428. if ((res != 0) && (bfmaxinc->fixed)) {
  16429. FACET_RESTR_FIXED_ERR(fmaxinc)
  16430. }
  16431. }
  16432. if (bfmaxexc) {
  16433. /* maxInclusive < BASE maxExclusive */
  16434. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
  16435. if (res == -2)
  16436. goto internal_error;
  16437. if (res != -1) {
  16438. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
  16439. }
  16440. }
  16441. if (bfmininc) {
  16442. /* maxInclusive >= BASE minInclusive */
  16443. res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
  16444. if (res == -2)
  16445. goto internal_error;
  16446. if (res == -1) {
  16447. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
  16448. }
  16449. }
  16450. if (bfminexc) {
  16451. /* maxInclusive > BASE minExclusive */
  16452. res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
  16453. if (res == -2)
  16454. goto internal_error;
  16455. if (res != 1) {
  16456. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
  16457. }
  16458. }
  16459. }
  16460. if (fmaxexc) {
  16461. /*
  16462. * "maxExclusive >= minExclusive"
  16463. */
  16464. if (fminexc) {
  16465. res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
  16466. if (res == -2)
  16467. goto internal_error;
  16468. if (res == -1) {
  16469. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
  16470. }
  16471. }
  16472. /*
  16473. * "maxExclusive valid restriction"
  16474. */
  16475. if (bfmaxexc) {
  16476. /* maxExclusive <= BASE maxExclusive */
  16477. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
  16478. if (res == -2)
  16479. goto internal_error;
  16480. if (res == 1) {
  16481. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
  16482. }
  16483. if ((res != 0) && (bfmaxexc->fixed)) {
  16484. FACET_RESTR_FIXED_ERR(fmaxexc)
  16485. }
  16486. }
  16487. if (bfmaxinc) {
  16488. /* maxExclusive <= BASE maxInclusive */
  16489. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
  16490. if (res == -2)
  16491. goto internal_error;
  16492. if (res == 1) {
  16493. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
  16494. }
  16495. }
  16496. if (bfmininc) {
  16497. /* maxExclusive > BASE minInclusive */
  16498. res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
  16499. if (res == -2)
  16500. goto internal_error;
  16501. if (res != 1) {
  16502. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
  16503. }
  16504. }
  16505. if (bfminexc) {
  16506. /* maxExclusive > BASE minExclusive */
  16507. res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
  16508. if (res == -2)
  16509. goto internal_error;
  16510. if (res != 1) {
  16511. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
  16512. }
  16513. }
  16514. }
  16515. if (fminexc) {
  16516. /*
  16517. * "minExclusive < maxInclusive"
  16518. */
  16519. if (fmaxinc) {
  16520. res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
  16521. if (res == -2)
  16522. goto internal_error;
  16523. if (res != -1) {
  16524. xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
  16525. }
  16526. }
  16527. /*
  16528. * "minExclusive valid restriction"
  16529. */
  16530. if (bfminexc) {
  16531. /* minExclusive >= BASE minExclusive */
  16532. res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
  16533. if (res == -2)
  16534. goto internal_error;
  16535. if (res == -1) {
  16536. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
  16537. }
  16538. if ((res != 0) && (bfminexc->fixed)) {
  16539. FACET_RESTR_FIXED_ERR(fminexc)
  16540. }
  16541. }
  16542. if (bfmaxinc) {
  16543. /* minExclusive <= BASE maxInclusive */
  16544. res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
  16545. if (res == -2)
  16546. goto internal_error;
  16547. if (res == 1) {
  16548. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
  16549. }
  16550. }
  16551. if (bfmininc) {
  16552. /* minExclusive >= BASE minInclusive */
  16553. res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
  16554. if (res == -2)
  16555. goto internal_error;
  16556. if (res == -1) {
  16557. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
  16558. }
  16559. }
  16560. if (bfmaxexc) {
  16561. /* minExclusive < BASE maxExclusive */
  16562. res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
  16563. if (res == -2)
  16564. goto internal_error;
  16565. if (res != -1) {
  16566. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
  16567. }
  16568. }
  16569. }
  16570. if (fmininc) {
  16571. /*
  16572. * "minInclusive < maxExclusive"
  16573. */
  16574. if (fmaxexc) {
  16575. res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
  16576. if (res == -2)
  16577. goto internal_error;
  16578. if (res != -1) {
  16579. xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
  16580. }
  16581. }
  16582. /*
  16583. * "minExclusive valid restriction"
  16584. */
  16585. if (bfmininc) {
  16586. /* minInclusive >= BASE minInclusive */
  16587. res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
  16588. if (res == -2)
  16589. goto internal_error;
  16590. if (res == -1) {
  16591. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
  16592. }
  16593. if ((res != 0) && (bfmininc->fixed)) {
  16594. FACET_RESTR_FIXED_ERR(fmininc)
  16595. }
  16596. }
  16597. if (bfmaxinc) {
  16598. /* minInclusive <= BASE maxInclusive */
  16599. res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
  16600. if (res == -2)
  16601. goto internal_error;
  16602. if (res == 1) {
  16603. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
  16604. }
  16605. }
  16606. if (bfminexc) {
  16607. /* minInclusive > BASE minExclusive */
  16608. res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
  16609. if (res == -2)
  16610. goto internal_error;
  16611. if (res != 1)
  16612. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
  16613. }
  16614. if (bfmaxexc) {
  16615. /* minInclusive < BASE maxExclusive */
  16616. res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
  16617. if (res == -2)
  16618. goto internal_error;
  16619. if (res != -1)
  16620. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
  16621. }
  16622. }
  16623. if (ftotdig && bftotdig) {
  16624. /*
  16625. * SCC " totalDigits valid restriction"
  16626. * totalDigits <= BASE totalDigits
  16627. */
  16628. res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
  16629. if (res == -2)
  16630. goto internal_error;
  16631. if (res == 1)
  16632. xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
  16633. -1, 1, 1);
  16634. if ((res != 0) && (bftotdig->fixed)) {
  16635. FACET_RESTR_FIXED_ERR(ftotdig)
  16636. }
  16637. }
  16638. if (ffracdig && bffracdig) {
  16639. /*
  16640. * SCC "fractionDigits valid restriction"
  16641. * fractionDigits <= BASE fractionDigits
  16642. */
  16643. res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
  16644. if (res == -2)
  16645. goto internal_error;
  16646. if (res == 1)
  16647. xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
  16648. -1, 1, 1);
  16649. if ((res != 0) && (bffracdig->fixed)) {
  16650. FACET_RESTR_FIXED_ERR(ffracdig)
  16651. }
  16652. }
  16653. /*
  16654. * SCC "fractionDigits less than or equal to totalDigits"
  16655. */
  16656. if (! ftotdig)
  16657. ftotdig = bftotdig;
  16658. if (! ffracdig)
  16659. ffracdig = bffracdig;
  16660. if (ftotdig && ffracdig) {
  16661. res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
  16662. if (res == -2)
  16663. goto internal_error;
  16664. if (res == 1)
  16665. xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
  16666. -1, 1, 0);
  16667. }
  16668. /*
  16669. * *Enumerations* won' be added here, since only the first set
  16670. * of enumerations in the ancestor-or-self axis is used
  16671. * for validation, plus we need to use the base type of those
  16672. * enumerations for whitespace.
  16673. *
  16674. * *Patterns*: won't be add here, since they are ORed at
  16675. * type level and ANDed at ancestor level. This will
  16676. * happen during validation by walking the base axis
  16677. * of the type.
  16678. */
  16679. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16680. bfacet = cur->facet;
  16681. /*
  16682. * Special handling of enumerations and patterns.
  16683. * TODO: hmm, they should not appear in the set, so remove this.
  16684. */
  16685. if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
  16686. (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
  16687. continue;
  16688. /*
  16689. * Search for a duplicate facet in the current type.
  16690. */
  16691. link = type->facetSet;
  16692. /* err = 0; */
  16693. /* fixedErr = 0; */
  16694. while (link != NULL) {
  16695. facet = link->facet;
  16696. if (facet->type == bfacet->type) {
  16697. switch (facet->type) {
  16698. case XML_SCHEMA_FACET_WHITESPACE:
  16699. /*
  16700. * The whitespace must be stronger.
  16701. */
  16702. if (facet->whitespace < bfacet->whitespace) {
  16703. FACET_RESTR_ERR(facet,
  16704. "The 'whitespace' value has to be equal to "
  16705. "or stronger than the 'whitespace' value of "
  16706. "the base type")
  16707. }
  16708. if ((bfacet->fixed) &&
  16709. (facet->whitespace != bfacet->whitespace)) {
  16710. FACET_RESTR_FIXED_ERR(facet)
  16711. }
  16712. break;
  16713. default:
  16714. break;
  16715. }
  16716. /* Duplicate found. */
  16717. break;
  16718. }
  16719. link = link->next;
  16720. }
  16721. /*
  16722. * If no duplicate was found: add the base types's facet
  16723. * to the set.
  16724. */
  16725. if (link == NULL) {
  16726. link = (xmlSchemaFacetLinkPtr)
  16727. xmlMalloc(sizeof(xmlSchemaFacetLink));
  16728. if (link == NULL) {
  16729. xmlSchemaPErrMemory(pctxt,
  16730. "deriving facets, creating a facet link", NULL);
  16731. return (-1);
  16732. }
  16733. link->facet = cur->facet;
  16734. link->next = NULL;
  16735. if (last == NULL)
  16736. type->facetSet = link;
  16737. else
  16738. last->next = link;
  16739. last = link;
  16740. }
  16741. }
  16742. return (0);
  16743. internal_error:
  16744. PERROR_INT("xmlSchemaDeriveAndValidateFacets",
  16745. "an error occurred");
  16746. return (-1);
  16747. }
  16748. static int
  16749. xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
  16750. xmlSchemaTypePtr type)
  16751. {
  16752. xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
  16753. /*
  16754. * The actual value is then formed by replacing any union type
  16755. * definition in the `explicit members` with the members of their
  16756. * {member type definitions}, in order.
  16757. *
  16758. * TODO: There's a bug entry at
  16759. * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
  16760. * which indicates that we'll keep the union types the future.
  16761. */
  16762. link = type->memberTypes;
  16763. while (link != NULL) {
  16764. if (WXS_IS_TYPE_NOT_FIXED(link->type))
  16765. xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
  16766. if (WXS_IS_UNION(link->type)) {
  16767. subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
  16768. if (subLink != NULL) {
  16769. link->type = subLink->type;
  16770. if (subLink->next != NULL) {
  16771. lastLink = link->next;
  16772. subLink = subLink->next;
  16773. prevLink = link;
  16774. while (subLink != NULL) {
  16775. newLink = (xmlSchemaTypeLinkPtr)
  16776. xmlMalloc(sizeof(xmlSchemaTypeLink));
  16777. if (newLink == NULL) {
  16778. xmlSchemaPErrMemory(pctxt, "allocating a type link",
  16779. NULL);
  16780. return (-1);
  16781. }
  16782. newLink->type = subLink->type;
  16783. prevLink->next = newLink;
  16784. prevLink = newLink;
  16785. newLink->next = lastLink;
  16786. subLink = subLink->next;
  16787. }
  16788. }
  16789. }
  16790. }
  16791. link = link->next;
  16792. }
  16793. return (0);
  16794. }
  16795. static void
  16796. xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
  16797. {
  16798. int has = 0, needVal = 0, normVal = 0;
  16799. has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
  16800. if (has) {
  16801. needVal = (type->baseType->flags &
  16802. XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
  16803. normVal = (type->baseType->flags &
  16804. XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
  16805. }
  16806. if (type->facets != NULL) {
  16807. xmlSchemaFacetPtr fac;
  16808. for (fac = type->facets; fac != NULL; fac = fac->next) {
  16809. switch (fac->type) {
  16810. case XML_SCHEMA_FACET_WHITESPACE:
  16811. break;
  16812. case XML_SCHEMA_FACET_PATTERN:
  16813. normVal = 1;
  16814. has = 1;
  16815. break;
  16816. case XML_SCHEMA_FACET_ENUMERATION:
  16817. needVal = 1;
  16818. normVal = 1;
  16819. has = 1;
  16820. break;
  16821. default:
  16822. has = 1;
  16823. break;
  16824. }
  16825. }
  16826. }
  16827. if (normVal)
  16828. type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
  16829. if (needVal)
  16830. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16831. if (has)
  16832. type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
  16833. if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
  16834. xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
  16835. /*
  16836. * OPTIMIZE VAL TODO: Some facets need a computed value.
  16837. */
  16838. if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
  16839. (prim->builtInType != XML_SCHEMAS_STRING)) {
  16840. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16841. }
  16842. }
  16843. }
  16844. static int
  16845. xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
  16846. {
  16847. /*
  16848. * Evaluate the whitespace-facet value.
  16849. */
  16850. if (WXS_IS_LIST(type)) {
  16851. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16852. return (0);
  16853. } else if (WXS_IS_UNION(type))
  16854. return (0);
  16855. if (type->facetSet != NULL) {
  16856. xmlSchemaFacetLinkPtr lin;
  16857. for (lin = type->facetSet; lin != NULL; lin = lin->next) {
  16858. if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
  16859. switch (lin->facet->whitespace) {
  16860. case XML_SCHEMAS_FACET_PRESERVE:
  16861. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16862. break;
  16863. case XML_SCHEMAS_FACET_REPLACE:
  16864. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16865. break;
  16866. case XML_SCHEMAS_FACET_COLLAPSE:
  16867. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16868. break;
  16869. default:
  16870. return (-1);
  16871. }
  16872. return (0);
  16873. }
  16874. }
  16875. }
  16876. /*
  16877. * For all `atomic` datatypes other than string (and types `derived`
  16878. * by `restriction` from it) the value of whiteSpace is fixed to
  16879. * collapse
  16880. */
  16881. {
  16882. xmlSchemaTypePtr anc;
  16883. for (anc = type->baseType; anc != NULL &&
  16884. anc->builtInType != XML_SCHEMAS_ANYTYPE;
  16885. anc = anc->baseType) {
  16886. if (anc->type == XML_SCHEMA_TYPE_BASIC) {
  16887. if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
  16888. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16889. } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
  16890. (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
  16891. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16892. } else
  16893. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16894. break;
  16895. }
  16896. }
  16897. }
  16898. return (0);
  16899. }
  16900. static int
  16901. xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
  16902. xmlSchemaTypePtr type)
  16903. {
  16904. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  16905. return(0);
  16906. if (! WXS_IS_TYPE_NOT_FIXED_1(type))
  16907. return(0);
  16908. type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
  16909. if (WXS_IS_LIST(type)) {
  16910. /*
  16911. * Corresponds to <simpleType><list>...
  16912. */
  16913. if (type->subtypes == NULL) {
  16914. /*
  16915. * This one is really needed, so get out.
  16916. */
  16917. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16918. "list type has no item-type assigned");
  16919. return(-1);
  16920. }
  16921. } else if (WXS_IS_UNION(type)) {
  16922. /*
  16923. * Corresponds to <simpleType><union>...
  16924. */
  16925. if (type->memberTypes == NULL) {
  16926. /*
  16927. * This one is really needed, so get out.
  16928. */
  16929. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16930. "union type has no member-types assigned");
  16931. return(-1);
  16932. }
  16933. } else {
  16934. /*
  16935. * Corresponds to <simpleType><restriction>...
  16936. */
  16937. if (type->baseType == NULL) {
  16938. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16939. "type has no base-type assigned");
  16940. return(-1);
  16941. }
  16942. if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
  16943. if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
  16944. return(-1);
  16945. /*
  16946. * Variety
  16947. * If the <restriction> alternative is chosen, then the
  16948. * {variety} of the {base type definition}.
  16949. */
  16950. if (WXS_IS_ATOMIC(type->baseType))
  16951. type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
  16952. else if (WXS_IS_LIST(type->baseType)) {
  16953. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  16954. /*
  16955. * Inherit the itemType.
  16956. */
  16957. type->subtypes = type->baseType->subtypes;
  16958. } else if (WXS_IS_UNION(type->baseType)) {
  16959. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  16960. /*
  16961. * NOTE that we won't assign the memberTypes of the base,
  16962. * since this will make trouble when freeing them; we will
  16963. * use a lookup function to access them instead.
  16964. */
  16965. }
  16966. }
  16967. return(0);
  16968. }
  16969. /*
  16970. * 3.14.6 Constraints on Simple Type Definition Schema Components
  16971. */
  16972. static int
  16973. xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
  16974. xmlSchemaTypePtr type)
  16975. {
  16976. int res, olderrs = pctxt->nberrors;
  16977. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  16978. return(-1);
  16979. if (! WXS_IS_TYPE_NOT_FIXED(type))
  16980. return(0);
  16981. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  16982. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  16983. if (type->baseType == NULL) {
  16984. PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
  16985. "missing baseType");
  16986. goto exit_failure;
  16987. }
  16988. if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
  16989. xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
  16990. /*
  16991. * If a member type of a union is a union itself, we need to substitute
  16992. * that member type for its member types.
  16993. * NOTE that this might change in WXS 1.1; i.e. we will keep the union
  16994. * types in WXS 1.1.
  16995. */
  16996. if ((type->memberTypes != NULL) &&
  16997. (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
  16998. return(-1);
  16999. /*
  17000. * SPEC src-simple-type 1
  17001. * "The corresponding simple type definition, if any, must satisfy
  17002. * the conditions set out in Constraints on Simple Type Definition
  17003. * Schema Components ($3.14.6)."
  17004. */
  17005. /*
  17006. * Schema Component Constraint: Simple Type Definition Properties Correct
  17007. * (st-props-correct)
  17008. */
  17009. res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
  17010. HFAILURE HERROR
  17011. /*
  17012. * Schema Component Constraint: Derivation Valid (Restriction, Simple)
  17013. * (cos-st-restricts)
  17014. */
  17015. res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
  17016. HFAILURE HERROR
  17017. /*
  17018. * TODO: Removed the error report, since it got annoying to get an
  17019. * extra error report, if anything failed until now.
  17020. * Enable this if needed.
  17021. *
  17022. * xmlSchemaPErr(ctxt, type->node,
  17023. * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  17024. * "Simple type '%s' does not satisfy the constraints "
  17025. * "on simple type definitions.\n",
  17026. * type->name, NULL);
  17027. */
  17028. /*
  17029. * Schema Component Constraint: Simple Type Restriction (Facets)
  17030. * (st-restrict-facets)
  17031. */
  17032. res = xmlSchemaCheckFacetValues(type, pctxt);
  17033. HFAILURE HERROR
  17034. if ((type->facetSet != NULL) ||
  17035. (type->baseType->facetSet != NULL)) {
  17036. res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
  17037. HFAILURE HERROR
  17038. }
  17039. /*
  17040. * Whitespace value.
  17041. */
  17042. res = xmlSchemaTypeFixupWhitespace(type);
  17043. HFAILURE HERROR
  17044. xmlSchemaTypeFixupOptimFacets(type);
  17045. exit_error:
  17046. if (olderrs != pctxt->nberrors)
  17047. return(pctxt->err);
  17048. return(0);
  17049. exit_failure:
  17050. return(-1);
  17051. }
  17052. static int
  17053. xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
  17054. xmlSchemaTypePtr type)
  17055. {
  17056. int res = 0, olderrs = pctxt->nberrors;
  17057. xmlSchemaTypePtr baseType = type->baseType;
  17058. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17059. return(0);
  17060. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17061. if (baseType == NULL) {
  17062. PERROR_INT("xmlSchemaFixupComplexType",
  17063. "missing baseType");
  17064. goto exit_failure;
  17065. }
  17066. /*
  17067. * Fixup the base type.
  17068. */
  17069. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  17070. xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
  17071. if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
  17072. /*
  17073. * Skip fixup if the base type is invalid.
  17074. * TODO: Generate a warning!
  17075. */
  17076. return(0);
  17077. }
  17078. /*
  17079. * This basically checks if the base type can be derived.
  17080. */
  17081. res = xmlSchemaCheckSRCCT(pctxt, type);
  17082. HFAILURE HERROR
  17083. /*
  17084. * Fixup the content type.
  17085. */
  17086. if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
  17087. /*
  17088. * Corresponds to <complexType><simpleContent>...
  17089. */
  17090. if ((WXS_IS_COMPLEX(baseType)) &&
  17091. (baseType->contentTypeDef != NULL) &&
  17092. (WXS_IS_RESTRICTION(type))) {
  17093. xmlSchemaTypePtr contentBase, content;
  17094. #ifdef ENABLE_NAMED_LOCALS
  17095. char buf[30];
  17096. const xmlChar *tmpname;
  17097. #endif
  17098. /*
  17099. * SPEC (1) If <restriction> + base type is <complexType>,
  17100. * "whose own {content type} is a simple type..."
  17101. */
  17102. if (type->contentTypeDef != NULL) {
  17103. /*
  17104. * SPEC (1.1) "the simple type definition corresponding to the
  17105. * <simpleType> among the [children] of <restriction> if there
  17106. * is one;"
  17107. * Note that this "<simpleType> among the [children]" was put
  17108. * into ->contentTypeDef during parsing.
  17109. */
  17110. contentBase = type->contentTypeDef;
  17111. type->contentTypeDef = NULL;
  17112. } else {
  17113. /*
  17114. * (1.2) "...otherwise (<restriction> has no <simpleType>
  17115. * among its [children]), the simple type definition which
  17116. * is the {content type} of the ... base type."
  17117. */
  17118. contentBase = baseType->contentTypeDef;
  17119. }
  17120. /*
  17121. * SPEC
  17122. * "... a simple type definition which restricts the simple
  17123. * type definition identified in clause 1.1 or clause 1.2
  17124. * with a set of facet components"
  17125. *
  17126. * Create the anonymous simple type, which will be the content
  17127. * type of the complex type.
  17128. */
  17129. #ifdef ENABLE_NAMED_LOCALS
  17130. snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
  17131. tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
  17132. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17133. XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
  17134. type->node, 0);
  17135. #else
  17136. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17137. XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
  17138. type->node, 0);
  17139. #endif
  17140. if (content == NULL)
  17141. goto exit_failure;
  17142. /*
  17143. * We will use the same node as for the <complexType>
  17144. * to have it somehow anchored in the schema doc.
  17145. */
  17146. content->type = XML_SCHEMA_TYPE_SIMPLE;
  17147. content->baseType = contentBase;
  17148. /*
  17149. * Move the facets, previously anchored on the
  17150. * complexType during parsing.
  17151. */
  17152. content->facets = type->facets;
  17153. type->facets = NULL;
  17154. content->facetSet = type->facetSet;
  17155. type->facetSet = NULL;
  17156. type->contentTypeDef = content;
  17157. if (WXS_IS_TYPE_NOT_FIXED(contentBase))
  17158. xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
  17159. /*
  17160. * Fixup the newly created type. We don't need to check
  17161. * for circularity here.
  17162. */
  17163. res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
  17164. HFAILURE HERROR
  17165. res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
  17166. HFAILURE HERROR
  17167. } else if ((WXS_IS_COMPLEX(baseType)) &&
  17168. (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  17169. (WXS_IS_RESTRICTION(type))) {
  17170. /*
  17171. * SPEC (2) If <restriction> + base is a mixed <complexType> with
  17172. * an emptiable particle, then a simple type definition which
  17173. * restricts the <restriction>'s <simpleType> child.
  17174. */
  17175. if ((type->contentTypeDef == NULL) ||
  17176. (type->contentTypeDef->baseType == NULL)) {
  17177. /*
  17178. * TODO: Check if this ever happens.
  17179. */
  17180. xmlSchemaPCustomErr(pctxt,
  17181. XML_SCHEMAP_INTERNAL,
  17182. WXS_BASIC_CAST type, NULL,
  17183. "Internal error: xmlSchemaTypeFixup, "
  17184. "complex type '%s': the <simpleContent><restriction> "
  17185. "is missing a <simpleType> child, but was not caught "
  17186. "by xmlSchemaCheckSRCCT()", type->name);
  17187. goto exit_failure;
  17188. }
  17189. } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
  17190. /*
  17191. * SPEC (3) If <extension> + base is <complexType> with
  17192. * <simpleType> content, "...then the {content type} of that
  17193. * complex type definition"
  17194. */
  17195. if (baseType->contentTypeDef == NULL) {
  17196. /*
  17197. * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
  17198. * should have caught this already.
  17199. */
  17200. xmlSchemaPCustomErr(pctxt,
  17201. XML_SCHEMAP_INTERNAL,
  17202. WXS_BASIC_CAST type, NULL,
  17203. "Internal error: xmlSchemaTypeFixup, "
  17204. "complex type '%s': the <extension>ed base type is "
  17205. "a complex type with no simple content type",
  17206. type->name);
  17207. goto exit_failure;
  17208. }
  17209. type->contentTypeDef = baseType->contentTypeDef;
  17210. } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
  17211. /*
  17212. * SPEC (4) <extension> + base is <simpleType>
  17213. * "... then that simple type definition"
  17214. */
  17215. type->contentTypeDef = baseType;
  17216. } else {
  17217. /*
  17218. * TODO: Check if this ever happens.
  17219. */
  17220. xmlSchemaPCustomErr(pctxt,
  17221. XML_SCHEMAP_INTERNAL,
  17222. WXS_BASIC_CAST type, NULL,
  17223. "Internal error: xmlSchemaTypeFixup, "
  17224. "complex type '%s' with <simpleContent>: unhandled "
  17225. "derivation case", type->name);
  17226. goto exit_failure;
  17227. }
  17228. } else {
  17229. int dummySequence = 0;
  17230. xmlSchemaParticlePtr particle =
  17231. (xmlSchemaParticlePtr) type->subtypes;
  17232. /*
  17233. * Corresponds to <complexType><complexContent>...
  17234. *
  17235. * NOTE that the effective mixed was already set during parsing of
  17236. * <complexType> and <complexContent>; its flag value is
  17237. * XML_SCHEMAS_TYPE_MIXED.
  17238. *
  17239. * Compute the "effective content":
  17240. * (2.1.1) + (2.1.2) + (2.1.3)
  17241. */
  17242. if ((particle == NULL) ||
  17243. ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
  17244. ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
  17245. (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  17246. ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
  17247. (particle->minOccurs == 0))) &&
  17248. ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
  17249. if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
  17250. /*
  17251. * SPEC (2.1.4) "If the `effective mixed` is true, then
  17252. * a particle whose properties are as follows:..."
  17253. *
  17254. * Empty sequence model group with
  17255. * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
  17256. * NOTE that we sill assign it the <complexType> node to
  17257. * somehow anchor it in the doc.
  17258. */
  17259. if ((particle == NULL) ||
  17260. (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
  17261. /*
  17262. * Create the particle.
  17263. */
  17264. particle = xmlSchemaAddParticle(pctxt,
  17265. type->node, 1, 1);
  17266. if (particle == NULL)
  17267. goto exit_failure;
  17268. /*
  17269. * Create the model group.
  17270. */ /* URGENT TODO: avoid adding to pending items. */
  17271. particle->children = (xmlSchemaTreeItemPtr)
  17272. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17273. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17274. if (particle->children == NULL)
  17275. goto exit_failure;
  17276. type->subtypes = (xmlSchemaTypePtr) particle;
  17277. }
  17278. dummySequence = 1;
  17279. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17280. } else {
  17281. /*
  17282. * SPEC (2.1.5) "otherwise empty"
  17283. */
  17284. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  17285. }
  17286. } else {
  17287. /*
  17288. * SPEC (2.2) "otherwise the particle corresponding to the
  17289. * <all>, <choice>, <group> or <sequence> among the
  17290. * [children]."
  17291. */
  17292. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17293. }
  17294. /*
  17295. * Compute the "content type".
  17296. */
  17297. if (WXS_IS_RESTRICTION(type)) {
  17298. /*
  17299. * SPEC (3.1) "If <restriction>..."
  17300. * (3.1.1) + (3.1.2) */
  17301. if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
  17302. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17303. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17304. }
  17305. } else {
  17306. /*
  17307. * SPEC (3.2) "If <extension>..."
  17308. */
  17309. if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17310. /*
  17311. * SPEC (3.2.1)
  17312. * "If the `effective content` is empty, then the
  17313. * {content type} of the [...] base ..."
  17314. */
  17315. type->contentType = baseType->contentType;
  17316. type->subtypes = baseType->subtypes;
  17317. /*
  17318. * Fixes bug #347316:
  17319. * This is the case when the base type has a simple
  17320. * type definition as content.
  17321. */
  17322. type->contentTypeDef = baseType->contentTypeDef;
  17323. /*
  17324. * NOTE that the effective mixed is ignored here.
  17325. */
  17326. } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17327. /*
  17328. * SPEC (3.2.2)
  17329. */
  17330. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17331. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17332. } else {
  17333. /*
  17334. * SPEC (3.2.3)
  17335. */
  17336. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17337. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17338. /*
  17339. * "A model group whose {compositor} is sequence and whose
  17340. * {particles} are..."
  17341. */
  17342. if ((WXS_TYPE_PARTICLE(type) != NULL) &&
  17343. (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
  17344. ((WXS_TYPE_PARTICLE_TERM(type))->type ==
  17345. XML_SCHEMA_TYPE_ALL))
  17346. {
  17347. /*
  17348. * SPEC cos-all-limited (1)
  17349. */
  17350. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17351. /* TODO: error code */
  17352. XML_SCHEMAP_COS_ALL_LIMITED,
  17353. WXS_ITEM_NODE(type), NULL,
  17354. "The type has an 'all' model group in its "
  17355. "{content type} and thus cannot be derived from "
  17356. "a non-empty type, since this would produce a "
  17357. "'sequence' model group containing the 'all' "
  17358. "model group; 'all' model groups are not "
  17359. "allowed to appear inside other model groups",
  17360. NULL, NULL);
  17361. } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
  17362. (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
  17363. ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
  17364. XML_SCHEMA_TYPE_ALL))
  17365. {
  17366. /*
  17367. * SPEC cos-all-limited (1)
  17368. */
  17369. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17370. /* TODO: error code */
  17371. XML_SCHEMAP_COS_ALL_LIMITED,
  17372. WXS_ITEM_NODE(type), NULL,
  17373. "A type cannot be derived by extension from a type "
  17374. "which has an 'all' model group in its "
  17375. "{content type}, since this would produce a "
  17376. "'sequence' model group containing the 'all' "
  17377. "model group; 'all' model groups are not "
  17378. "allowed to appear inside other model groups",
  17379. NULL, NULL);
  17380. } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
  17381. xmlSchemaTreeItemPtr effectiveContent =
  17382. (xmlSchemaTreeItemPtr) type->subtypes;
  17383. /*
  17384. * Create the particle.
  17385. */
  17386. particle = xmlSchemaAddParticle(pctxt,
  17387. type->node, 1, 1);
  17388. if (particle == NULL)
  17389. goto exit_failure;
  17390. /*
  17391. * Create the "sequence" model group.
  17392. */
  17393. particle->children = (xmlSchemaTreeItemPtr)
  17394. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17395. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17396. if (particle->children == NULL)
  17397. goto exit_failure;
  17398. WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
  17399. /*
  17400. * SPEC "the particle of the {content type} of
  17401. * the ... base ..."
  17402. * Create a duplicate of the base type's particle
  17403. * and assign its "term" to it.
  17404. */
  17405. particle->children->children =
  17406. (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
  17407. type->node,
  17408. ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
  17409. ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
  17410. if (particle->children->children == NULL)
  17411. goto exit_failure;
  17412. particle = (xmlSchemaParticlePtr)
  17413. particle->children->children;
  17414. particle->children =
  17415. ((xmlSchemaParticlePtr) baseType->subtypes)->children;
  17416. /*
  17417. * SPEC "followed by the `effective content`."
  17418. */
  17419. particle->next = effectiveContent;
  17420. /*
  17421. * This all will result in:
  17422. * new-particle
  17423. * --> new-sequence(
  17424. * new-particle
  17425. * --> base-model,
  17426. * this-particle
  17427. * --> this-model
  17428. * )
  17429. */
  17430. } else {
  17431. /*
  17432. * This is the case when there is already an empty
  17433. * <sequence> with minOccurs==maxOccurs==1.
  17434. * Just add the base types's content type.
  17435. * NOTE that, although we miss to add an intermediate
  17436. * <sequence>, this should produce no difference to
  17437. * neither the regex compilation of the content model,
  17438. * nor to the complex type constraints.
  17439. */
  17440. particle->children->children =
  17441. (xmlSchemaTreeItemPtr) baseType->subtypes;
  17442. }
  17443. }
  17444. }
  17445. }
  17446. /*
  17447. * Now fixup attribute uses:
  17448. * - expand attr. group references
  17449. * - intersect attribute wildcards
  17450. * - inherit attribute uses of the base type
  17451. * - inherit or union attr. wildcards if extending
  17452. * - apply attr. use prohibitions if restricting
  17453. */
  17454. res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
  17455. HFAILURE HERROR
  17456. /*
  17457. * Apply the complex type component constraints; this will not
  17458. * check attributes, since this is done in
  17459. * xmlSchemaFixupTypeAttributeUses().
  17460. */
  17461. res = xmlSchemaCheckCTComponent(pctxt, type);
  17462. HFAILURE HERROR
  17463. if (olderrs != pctxt->nberrors)
  17464. return(pctxt->err);
  17465. else
  17466. return(0);
  17467. exit_error:
  17468. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17469. return(pctxt->err);
  17470. exit_failure:
  17471. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17472. return(-1);
  17473. }
  17474. /**
  17475. * xmlSchemaTypeFixup:
  17476. * @typeDecl: the schema type definition
  17477. * @ctxt: the schema parser context
  17478. *
  17479. * Fixes the content model of the type.
  17480. * URGENT TODO: We need an int result!
  17481. */
  17482. static int
  17483. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  17484. xmlSchemaAbstractCtxtPtr actxt)
  17485. {
  17486. if (type == NULL)
  17487. return(0);
  17488. if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
  17489. AERROR_INT("xmlSchemaTypeFixup",
  17490. "this function needs a parser context");
  17491. return(-1);
  17492. }
  17493. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17494. return(0);
  17495. if (type->type == XML_SCHEMA_TYPE_COMPLEX)
  17496. return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
  17497. else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
  17498. return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
  17499. return(0);
  17500. }
  17501. /**
  17502. * xmlSchemaCheckFacet:
  17503. * @facet: the facet
  17504. * @typeDecl: the schema type definition
  17505. * @pctxt: the schema parser context or NULL
  17506. * @name: the optional name of the type
  17507. *
  17508. * Checks and computes the values of facets.
  17509. *
  17510. * Returns 0 if valid, a positive error code if not valid and
  17511. * -1 in case of an internal or API error.
  17512. */
  17513. int
  17514. xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
  17515. xmlSchemaTypePtr typeDecl,
  17516. xmlSchemaParserCtxtPtr pctxt,
  17517. const xmlChar * name ATTRIBUTE_UNUSED)
  17518. {
  17519. int ret = 0, ctxtGiven;
  17520. if ((facet == NULL) || (typeDecl == NULL))
  17521. return(-1);
  17522. /*
  17523. * TODO: will the parser context be given if used from
  17524. * the relaxNG module?
  17525. */
  17526. if (pctxt == NULL)
  17527. ctxtGiven = 0;
  17528. else
  17529. ctxtGiven = 1;
  17530. switch (facet->type) {
  17531. case XML_SCHEMA_FACET_MININCLUSIVE:
  17532. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  17533. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  17534. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  17535. case XML_SCHEMA_FACET_ENUMERATION: {
  17536. /*
  17537. * Okay we need to validate the value
  17538. * at that point.
  17539. */
  17540. xmlSchemaTypePtr base;
  17541. /* 4.3.5.5 Constraints on enumeration Schema Components
  17542. * Schema Component Constraint: enumeration valid restriction
  17543. * It is an `error` if any member of {value} is not in the
  17544. * `value space` of {base type definition}.
  17545. *
  17546. * minInclusive, maxInclusive, minExclusive, maxExclusive:
  17547. * The value `must` be in the
  17548. * `value space` of the `base type`.
  17549. */
  17550. /*
  17551. * This function is intended to deliver a compiled value
  17552. * on the facet. In this implementation of XML Schemata the
  17553. * type holding a facet, won't be a built-in type.
  17554. * Thus to ensure that other API
  17555. * calls (relaxng) do work, if the given type is a built-in
  17556. * type, we will assume that the given built-in type *is
  17557. * already* the base type.
  17558. */
  17559. if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
  17560. base = typeDecl->baseType;
  17561. if (base == NULL) {
  17562. PERROR_INT("xmlSchemaCheckFacet",
  17563. "a type user derived type has no base type");
  17564. return (-1);
  17565. }
  17566. } else
  17567. base = typeDecl;
  17568. if (! ctxtGiven) {
  17569. /*
  17570. * A context is needed if called from RelaxNG.
  17571. */
  17572. pctxt = xmlSchemaNewParserCtxt("*");
  17573. if (pctxt == NULL)
  17574. return (-1);
  17575. }
  17576. /*
  17577. * NOTE: This call does not check the content nodes,
  17578. * since they are not available:
  17579. * facet->node is just the node holding the facet
  17580. * definition, *not* the attribute holding the *value*
  17581. * of the facet.
  17582. */
  17583. ret = xmlSchemaVCheckCVCSimpleType(
  17584. ACTXT_CAST pctxt, facet->node, base,
  17585. facet->value, &(facet->val), 1, 1, 0);
  17586. if (ret != 0) {
  17587. if (ret < 0) {
  17588. /* No error message for RelaxNG. */
  17589. if (ctxtGiven) {
  17590. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17591. XML_SCHEMAP_INTERNAL, facet->node, NULL,
  17592. "Internal error: xmlSchemaCheckFacet, "
  17593. "failed to validate the value '%s' of the "
  17594. "facet '%s' against the base type",
  17595. facet->value, xmlSchemaFacetTypeToString(facet->type));
  17596. }
  17597. goto internal_error;
  17598. }
  17599. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17600. /* No error message for RelaxNG. */
  17601. if (ctxtGiven) {
  17602. xmlChar *str = NULL;
  17603. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17604. ret, facet->node, WXS_BASIC_CAST facet,
  17605. "The value '%s' of the facet does not validate "
  17606. "against the base type '%s'",
  17607. facet->value,
  17608. xmlSchemaFormatQName(&str,
  17609. base->targetNamespace, base->name));
  17610. FREE_AND_NULL(str);
  17611. }
  17612. goto exit;
  17613. } else if (facet->val == NULL) {
  17614. if (ctxtGiven) {
  17615. PERROR_INT("xmlSchemaCheckFacet",
  17616. "value was not computed");
  17617. }
  17618. TODO
  17619. }
  17620. break;
  17621. }
  17622. case XML_SCHEMA_FACET_PATTERN:
  17623. facet->regexp = xmlRegexpCompile(facet->value);
  17624. if (facet->regexp == NULL) {
  17625. ret = XML_SCHEMAP_REGEXP_INVALID;
  17626. /* No error message for RelaxNG. */
  17627. if (ctxtGiven) {
  17628. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17629. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17630. "The value '%s' of the facet 'pattern' is not a "
  17631. "valid regular expression",
  17632. facet->value, NULL);
  17633. }
  17634. }
  17635. break;
  17636. case XML_SCHEMA_FACET_TOTALDIGITS:
  17637. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  17638. case XML_SCHEMA_FACET_LENGTH:
  17639. case XML_SCHEMA_FACET_MAXLENGTH:
  17640. case XML_SCHEMA_FACET_MINLENGTH:
  17641. if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
  17642. ret = xmlSchemaValidatePredefinedType(
  17643. xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
  17644. facet->value, &(facet->val));
  17645. } else {
  17646. ret = xmlSchemaValidatePredefinedType(
  17647. xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
  17648. facet->value, &(facet->val));
  17649. }
  17650. if (ret != 0) {
  17651. if (ret < 0) {
  17652. /* No error message for RelaxNG. */
  17653. if (ctxtGiven) {
  17654. PERROR_INT("xmlSchemaCheckFacet",
  17655. "validating facet value");
  17656. }
  17657. goto internal_error;
  17658. }
  17659. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17660. /* No error message for RelaxNG. */
  17661. if (ctxtGiven) {
  17662. /* error code */
  17663. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  17664. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17665. "The value '%s' of the facet '%s' is not a valid '%s'",
  17666. facet->value,
  17667. xmlSchemaFacetTypeToString(facet->type),
  17668. (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
  17669. BAD_CAST "nonNegativeInteger" :
  17670. BAD_CAST "positiveInteger",
  17671. NULL);
  17672. }
  17673. }
  17674. break;
  17675. case XML_SCHEMA_FACET_WHITESPACE:{
  17676. if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
  17677. facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
  17678. } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
  17679. facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
  17680. } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
  17681. facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
  17682. } else {
  17683. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17684. /* No error message for RelaxNG. */
  17685. if (ctxtGiven) {
  17686. /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
  17687. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17688. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17689. "The value '%s' of the facet 'whitespace' is not "
  17690. "valid", facet->value, NULL);
  17691. }
  17692. }
  17693. }
  17694. default:
  17695. break;
  17696. }
  17697. exit:
  17698. if ((! ctxtGiven) && (pctxt != NULL))
  17699. xmlSchemaFreeParserCtxt(pctxt);
  17700. return (ret);
  17701. internal_error:
  17702. if ((! ctxtGiven) && (pctxt != NULL))
  17703. xmlSchemaFreeParserCtxt(pctxt);
  17704. return (-1);
  17705. }
  17706. /**
  17707. * xmlSchemaCheckFacetValues:
  17708. * @typeDecl: the schema type definition
  17709. * @ctxt: the schema parser context
  17710. *
  17711. * Checks the default values types, especially for facets
  17712. */
  17713. static int
  17714. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  17715. xmlSchemaParserCtxtPtr pctxt)
  17716. {
  17717. int res, olderrs = pctxt->nberrors;
  17718. const xmlChar *name = typeDecl->name;
  17719. /*
  17720. * NOTE: It is intended to use the facets list, instead
  17721. * of facetSet.
  17722. */
  17723. if (typeDecl->facets != NULL) {
  17724. xmlSchemaFacetPtr facet = typeDecl->facets;
  17725. /*
  17726. * Temporarily assign the "schema" to the validation context
  17727. * of the parser context. This is needed for NOTATION validation.
  17728. */
  17729. if (pctxt->vctxt == NULL) {
  17730. if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
  17731. return(-1);
  17732. }
  17733. pctxt->vctxt->schema = pctxt->schema;
  17734. while (facet != NULL) {
  17735. res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
  17736. HFAILURE
  17737. facet = facet->next;
  17738. }
  17739. pctxt->vctxt->schema = NULL;
  17740. }
  17741. if (olderrs != pctxt->nberrors)
  17742. return(pctxt->err);
  17743. return(0);
  17744. exit_failure:
  17745. return(-1);
  17746. }
  17747. /**
  17748. * xmlSchemaGetCircModelGrDefRef:
  17749. * @ctxtMGroup: the searched model group
  17750. * @selfMGroup: the second searched model group
  17751. * @particle: the first particle
  17752. *
  17753. * This one is intended to be used by
  17754. * xmlSchemaCheckGroupDefCircular only.
  17755. *
  17756. * Returns the particle with the circular model group definition reference,
  17757. * otherwise NULL.
  17758. */
  17759. static xmlSchemaTreeItemPtr
  17760. xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
  17761. xmlSchemaTreeItemPtr particle)
  17762. {
  17763. xmlSchemaTreeItemPtr circ = NULL;
  17764. xmlSchemaTreeItemPtr term;
  17765. xmlSchemaModelGroupDefPtr gdef;
  17766. for (; particle != NULL; particle = particle->next) {
  17767. term = particle->children;
  17768. if (term == NULL)
  17769. continue;
  17770. switch (term->type) {
  17771. case XML_SCHEMA_TYPE_GROUP:
  17772. gdef = (xmlSchemaModelGroupDefPtr) term;
  17773. if (gdef == groupDef)
  17774. return (particle);
  17775. /*
  17776. * Mark this model group definition to avoid infinite
  17777. * recursion on circular references not yet examined.
  17778. */
  17779. if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
  17780. continue;
  17781. if (gdef->children != NULL) {
  17782. gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17783. circ = xmlSchemaGetCircModelGrDefRef(groupDef,
  17784. gdef->children->children);
  17785. gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17786. if (circ != NULL)
  17787. return (circ);
  17788. }
  17789. break;
  17790. case XML_SCHEMA_TYPE_SEQUENCE:
  17791. case XML_SCHEMA_TYPE_CHOICE:
  17792. case XML_SCHEMA_TYPE_ALL:
  17793. circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
  17794. if (circ != NULL)
  17795. return (circ);
  17796. break;
  17797. default:
  17798. break;
  17799. }
  17800. }
  17801. return (NULL);
  17802. }
  17803. /**
  17804. * xmlSchemaCheckGroupDefCircular:
  17805. * @item: the model group definition
  17806. * @ctxt: the parser context
  17807. * @name: the name
  17808. *
  17809. * Checks for circular references to model group definitions.
  17810. */
  17811. static void
  17812. xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
  17813. xmlSchemaParserCtxtPtr ctxt)
  17814. {
  17815. /*
  17816. * Schema Component Constraint: Model Group Correct
  17817. * 2 Circular groups are disallowed. That is, within the {particles}
  17818. * of a group there must not be at any depth a particle whose {term}
  17819. * is the group itself.
  17820. */
  17821. if ((item == NULL) ||
  17822. (item->type != XML_SCHEMA_TYPE_GROUP) ||
  17823. (item->children == NULL))
  17824. return;
  17825. {
  17826. xmlSchemaTreeItemPtr circ;
  17827. circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
  17828. if (circ != NULL) {
  17829. xmlChar *str = NULL;
  17830. /*
  17831. * TODO: The error report is not adequate: this constraint
  17832. * is defined for model groups but not definitions, but since
  17833. * there cannot be any circular model groups without a model group
  17834. * definition (if not using a construction API), we check those
  17835. * definitions only.
  17836. */
  17837. xmlSchemaPCustomErr(ctxt,
  17838. XML_SCHEMAP_MG_PROPS_CORRECT_2,
  17839. NULL, WXS_ITEM_NODE(circ),
  17840. "Circular reference to the model group definition '%s' "
  17841. "defined", xmlSchemaFormatQName(&str,
  17842. item->targetNamespace, item->name));
  17843. FREE_AND_NULL(str)
  17844. /*
  17845. * NOTE: We will cut the reference to avoid further
  17846. * confusion of the processor. This is a fatal error.
  17847. */
  17848. circ->children = NULL;
  17849. }
  17850. }
  17851. }
  17852. /**
  17853. * xmlSchemaModelGroupToModelGroupDefFixup:
  17854. * @ctxt: the parser context
  17855. * @mg: the model group
  17856. *
  17857. * Assigns the model group of model group definitions to the "term"
  17858. * of the referencing particle.
  17859. * In xmlSchemaResolveModelGroupParticleReferences the model group
  17860. * definitions were assigned to the "term", since needed for the
  17861. * circularity check.
  17862. *
  17863. * Schema Component Constraint:
  17864. * All Group Limited (cos-all-limited) (1.2)
  17865. */
  17866. static void
  17867. xmlSchemaModelGroupToModelGroupDefFixup(
  17868. xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  17869. xmlSchemaModelGroupPtr mg)
  17870. {
  17871. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  17872. while (particle != NULL) {
  17873. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  17874. ((WXS_PARTICLE_TERM(particle))->type !=
  17875. XML_SCHEMA_TYPE_GROUP))
  17876. {
  17877. particle = WXS_PTC_CAST particle->next;
  17878. continue;
  17879. }
  17880. if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
  17881. /*
  17882. * TODO: Remove the particle.
  17883. */
  17884. WXS_PARTICLE_TERM(particle) = NULL;
  17885. particle = WXS_PTC_CAST particle->next;
  17886. continue;
  17887. }
  17888. /*
  17889. * Assign the model group to the {term} of the particle.
  17890. */
  17891. WXS_PARTICLE_TERM(particle) =
  17892. WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
  17893. particle = WXS_PTC_CAST particle->next;
  17894. }
  17895. }
  17896. /**
  17897. * xmlSchemaCheckAttrGroupCircularRecur:
  17898. * @ctxtGr: the searched attribute group
  17899. * @attr: the current attribute list to be processed
  17900. *
  17901. * This one is intended to be used by
  17902. * xmlSchemaCheckAttrGroupCircular only.
  17903. *
  17904. * Returns the circular attribute group reference, otherwise NULL.
  17905. */
  17906. static xmlSchemaQNameRefPtr
  17907. xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
  17908. xmlSchemaItemListPtr list)
  17909. {
  17910. xmlSchemaAttributeGroupPtr gr;
  17911. xmlSchemaQNameRefPtr ref, circ;
  17912. int i;
  17913. /*
  17914. * We will search for an attribute group reference which
  17915. * references the context attribute group.
  17916. */
  17917. for (i = 0; i < list->nbItems; i++) {
  17918. ref = list->items[i];
  17919. if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  17920. (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  17921. (ref->item != NULL))
  17922. {
  17923. gr = WXS_ATTR_GROUP_CAST ref->item;
  17924. if (gr == ctxtGr)
  17925. return(ref);
  17926. if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
  17927. continue;
  17928. /*
  17929. * Mark as visited to avoid infinite recursion on
  17930. * circular references not yet examined.
  17931. */
  17932. if ((gr->attrUses) &&
  17933. (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
  17934. {
  17935. gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
  17936. circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
  17937. (xmlSchemaItemListPtr) gr->attrUses);
  17938. gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
  17939. if (circ != NULL)
  17940. return (circ);
  17941. }
  17942. }
  17943. }
  17944. return (NULL);
  17945. }
  17946. /**
  17947. * xmlSchemaCheckAttrGroupCircular:
  17948. * attrGr: the attribute group definition
  17949. * @ctxt: the parser context
  17950. * @name: the name
  17951. *
  17952. * Checks for circular references of attribute groups.
  17953. */
  17954. static int
  17955. xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
  17956. xmlSchemaParserCtxtPtr ctxt)
  17957. {
  17958. /*
  17959. * Schema Representation Constraint:
  17960. * Attribute Group Definition Representation OK
  17961. * 3 Circular group reference is disallowed outside <redefine>.
  17962. * That is, unless this element information item's parent is
  17963. * <redefine>, then among the [children], if any, there must
  17964. * not be an <attributeGroup> with ref [attribute] which resolves
  17965. * to the component corresponding to this <attributeGroup>. Indirect
  17966. * circularity is also ruled out. That is, when QName resolution
  17967. * (Schema Document) ($3.15.3) is applied to a `QName` arising from
  17968. * any <attributeGroup>s with a ref [attribute] among the [children],
  17969. * it must not be the case that a `QName` is encountered at any depth
  17970. * which resolves to the component corresponding to this <attributeGroup>.
  17971. */
  17972. if (attrGr->attrUses == NULL)
  17973. return(0);
  17974. else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
  17975. return(0);
  17976. else {
  17977. xmlSchemaQNameRefPtr circ;
  17978. circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
  17979. (xmlSchemaItemListPtr) attrGr->attrUses);
  17980. if (circ != NULL) {
  17981. xmlChar *str = NULL;
  17982. /*
  17983. * TODO: Report the referenced attr group as QName.
  17984. */
  17985. xmlSchemaPCustomErr(ctxt,
  17986. XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
  17987. NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
  17988. "Circular reference to the attribute group '%s' "
  17989. "defined", xmlSchemaGetComponentQName(&str, attrGr));
  17990. FREE_AND_NULL(str);
  17991. /*
  17992. * NOTE: We will cut the reference to avoid further
  17993. * confusion of the processor.
  17994. * BADSPEC TODO: The spec should define how to process in this case.
  17995. */
  17996. circ->item = NULL;
  17997. return(ctxt->err);
  17998. }
  17999. }
  18000. return(0);
  18001. }
  18002. static int
  18003. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18004. xmlSchemaAttributeGroupPtr attrGr);
  18005. /**
  18006. * xmlSchemaExpandAttributeGroupRefs:
  18007. * @pctxt: the parser context
  18008. * @node: the node of the component holding the attribute uses
  18009. * @completeWild: the intersected wildcard to be returned
  18010. * @list: the attribute uses
  18011. *
  18012. * Substitutes contained attribute group references
  18013. * for their attribute uses. Wildcards are intersected.
  18014. * Attribute use prohibitions are removed from the list
  18015. * and returned via the @prohibs list.
  18016. * Pointlessness of attr. prohibs, if a matching attr. decl
  18017. * is existent a well, are checked.
  18018. */
  18019. static int
  18020. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  18021. xmlSchemaBasicItemPtr item,
  18022. xmlSchemaWildcardPtr *completeWild,
  18023. xmlSchemaItemListPtr list,
  18024. xmlSchemaItemListPtr prohibs)
  18025. {
  18026. xmlSchemaAttributeGroupPtr gr;
  18027. xmlSchemaAttributeUsePtr use;
  18028. xmlSchemaItemListPtr sublist;
  18029. int i, j;
  18030. int created = (*completeWild == NULL) ? 0 : 1;
  18031. if (prohibs)
  18032. prohibs->nbItems = 0;
  18033. for (i = 0; i < list->nbItems; i++) {
  18034. use = list->items[i];
  18035. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  18036. if (prohibs == NULL) {
  18037. PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
  18038. "unexpected attr prohibition found");
  18039. return(-1);
  18040. }
  18041. /*
  18042. * Remove from attribute uses.
  18043. */
  18044. if (xmlSchemaItemListRemove(list, i) == -1)
  18045. return(-1);
  18046. i--;
  18047. /*
  18048. * Note that duplicate prohibitions were already
  18049. * handled at parsing time.
  18050. */
  18051. /*
  18052. * Add to list of prohibitions.
  18053. */
  18054. xmlSchemaItemListAddSize(prohibs, 2, use);
  18055. continue;
  18056. }
  18057. if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18058. ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
  18059. {
  18060. if ((WXS_QNAME_CAST use)->item == NULL)
  18061. return(-1);
  18062. gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
  18063. /*
  18064. * Expand the referenced attr. group.
  18065. * TODO: remove this, this is done in a previous step, so
  18066. * already done here.
  18067. */
  18068. if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
  18069. if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
  18070. return(-1);
  18071. }
  18072. /*
  18073. * Build the 'complete' wildcard; i.e. intersect multiple
  18074. * wildcards.
  18075. */
  18076. if (gr->attributeWildcard != NULL) {
  18077. if (*completeWild == NULL) {
  18078. *completeWild = gr->attributeWildcard;
  18079. } else {
  18080. if (! created) {
  18081. xmlSchemaWildcardPtr tmpWild;
  18082. /*
  18083. * Copy the first encountered wildcard as context,
  18084. * except for the annotation.
  18085. *
  18086. * Although the complete wildcard might not correspond
  18087. * to any node in the schema, we will anchor it on
  18088. * the node of the owner component.
  18089. */
  18090. tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
  18091. XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  18092. WXS_ITEM_NODE(item));
  18093. if (tmpWild == NULL)
  18094. return(-1);
  18095. if (xmlSchemaCloneWildcardNsConstraints(pctxt,
  18096. tmpWild, *completeWild) == -1)
  18097. return (-1);
  18098. tmpWild->processContents = (*completeWild)->processContents;
  18099. *completeWild = tmpWild;
  18100. created = 1;
  18101. }
  18102. if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
  18103. gr->attributeWildcard) == -1)
  18104. return(-1);
  18105. }
  18106. }
  18107. /*
  18108. * Just remove the reference if the referenced group does not
  18109. * contain any attribute uses.
  18110. */
  18111. sublist = ((xmlSchemaItemListPtr) gr->attrUses);
  18112. if ((sublist == NULL) || sublist->nbItems == 0) {
  18113. if (xmlSchemaItemListRemove(list, i) == -1)
  18114. return(-1);
  18115. i--;
  18116. continue;
  18117. }
  18118. /*
  18119. * Add the attribute uses.
  18120. */
  18121. list->items[i] = sublist->items[0];
  18122. if (sublist->nbItems != 1) {
  18123. for (j = 1; j < sublist->nbItems; j++) {
  18124. i++;
  18125. if (xmlSchemaItemListInsert(list,
  18126. sublist->items[j], i) == -1)
  18127. return(-1);
  18128. }
  18129. }
  18130. }
  18131. }
  18132. /*
  18133. * Handle pointless prohibitions of declared attributes.
  18134. */
  18135. if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
  18136. xmlSchemaAttributeUseProhibPtr prohib;
  18137. for (i = prohibs->nbItems -1; i >= 0; i--) {
  18138. prohib = prohibs->items[i];
  18139. for (j = 0; j < list->nbItems; j++) {
  18140. use = list->items[j];
  18141. if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
  18142. (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
  18143. {
  18144. xmlChar *str = NULL;
  18145. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  18146. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  18147. prohib->node, NULL,
  18148. "Skipping pointless attribute use prohibition "
  18149. "'%s', since a corresponding attribute use "
  18150. "exists already in the type definition",
  18151. xmlSchemaFormatQName(&str,
  18152. prohib->targetNamespace, prohib->name),
  18153. NULL, NULL);
  18154. FREE_AND_NULL(str);
  18155. /*
  18156. * Remove the prohibition.
  18157. */
  18158. if (xmlSchemaItemListRemove(prohibs, i) == -1)
  18159. return(-1);
  18160. break;
  18161. }
  18162. }
  18163. }
  18164. }
  18165. return(0);
  18166. }
  18167. /**
  18168. * xmlSchemaAttributeGroupExpandRefs:
  18169. * @pctxt: the parser context
  18170. * @attrGr: the attribute group definition
  18171. *
  18172. * Computation of:
  18173. * {attribute uses} property
  18174. * {attribute wildcard} property
  18175. *
  18176. * Substitutes contained attribute group references
  18177. * for their attribute uses. Wildcards are intersected.
  18178. */
  18179. static int
  18180. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18181. xmlSchemaAttributeGroupPtr attrGr)
  18182. {
  18183. if ((attrGr->attrUses == NULL) ||
  18184. (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
  18185. return(0);
  18186. attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
  18187. if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
  18188. &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
  18189. return(-1);
  18190. return(0);
  18191. }
  18192. /**
  18193. * xmlSchemaAttributeGroupExpandRefs:
  18194. * @pctxt: the parser context
  18195. * @attrGr: the attribute group definition
  18196. *
  18197. * Substitutes contained attribute group references
  18198. * for their attribute uses. Wildcards are intersected.
  18199. *
  18200. * Schema Component Constraint:
  18201. * Attribute Group Definition Properties Correct (ag-props-correct)
  18202. */
  18203. static int
  18204. xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18205. xmlSchemaAttributeGroupPtr attrGr)
  18206. {
  18207. /*
  18208. * SPEC ag-props-correct
  18209. * (1) "The values of the properties of an attribute group definition
  18210. * must be as described in the property tableau in The Attribute
  18211. * Group Definition Schema Component ($3.6.1), modulo the impact of
  18212. * Missing Sub-components ($5.3);"
  18213. */
  18214. if ((attrGr->attrUses != NULL) &&
  18215. (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
  18216. {
  18217. xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
  18218. xmlSchemaAttributeUsePtr use, tmp;
  18219. int i, j, hasId = 0;
  18220. for (i = uses->nbItems -1; i >= 0; i--) {
  18221. use = uses->items[i];
  18222. /*
  18223. * SPEC ag-props-correct
  18224. * (2) "Two distinct members of the {attribute uses} must not have
  18225. * {attribute declaration}s both of whose {name}s match and whose
  18226. * {target namespace}s are identical."
  18227. */
  18228. if (i > 0) {
  18229. for (j = i -1; j >= 0; j--) {
  18230. tmp = uses->items[j];
  18231. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  18232. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  18233. (WXS_ATTRUSE_DECL_TNS(use) ==
  18234. WXS_ATTRUSE_DECL_TNS(tmp)))
  18235. {
  18236. xmlChar *str = NULL;
  18237. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18238. XML_SCHEMAP_AG_PROPS_CORRECT,
  18239. attrGr->node, WXS_BASIC_CAST attrGr,
  18240. "Duplicate %s",
  18241. xmlSchemaGetComponentDesignation(&str, use),
  18242. NULL);
  18243. FREE_AND_NULL(str);
  18244. /*
  18245. * Remove the duplicate.
  18246. */
  18247. if (xmlSchemaItemListRemove(uses, i) == -1)
  18248. return(-1);
  18249. goto next_use;
  18250. }
  18251. }
  18252. }
  18253. /*
  18254. * SPEC ag-props-correct
  18255. * (3) "Two distinct members of the {attribute uses} must not have
  18256. * {attribute declaration}s both of whose {type definition}s are or
  18257. * are derived from ID."
  18258. * TODO: Does 'derived' include member-types of unions?
  18259. */
  18260. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  18261. if (xmlSchemaIsDerivedFromBuiltInType(
  18262. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  18263. {
  18264. if (hasId) {
  18265. xmlChar *str = NULL;
  18266. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18267. XML_SCHEMAP_AG_PROPS_CORRECT,
  18268. attrGr->node, WXS_BASIC_CAST attrGr,
  18269. "There must not exist more than one attribute "
  18270. "declaration of type 'xs:ID' "
  18271. "(or derived from 'xs:ID'). The %s violates this "
  18272. "constraint",
  18273. xmlSchemaGetComponentDesignation(&str, use),
  18274. NULL);
  18275. FREE_AND_NULL(str);
  18276. if (xmlSchemaItemListRemove(uses, i) == -1)
  18277. return(-1);
  18278. }
  18279. hasId = 1;
  18280. }
  18281. }
  18282. next_use: {}
  18283. }
  18284. }
  18285. return(0);
  18286. }
  18287. /**
  18288. * xmlSchemaResolveAttrGroupReferences:
  18289. * @attrgrpDecl: the schema attribute definition
  18290. * @ctxt: the schema parser context
  18291. * @name: the attribute name
  18292. *
  18293. * Resolves references to attribute group definitions.
  18294. */
  18295. static int
  18296. xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
  18297. xmlSchemaParserCtxtPtr ctxt)
  18298. {
  18299. xmlSchemaAttributeGroupPtr group;
  18300. if (ref->item != NULL)
  18301. return(0);
  18302. group = xmlSchemaGetAttributeGroup(ctxt->schema,
  18303. ref->name,
  18304. ref->targetNamespace);
  18305. if (group == NULL) {
  18306. xmlSchemaPResCompAttrErr(ctxt,
  18307. XML_SCHEMAP_SRC_RESOLVE,
  18308. NULL, ref->node,
  18309. "ref", ref->name, ref->targetNamespace,
  18310. ref->itemType, NULL);
  18311. return(ctxt->err);
  18312. }
  18313. ref->item = WXS_BASIC_CAST group;
  18314. return(0);
  18315. }
  18316. /**
  18317. * xmlSchemaCheckAttrPropsCorrect:
  18318. * @item: an schema attribute declaration/use
  18319. * @ctxt: a schema parser context
  18320. * @name: the name of the attribute
  18321. *
  18322. *
  18323. * Schema Component Constraint:
  18324. * Attribute Declaration Properties Correct (a-props-correct)
  18325. *
  18326. * Validates the value constraints of an attribute declaration/use.
  18327. * NOTE that this needs the simple type definitions to be already
  18328. * built and checked.
  18329. */
  18330. static int
  18331. xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18332. xmlSchemaAttributePtr attr)
  18333. {
  18334. /*
  18335. * SPEC a-props-correct (1)
  18336. * "The values of the properties of an attribute declaration must
  18337. * be as described in the property tableau in The Attribute
  18338. * Declaration Schema Component ($3.2.1), modulo the impact of
  18339. * Missing Sub-components ($5.3)."
  18340. */
  18341. if (WXS_ATTR_TYPEDEF(attr) == NULL)
  18342. return(0);
  18343. if (attr->defValue != NULL) {
  18344. int ret;
  18345. /*
  18346. * SPEC a-props-correct (3)
  18347. * "If the {type definition} is or is derived from ID then there
  18348. * must not be a {value constraint}."
  18349. */
  18350. if (xmlSchemaIsDerivedFromBuiltInType(
  18351. WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
  18352. {
  18353. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18354. XML_SCHEMAP_A_PROPS_CORRECT_3,
  18355. NULL, WXS_BASIC_CAST attr,
  18356. "Value constraints are not allowed if the type definition "
  18357. "is or is derived from xs:ID",
  18358. NULL, NULL);
  18359. return(pctxt->err);
  18360. }
  18361. /*
  18362. * SPEC a-props-correct (2)
  18363. * "if there is a {value constraint}, the canonical lexical
  18364. * representation of its value must be `valid` with respect
  18365. * to the {type definition} as defined in String Valid ($3.14.4)."
  18366. * TODO: Don't care about the *canonical* stuff here, this requirement
  18367. * will be removed in WXS 1.1 anyway.
  18368. */
  18369. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
  18370. attr->node, WXS_ATTR_TYPEDEF(attr),
  18371. attr->defValue, &(attr->defVal),
  18372. 1, 1, 0);
  18373. if (ret != 0) {
  18374. if (ret < 0) {
  18375. PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
  18376. "calling xmlSchemaVCheckCVCSimpleType()");
  18377. return(-1);
  18378. }
  18379. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18380. XML_SCHEMAP_A_PROPS_CORRECT_2,
  18381. NULL, WXS_BASIC_CAST attr,
  18382. "The value of the value constraint is not valid",
  18383. NULL, NULL);
  18384. return(pctxt->err);
  18385. }
  18386. }
  18387. return(0);
  18388. }
  18389. static xmlSchemaElementPtr
  18390. xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
  18391. xmlSchemaElementPtr ancestor)
  18392. {
  18393. xmlSchemaElementPtr ret;
  18394. if (WXS_SUBST_HEAD(ancestor) == NULL)
  18395. return (NULL);
  18396. if (WXS_SUBST_HEAD(ancestor) == elemDecl)
  18397. return (ancestor);
  18398. if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
  18399. return (NULL);
  18400. WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
  18401. ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
  18402. WXS_SUBST_HEAD(ancestor));
  18403. WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
  18404. return (ret);
  18405. }
  18406. /**
  18407. * xmlSchemaCheckElemPropsCorrect:
  18408. * @ctxt: a schema parser context
  18409. * @decl: the element declaration
  18410. * @name: the name of the attribute
  18411. *
  18412. * Schema Component Constraint:
  18413. * Element Declaration Properties Correct (e-props-correct)
  18414. *
  18415. * STATUS:
  18416. * missing: (6)
  18417. */
  18418. static int
  18419. xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18420. xmlSchemaElementPtr elemDecl)
  18421. {
  18422. int ret = 0;
  18423. xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
  18424. /*
  18425. * SPEC (1) "The values of the properties of an element declaration
  18426. * must be as described in the property tableau in The Element
  18427. * Declaration Schema Component ($3.3.1), modulo the impact of Missing
  18428. * Sub-components ($5.3)."
  18429. */
  18430. if (WXS_SUBST_HEAD(elemDecl) != NULL) {
  18431. xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
  18432. xmlSchemaCheckElementDeclComponent(head, pctxt);
  18433. /*
  18434. * SPEC (3) "If there is a non-`absent` {substitution group
  18435. * affiliation}, then {scope} must be global."
  18436. */
  18437. if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
  18438. xmlSchemaPCustomErr(pctxt,
  18439. XML_SCHEMAP_E_PROPS_CORRECT_3,
  18440. WXS_BASIC_CAST elemDecl, NULL,
  18441. "Only global element declarations can have a "
  18442. "substitution group affiliation", NULL);
  18443. ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
  18444. }
  18445. /*
  18446. * TODO: SPEC (6) "Circular substitution groups are disallowed.
  18447. * That is, it must not be possible to return to an element declaration
  18448. * by repeatedly following the {substitution group affiliation}
  18449. * property."
  18450. */
  18451. if (head == elemDecl)
  18452. circ = head;
  18453. else if (WXS_SUBST_HEAD(head) != NULL)
  18454. circ = xmlSchemaCheckSubstGroupCircular(head, head);
  18455. else
  18456. circ = NULL;
  18457. if (circ != NULL) {
  18458. xmlChar *strA = NULL, *strB = NULL;
  18459. xmlSchemaPCustomErrExt(pctxt,
  18460. XML_SCHEMAP_E_PROPS_CORRECT_6,
  18461. WXS_BASIC_CAST circ, NULL,
  18462. "The element declaration '%s' defines a circular "
  18463. "substitution group to element declaration '%s'",
  18464. xmlSchemaGetComponentQName(&strA, circ),
  18465. xmlSchemaGetComponentQName(&strB, head),
  18466. NULL);
  18467. FREE_AND_NULL(strA)
  18468. FREE_AND_NULL(strB)
  18469. ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
  18470. }
  18471. /*
  18472. * SPEC (4) "If there is a {substitution group affiliation},
  18473. * the {type definition}
  18474. * of the element declaration must be validly derived from the {type
  18475. * definition} of the {substitution group affiliation}, given the value
  18476. * of the {substitution group exclusions} of the {substitution group
  18477. * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
  18478. * (if the {type definition} is complex) or as defined in
  18479. * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
  18480. * simple)."
  18481. *
  18482. * NOTE: {substitution group exclusions} means the values of the
  18483. * attribute "final".
  18484. */
  18485. if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
  18486. int set = 0;
  18487. if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
  18488. set |= SUBSET_EXTENSION;
  18489. if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
  18490. set |= SUBSET_RESTRICTION;
  18491. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
  18492. WXS_ELEM_TYPEDEF(head), set) != 0) {
  18493. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  18494. ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
  18495. xmlSchemaPCustomErrExt(pctxt,
  18496. XML_SCHEMAP_E_PROPS_CORRECT_4,
  18497. WXS_BASIC_CAST elemDecl, NULL,
  18498. "The type definition '%s' was "
  18499. "either rejected by the substitution group "
  18500. "affiliation '%s', or not validly derived from its type "
  18501. "definition '%s'",
  18502. xmlSchemaGetComponentQName(&strA, typeDef),
  18503. xmlSchemaGetComponentQName(&strB, head),
  18504. xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
  18505. FREE_AND_NULL(strA)
  18506. FREE_AND_NULL(strB)
  18507. FREE_AND_NULL(strC)
  18508. }
  18509. }
  18510. }
  18511. /*
  18512. * SPEC (5) "If the {type definition} or {type definition}'s
  18513. * {content type}
  18514. * is or is derived from ID then there must not be a {value constraint}.
  18515. * Note: The use of ID as a type definition for elements goes beyond
  18516. * XML 1.0, and should be avoided if backwards compatibility is desired"
  18517. */
  18518. if ((elemDecl->value != NULL) &&
  18519. ((WXS_IS_SIMPLE(typeDef) &&
  18520. xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
  18521. (WXS_IS_COMPLEX(typeDef) &&
  18522. WXS_HAS_SIMPLE_CONTENT(typeDef) &&
  18523. xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
  18524. XML_SCHEMAS_ID)))) {
  18525. ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
  18526. xmlSchemaPCustomErr(pctxt,
  18527. XML_SCHEMAP_E_PROPS_CORRECT_5,
  18528. WXS_BASIC_CAST elemDecl, NULL,
  18529. "The type definition (or type definition's content type) is or "
  18530. "is derived from ID; value constraints are not allowed in "
  18531. "conjunction with such a type definition", NULL);
  18532. } else if (elemDecl->value != NULL) {
  18533. int vcret;
  18534. xmlNodePtr node = NULL;
  18535. /*
  18536. * SPEC (2) "If there is a {value constraint}, the canonical lexical
  18537. * representation of its value must be `valid` with respect to the
  18538. * {type definition} as defined in Element Default Valid (Immediate)
  18539. * ($3.3.6)."
  18540. */
  18541. if (typeDef == NULL) {
  18542. xmlSchemaPErr(pctxt, elemDecl->node,
  18543. XML_SCHEMAP_INTERNAL,
  18544. "Internal error: xmlSchemaCheckElemPropsCorrect, "
  18545. "type is missing... skipping validation of "
  18546. "the value constraint", NULL, NULL);
  18547. return (-1);
  18548. }
  18549. if (elemDecl->node != NULL) {
  18550. if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
  18551. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18552. BAD_CAST "fixed");
  18553. else
  18554. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18555. BAD_CAST "default");
  18556. }
  18557. vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
  18558. typeDef, elemDecl->value, &(elemDecl->defVal));
  18559. if (vcret != 0) {
  18560. if (vcret < 0) {
  18561. PERROR_INT("xmlSchemaElemCheckValConstr",
  18562. "failed to validate the value constraint of an "
  18563. "element declaration");
  18564. return (-1);
  18565. }
  18566. return (vcret);
  18567. }
  18568. }
  18569. return (ret);
  18570. }
  18571. /**
  18572. * xmlSchemaCheckElemSubstGroup:
  18573. * @ctxt: a schema parser context
  18574. * @decl: the element declaration
  18575. * @name: the name of the attribute
  18576. *
  18577. * Schema Component Constraint:
  18578. * Substitution Group (cos-equiv-class)
  18579. *
  18580. * In Libxml2 the subst. groups will be precomputed, in terms of that
  18581. * a list will be built for each subst. group head, holding all direct
  18582. * referents to this head.
  18583. * NOTE that this function needs:
  18584. * 1. circular subst. groups to be checked beforehand
  18585. * 2. the declaration's type to be derived from the head's type
  18586. *
  18587. * STATUS:
  18588. *
  18589. */
  18590. static void
  18591. xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
  18592. xmlSchemaElementPtr elemDecl)
  18593. {
  18594. if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
  18595. /* SPEC (1) "Its {abstract} is false." */
  18596. (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
  18597. return;
  18598. {
  18599. xmlSchemaElementPtr head;
  18600. xmlSchemaTypePtr headType, type;
  18601. int set, methSet;
  18602. /*
  18603. * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
  18604. * {disallowed substitutions} as the blocking constraint, as defined in
  18605. * Substitution Group OK (Transitive) ($3.3.6)."
  18606. */
  18607. for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
  18608. head = WXS_SUBST_HEAD(head)) {
  18609. set = 0;
  18610. methSet = 0;
  18611. /*
  18612. * The blocking constraints.
  18613. */
  18614. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
  18615. continue;
  18616. headType = head->subtypes;
  18617. type = elemDecl->subtypes;
  18618. if (headType == type)
  18619. goto add_member;
  18620. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
  18621. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18622. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
  18623. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18624. /*
  18625. * SPEC: Substitution Group OK (Transitive) (2.3)
  18626. * "The set of all {derivation method}s involved in the
  18627. * derivation of D's {type definition} from C's {type definition}
  18628. * does not intersect with the union of the blocking constraint,
  18629. * C's {prohibited substitutions} (if C is complex, otherwise the
  18630. * empty set) and the {prohibited substitutions} (respectively the
  18631. * empty set) of any intermediate {type definition}s in the
  18632. * derivation of D's {type definition} from C's {type definition}."
  18633. */
  18634. /*
  18635. * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
  18636. * subst.head axis, the methSet does not need to be computed for
  18637. * the full depth over and over.
  18638. */
  18639. /*
  18640. * The set of all {derivation method}s involved in the derivation
  18641. */
  18642. while ((type != NULL) && (type != headType) &&
  18643. (type != type->baseType)) {
  18644. if ((WXS_IS_EXTENSION(type)) &&
  18645. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18646. methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18647. if (WXS_IS_RESTRICTION(type) &&
  18648. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18649. methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18650. type = type->baseType;
  18651. }
  18652. /*
  18653. * The {prohibited substitutions} of all intermediate types +
  18654. * the head's type.
  18655. */
  18656. type = elemDecl->subtypes->baseType;
  18657. while (type != NULL) {
  18658. if (WXS_IS_COMPLEX(type)) {
  18659. if ((type->flags &
  18660. XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18661. ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
  18662. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18663. if ((type->flags &
  18664. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18665. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18666. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18667. } else
  18668. break;
  18669. if (type == headType)
  18670. break;
  18671. type = type->baseType;
  18672. }
  18673. if ((set != 0) &&
  18674. (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18675. (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
  18676. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18677. (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
  18678. continue;
  18679. }
  18680. add_member:
  18681. xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
  18682. if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
  18683. head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
  18684. }
  18685. }
  18686. }
  18687. #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
  18688. /**
  18689. * xmlSchemaCheckElementDeclComponent
  18690. * @pctxt: the schema parser context
  18691. * @ctxtComponent: the context component (an element declaration)
  18692. * @ctxtParticle: the first particle of the context component
  18693. * @searchParticle: the element declaration particle to be analysed
  18694. *
  18695. * Schema Component Constraint: Element Declarations Consistent
  18696. */
  18697. static int
  18698. xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
  18699. xmlSchemaBasicItemPtr ctxtComponent,
  18700. xmlSchemaParticlePtr ctxtParticle,
  18701. xmlSchemaParticlePtr searchParticle,
  18702. xmlSchemaParticlePtr curParticle,
  18703. int search)
  18704. {
  18705. return(0);
  18706. int ret = 0;
  18707. xmlSchemaParticlePtr cur = curParticle;
  18708. if (curParticle == NULL) {
  18709. return(0);
  18710. }
  18711. if (WXS_PARTICLE_TERM(curParticle) == NULL) {
  18712. /*
  18713. * Just return in this case. A missing "term" of the particle
  18714. * might arise due to an invalid "term" component.
  18715. */
  18716. return(0);
  18717. }
  18718. while (cur != NULL) {
  18719. switch (WXS_PARTICLE_TERM(cur)->type) {
  18720. case XML_SCHEMA_TYPE_ANY:
  18721. break;
  18722. case XML_SCHEMA_TYPE_ELEMENT:
  18723. if (search == 0) {
  18724. ret = xmlSchemaCheckElementDeclConsistent(pctxt,
  18725. ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
  18726. if (ret != 0)
  18727. return(ret);
  18728. } else {
  18729. xmlSchemaElementPtr elem =
  18730. WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
  18731. /*
  18732. * SPEC Element Declarations Consistent:
  18733. * "If the {particles} contains, either directly,
  18734. * indirectly (that is, within the {particles} of a
  18735. * contained model group, recursively) or `implicitly`
  18736. * two or more element declaration particles with
  18737. * the same {name} and {target namespace}, then
  18738. * all their type definitions must be the same
  18739. * top-level definition [...]"
  18740. */
  18741. if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
  18742. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
  18743. xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18744. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
  18745. {
  18746. xmlChar *strA = NULL, *strB = NULL;
  18747. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18748. /* TODO: error code */
  18749. XML_SCHEMAP_COS_NONAMBIG,
  18750. WXS_ITEM_NODE(cur), NULL,
  18751. "In the content model of %s, there are multiple "
  18752. "element declarations for '%s' with different "
  18753. "type definitions",
  18754. xmlSchemaGetComponentDesignation(&strA,
  18755. ctxtComponent),
  18756. xmlSchemaFormatQName(&strB,
  18757. WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18758. WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
  18759. FREE_AND_NULL(strA);
  18760. FREE_AND_NULL(strB);
  18761. return(XML_SCHEMAP_COS_NONAMBIG);
  18762. }
  18763. }
  18764. break;
  18765. case XML_SCHEMA_TYPE_SEQUENCE: {
  18766. break;
  18767. }
  18768. case XML_SCHEMA_TYPE_CHOICE:{
  18769. /*
  18770. xmlSchemaTreeItemPtr sub;
  18771. sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
  18772. while (sub != NULL) {
  18773. ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
  18774. ctxtParticle, ctxtElem);
  18775. if (ret != 0)
  18776. return(ret);
  18777. sub = sub->next;
  18778. }
  18779. */
  18780. break;
  18781. }
  18782. case XML_SCHEMA_TYPE_ALL:
  18783. break;
  18784. case XML_SCHEMA_TYPE_GROUP:
  18785. break;
  18786. default:
  18787. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  18788. "xmlSchemaCheckElementDeclConsistent",
  18789. "found unexpected term of type '%s' in content model",
  18790. WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
  18791. return(-1);
  18792. }
  18793. cur = (xmlSchemaParticlePtr) cur->next;
  18794. }
  18795. exit:
  18796. return(ret);
  18797. }
  18798. #endif
  18799. /**
  18800. * xmlSchemaCheckElementDeclComponent
  18801. * @item: an schema element declaration/particle
  18802. * @ctxt: a schema parser context
  18803. * @name: the name of the attribute
  18804. *
  18805. * Validates the value constraints of an element declaration.
  18806. * Adds substitution group members.
  18807. */
  18808. static void
  18809. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  18810. xmlSchemaParserCtxtPtr ctxt)
  18811. {
  18812. if (elemDecl == NULL)
  18813. return;
  18814. if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
  18815. return;
  18816. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
  18817. if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
  18818. /*
  18819. * Adds substitution group members.
  18820. */
  18821. xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
  18822. }
  18823. }
  18824. /**
  18825. * xmlSchemaResolveModelGroupParticleReferences:
  18826. * @particle: a particle component
  18827. * @ctxt: a parser context
  18828. *
  18829. * Resolves references of a model group's {particles} to
  18830. * model group definitions and to element declarations.
  18831. */
  18832. static void
  18833. xmlSchemaResolveModelGroupParticleReferences(
  18834. xmlSchemaParserCtxtPtr ctxt,
  18835. xmlSchemaModelGroupPtr mg)
  18836. {
  18837. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  18838. xmlSchemaQNameRefPtr ref;
  18839. xmlSchemaBasicItemPtr refItem;
  18840. /*
  18841. * URGENT TODO: Test this.
  18842. */
  18843. while (particle != NULL) {
  18844. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  18845. ((WXS_PARTICLE_TERM(particle))->type !=
  18846. XML_SCHEMA_EXTRA_QNAMEREF))
  18847. {
  18848. goto next_particle;
  18849. }
  18850. ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
  18851. /*
  18852. * Resolve the reference.
  18853. * NULL the {term} by default.
  18854. */
  18855. particle->children = NULL;
  18856. refItem = xmlSchemaGetNamedComponent(ctxt->schema,
  18857. ref->itemType, ref->name, ref->targetNamespace);
  18858. if (refItem == NULL) {
  18859. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  18860. NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
  18861. ref->targetNamespace, ref->itemType, NULL);
  18862. /* TODO: remove the particle. */
  18863. goto next_particle;
  18864. }
  18865. if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
  18866. if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
  18867. /* TODO: remove the particle. */
  18868. goto next_particle;
  18869. /*
  18870. * NOTE that we will assign the model group definition
  18871. * itself to the "term" of the particle. This will ease
  18872. * the check for circular model group definitions. After
  18873. * that the "term" will be assigned the model group of the
  18874. * model group definition.
  18875. */
  18876. if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
  18877. XML_SCHEMA_TYPE_ALL) {
  18878. /*
  18879. * SPEC cos-all-limited (1)
  18880. * SPEC cos-all-limited (1.2)
  18881. * "It appears only as the value of one or both of the
  18882. * following properties:"
  18883. * (1.1) "the {model group} property of a model group
  18884. * definition."
  18885. * (1.2) "the {term} property of a particle [... of] the "
  18886. * {content type} of a complex type definition."
  18887. */
  18888. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  18889. /* TODO: error code */
  18890. XML_SCHEMAP_COS_ALL_LIMITED,
  18891. WXS_ITEM_NODE(particle), NULL,
  18892. "A model group definition is referenced, but "
  18893. "it contains an 'all' model group, which "
  18894. "cannot be contained by model groups",
  18895. NULL, NULL);
  18896. /* TODO: remove the particle. */
  18897. goto next_particle;
  18898. }
  18899. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18900. } else {
  18901. /*
  18902. * TODO: Are referenced element declarations the only
  18903. * other components we expect here?
  18904. */
  18905. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18906. }
  18907. next_particle:
  18908. particle = WXS_PTC_CAST particle->next;
  18909. }
  18910. }
  18911. static int
  18912. xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
  18913. xmlSchemaValPtr y)
  18914. {
  18915. xmlSchemaTypePtr tx, ty, ptx, pty;
  18916. int ret;
  18917. while (x != NULL) {
  18918. /* Same types. */
  18919. tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
  18920. ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
  18921. ptx = xmlSchemaGetPrimitiveType(tx);
  18922. pty = xmlSchemaGetPrimitiveType(ty);
  18923. /*
  18924. * (1) if a datatype T' is `derived` by `restriction` from an
  18925. * atomic datatype T then the `value space` of T' is a subset of
  18926. * the `value space` of T. */
  18927. /*
  18928. * (2) if datatypes T' and T'' are `derived` by `restriction`
  18929. * from a common atomic ancestor T then the `value space`s of T'
  18930. * and T'' may overlap.
  18931. */
  18932. if (ptx != pty)
  18933. return(0);
  18934. /*
  18935. * We assume computed values to be normalized, so do a fast
  18936. * string comparison for string based types.
  18937. */
  18938. if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
  18939. WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
  18940. if (! xmlStrEqual(
  18941. xmlSchemaValueGetAsString(x),
  18942. xmlSchemaValueGetAsString(y)))
  18943. return (0);
  18944. } else {
  18945. ret = xmlSchemaCompareValuesWhtsp(
  18946. x, XML_SCHEMA_WHITESPACE_PRESERVE,
  18947. y, XML_SCHEMA_WHITESPACE_PRESERVE);
  18948. if (ret == -2)
  18949. return(-1);
  18950. if (ret != 0)
  18951. return(0);
  18952. }
  18953. /*
  18954. * Lists.
  18955. */
  18956. x = xmlSchemaValueGetNext(x);
  18957. if (x != NULL) {
  18958. y = xmlSchemaValueGetNext(y);
  18959. if (y == NULL)
  18960. return (0);
  18961. } else if (xmlSchemaValueGetNext(y) != NULL)
  18962. return (0);
  18963. else
  18964. return (1);
  18965. }
  18966. return (0);
  18967. }
  18968. /**
  18969. * xmlSchemaResolveAttrUseReferences:
  18970. * @item: an attribute use
  18971. * @ctxt: a parser context
  18972. *
  18973. * Resolves the referenced attribute declaration.
  18974. */
  18975. static int
  18976. xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
  18977. xmlSchemaParserCtxtPtr ctxt)
  18978. {
  18979. if ((ctxt == NULL) || (ause == NULL))
  18980. return(-1);
  18981. if ((ause->attrDecl == NULL) ||
  18982. (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
  18983. return(0);
  18984. {
  18985. xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
  18986. /*
  18987. * TODO: Evaluate, what errors could occur if the declaration is not
  18988. * found.
  18989. */
  18990. ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
  18991. ref->name, ref->targetNamespace);
  18992. if (ause->attrDecl == NULL) {
  18993. xmlSchemaPResCompAttrErr(ctxt,
  18994. XML_SCHEMAP_SRC_RESOLVE,
  18995. WXS_BASIC_CAST ause, ause->node,
  18996. "ref", ref->name, ref->targetNamespace,
  18997. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  18998. return(ctxt->err);;
  18999. }
  19000. }
  19001. return(0);
  19002. }
  19003. /**
  19004. * xmlSchemaCheckAttrUsePropsCorrect:
  19005. * @ctxt: a parser context
  19006. * @use: an attribute use
  19007. *
  19008. * Schema Component Constraint:
  19009. * Attribute Use Correct (au-props-correct)
  19010. *
  19011. */
  19012. static int
  19013. xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  19014. xmlSchemaAttributeUsePtr use)
  19015. {
  19016. if ((ctxt == NULL) || (use == NULL))
  19017. return(-1);
  19018. if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
  19019. ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
  19020. return(0);
  19021. /*
  19022. * SPEC au-props-correct (1)
  19023. * "The values of the properties of an attribute use must be as
  19024. * described in the property tableau in The Attribute Use Schema
  19025. * Component ($3.5.1), modulo the impact of Missing
  19026. * Sub-components ($5.3)."
  19027. */
  19028. if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
  19029. ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
  19030. ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19031. {
  19032. xmlSchemaPCustomErr(ctxt,
  19033. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19034. WXS_BASIC_CAST use, NULL,
  19035. "The attribute declaration has a 'fixed' value constraint "
  19036. ", thus the attribute use must also have a 'fixed' value "
  19037. "constraint",
  19038. NULL);
  19039. return(ctxt->err);
  19040. }
  19041. /*
  19042. * Compute and check the value constraint's value.
  19043. */
  19044. if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
  19045. int ret;
  19046. /*
  19047. * TODO: The spec seems to be missing a check of the
  19048. * value constraint of the attribute use. We will do it here.
  19049. */
  19050. /*
  19051. * SPEC a-props-correct (3)
  19052. */
  19053. if (xmlSchemaIsDerivedFromBuiltInType(
  19054. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  19055. {
  19056. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19057. XML_SCHEMAP_AU_PROPS_CORRECT,
  19058. NULL, WXS_BASIC_CAST use,
  19059. "Value constraints are not allowed if the type definition "
  19060. "is or is derived from xs:ID",
  19061. NULL, NULL);
  19062. return(ctxt->err);
  19063. }
  19064. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
  19065. use->node, WXS_ATTRUSE_TYPEDEF(use),
  19066. use->defValue, &(use->defVal),
  19067. 1, 1, 0);
  19068. if (ret != 0) {
  19069. if (ret < 0) {
  19070. PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
  19071. "calling xmlSchemaVCheckCVCSimpleType()");
  19072. return(-1);
  19073. }
  19074. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19075. XML_SCHEMAP_AU_PROPS_CORRECT,
  19076. NULL, WXS_BASIC_CAST use,
  19077. "The value of the value constraint is not valid",
  19078. NULL, NULL);
  19079. return(ctxt->err);
  19080. }
  19081. }
  19082. /*
  19083. * SPEC au-props-correct (2)
  19084. * "If the {attribute declaration} has a fixed
  19085. * {value constraint}, then if the attribute use itself has a
  19086. * {value constraint}, it must also be fixed and its value must match
  19087. * that of the {attribute declaration}'s {value constraint}."
  19088. */
  19089. if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
  19090. (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19091. {
  19092. if (! xmlSchemaAreValuesEqual(use->defVal,
  19093. (WXS_ATTRUSE_DECL(use))->defVal))
  19094. {
  19095. xmlSchemaPCustomErr(ctxt,
  19096. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19097. WXS_BASIC_CAST use, NULL,
  19098. "The 'fixed' value constraint of the attribute use "
  19099. "must match the attribute declaration's value "
  19100. "constraint '%s'",
  19101. (WXS_ATTRUSE_DECL(use))->defValue);
  19102. }
  19103. return(ctxt->err);
  19104. }
  19105. return(0);
  19106. }
  19107. /**
  19108. * xmlSchemaResolveAttrTypeReferences:
  19109. * @item: an attribute declaration
  19110. * @ctxt: a parser context
  19111. *
  19112. * Resolves the referenced type definition component.
  19113. */
  19114. static int
  19115. xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
  19116. xmlSchemaParserCtxtPtr ctxt)
  19117. {
  19118. /*
  19119. * The simple type definition corresponding to the <simpleType> element
  19120. * information item in the [children], if present, otherwise the simple
  19121. * type definition `resolved` to by the `actual value` of the type
  19122. * [attribute], if present, otherwise the `simple ur-type definition`.
  19123. */
  19124. if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
  19125. return(0);
  19126. item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
  19127. if (item->subtypes != NULL)
  19128. return(0);
  19129. if (item->typeName != NULL) {
  19130. xmlSchemaTypePtr type;
  19131. type = xmlSchemaGetType(ctxt->schema, item->typeName,
  19132. item->typeNs);
  19133. if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
  19134. xmlSchemaPResCompAttrErr(ctxt,
  19135. XML_SCHEMAP_SRC_RESOLVE,
  19136. WXS_BASIC_CAST item, item->node,
  19137. "type", item->typeName, item->typeNs,
  19138. XML_SCHEMA_TYPE_SIMPLE, NULL);
  19139. return(ctxt->err);
  19140. } else
  19141. item->subtypes = type;
  19142. } else {
  19143. /*
  19144. * The type defaults to the xs:anySimpleType.
  19145. */
  19146. item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  19147. }
  19148. return(0);
  19149. }
  19150. /**
  19151. * xmlSchemaResolveIDCKeyReferences:
  19152. * @idc: the identity-constraint definition
  19153. * @ctxt: the schema parser context
  19154. * @name: the attribute name
  19155. *
  19156. * Resolve keyRef references to key/unique IDCs.
  19157. * Schema Component Constraint:
  19158. * Identity-constraint Definition Properties Correct (c-props-correct)
  19159. */
  19160. static int
  19161. xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
  19162. xmlSchemaParserCtxtPtr pctxt)
  19163. {
  19164. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
  19165. return(0);
  19166. if (idc->ref->name != NULL) {
  19167. idc->ref->item = (xmlSchemaBasicItemPtr)
  19168. xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
  19169. idc->ref->targetNamespace);
  19170. if (idc->ref->item == NULL) {
  19171. /*
  19172. * TODO: It is actually not an error to fail to resolve
  19173. * at this stage. BUT we need to be that strict!
  19174. */
  19175. xmlSchemaPResCompAttrErr(pctxt,
  19176. XML_SCHEMAP_SRC_RESOLVE,
  19177. WXS_BASIC_CAST idc, idc->node,
  19178. "refer", idc->ref->name,
  19179. idc->ref->targetNamespace,
  19180. XML_SCHEMA_TYPE_IDC_KEY, NULL);
  19181. return(pctxt->err);
  19182. } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  19183. /*
  19184. * SPEC c-props-correct (1)
  19185. */
  19186. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19187. XML_SCHEMAP_C_PROPS_CORRECT,
  19188. NULL, WXS_BASIC_CAST idc,
  19189. "The keyref references a keyref",
  19190. NULL, NULL);
  19191. idc->ref->item = NULL;
  19192. return(pctxt->err);
  19193. } else {
  19194. if (idc->nbFields !=
  19195. ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
  19196. xmlChar *str = NULL;
  19197. xmlSchemaIDCPtr refer;
  19198. refer = (xmlSchemaIDCPtr) idc->ref->item;
  19199. /*
  19200. * SPEC c-props-correct(2)
  19201. * "If the {identity-constraint category} is keyref,
  19202. * the cardinality of the {fields} must equal that of
  19203. * the {fields} of the {referenced key}.
  19204. */
  19205. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19206. XML_SCHEMAP_C_PROPS_CORRECT,
  19207. NULL, WXS_BASIC_CAST idc,
  19208. "The cardinality of the keyref differs from the "
  19209. "cardinality of the referenced key/unique '%s'",
  19210. xmlSchemaFormatQName(&str, refer->targetNamespace,
  19211. refer->name),
  19212. NULL);
  19213. FREE_AND_NULL(str)
  19214. return(pctxt->err);
  19215. }
  19216. }
  19217. }
  19218. return(0);
  19219. }
  19220. static int
  19221. xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
  19222. xmlSchemaParserCtxtPtr pctxt)
  19223. {
  19224. if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
  19225. prohib->targetNamespace) == NULL) {
  19226. xmlSchemaPResCompAttrErr(pctxt,
  19227. XML_SCHEMAP_SRC_RESOLVE,
  19228. NULL, prohib->node,
  19229. "ref", prohib->name, prohib->targetNamespace,
  19230. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19231. return(XML_SCHEMAP_SRC_RESOLVE);
  19232. }
  19233. return(0);
  19234. }
  19235. #define WXS_REDEFINED_TYPE(c) \
  19236. (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
  19237. #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
  19238. (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19239. #define WXS_REDEFINED_ATTR_GROUP(c) \
  19240. (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19241. static int
  19242. xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
  19243. {
  19244. int err = 0;
  19245. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19246. xmlSchemaBasicItemPtr prev, item;
  19247. int wasRedefined;
  19248. if (redef == NULL)
  19249. return(0);
  19250. do {
  19251. item = redef->item;
  19252. /*
  19253. * First try to locate the redefined component in the
  19254. * schema graph starting with the redefined schema.
  19255. * NOTE: According to this schema bug entry:
  19256. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
  19257. * it's not clear if the referenced component needs to originate
  19258. * from the <redefine>d schema _document_ or the schema; the latter
  19259. * would include all imported and included sub-schemas of the
  19260. * <redefine>d schema. Currently the latter approach is used.
  19261. * SUPPLEMENT: It seems that the WG moves towards the latter
  19262. * approach, so we are doing it right.
  19263. *
  19264. */
  19265. prev = xmlSchemaFindRedefCompInGraph(
  19266. redef->targetBucket, item->type,
  19267. redef->refName, redef->refTargetNs);
  19268. if (prev == NULL) {
  19269. xmlChar *str = NULL;
  19270. xmlNodePtr node;
  19271. /*
  19272. * SPEC src-redefine:
  19273. * (6.2.1) "The `actual value` of its own name attribute plus
  19274. * target namespace must successfully `resolve` to a model
  19275. * group definition in I."
  19276. * (7.2.1) "The `actual value` of its own name attribute plus
  19277. * target namespace must successfully `resolve` to an attribute
  19278. * group definition in I."
  19279. *
  19280. * Note that, if we are redefining with the use of references
  19281. * to components, the spec assumes the src-resolve to be used;
  19282. * but this won't assure that we search only *inside* the
  19283. * redefined schema.
  19284. */
  19285. if (redef->reference)
  19286. node = WXS_ITEM_NODE(redef->reference);
  19287. else
  19288. node = WXS_ITEM_NODE(item);
  19289. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19290. /*
  19291. * TODO: error code.
  19292. * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
  19293. * reference kind.
  19294. */
  19295. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  19296. "The %s '%s' to be redefined could not be found in "
  19297. "the redefined schema",
  19298. WXS_ITEM_TYPE_NAME(item),
  19299. xmlSchemaFormatQName(&str, redef->refTargetNs,
  19300. redef->refName));
  19301. FREE_AND_NULL(str);
  19302. err = pctxt->err;
  19303. redef = redef->next;
  19304. continue;
  19305. }
  19306. /*
  19307. * TODO: Obtaining and setting the redefinition state is really
  19308. * clumsy.
  19309. */
  19310. wasRedefined = 0;
  19311. switch (item->type) {
  19312. case XML_SCHEMA_TYPE_COMPLEX:
  19313. case XML_SCHEMA_TYPE_SIMPLE:
  19314. if ((WXS_TYPE_CAST prev)->flags &
  19315. XML_SCHEMAS_TYPE_REDEFINED)
  19316. {
  19317. wasRedefined = 1;
  19318. break;
  19319. }
  19320. /* Mark it as redefined. */
  19321. (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
  19322. /*
  19323. * Assign the redefined type to the
  19324. * base type of the redefining type.
  19325. * TODO: How
  19326. */
  19327. ((xmlSchemaTypePtr) item)->baseType =
  19328. (xmlSchemaTypePtr) prev;
  19329. break;
  19330. case XML_SCHEMA_TYPE_GROUP:
  19331. if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
  19332. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19333. {
  19334. wasRedefined = 1;
  19335. break;
  19336. }
  19337. /* Mark it as redefined. */
  19338. (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
  19339. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
  19340. if (redef->reference != NULL) {
  19341. /*
  19342. * Overwrite the QName-reference with the
  19343. * referenced model group def.
  19344. */
  19345. (WXS_PTC_CAST redef->reference)->children =
  19346. WXS_TREE_CAST prev;
  19347. }
  19348. redef->target = prev;
  19349. break;
  19350. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19351. if ((WXS_ATTR_GROUP_CAST prev)->flags &
  19352. XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19353. {
  19354. wasRedefined = 1;
  19355. break;
  19356. }
  19357. (WXS_ATTR_GROUP_CAST prev)->flags |=
  19358. XML_SCHEMAS_ATTRGROUP_REDEFINED;
  19359. if (redef->reference != NULL) {
  19360. /*
  19361. * Assign the redefined attribute group to the
  19362. * QName-reference component.
  19363. * This is the easy case, since we will just
  19364. * expand the redefined group.
  19365. */
  19366. (WXS_QNAME_CAST redef->reference)->item = prev;
  19367. redef->target = NULL;
  19368. } else {
  19369. /*
  19370. * This is the complicated case: we need
  19371. * to apply src-redefine (7.2.2) at a later
  19372. * stage, i.e. when attribute group references
  19373. * have been expanded and simple types have
  19374. * been fixed.
  19375. */
  19376. redef->target = prev;
  19377. }
  19378. break;
  19379. default:
  19380. PERROR_INT("xmlSchemaResolveRedefReferences",
  19381. "Unexpected redefined component type");
  19382. return(-1);
  19383. }
  19384. if (wasRedefined) {
  19385. xmlChar *str = NULL;
  19386. xmlNodePtr node;
  19387. if (redef->reference)
  19388. node = WXS_ITEM_NODE(redef->reference);
  19389. else
  19390. node = WXS_ITEM_NODE(redef->item);
  19391. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19392. /* TODO: error code. */
  19393. XML_SCHEMAP_SRC_REDEFINE,
  19394. node, NULL,
  19395. "The referenced %s was already redefined. Multiple "
  19396. "redefinition of the same component is not supported",
  19397. xmlSchemaGetComponentDesignation(&str, prev),
  19398. NULL);
  19399. FREE_AND_NULL(str)
  19400. err = pctxt->err;
  19401. redef = redef->next;
  19402. continue;
  19403. }
  19404. redef = redef->next;
  19405. } while (redef != NULL);
  19406. return(err);
  19407. }
  19408. static int
  19409. xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
  19410. {
  19411. int err = 0;
  19412. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19413. xmlSchemaBasicItemPtr item;
  19414. if (redef == NULL)
  19415. return(0);
  19416. do {
  19417. if (redef->target == NULL) {
  19418. redef = redef->next;
  19419. continue;
  19420. }
  19421. item = redef->item;
  19422. switch (item->type) {
  19423. case XML_SCHEMA_TYPE_SIMPLE:
  19424. case XML_SCHEMA_TYPE_COMPLEX:
  19425. /*
  19426. * Since the spec wants the {name} of the redefined
  19427. * type to be 'absent', we'll NULL it.
  19428. */
  19429. (WXS_TYPE_CAST redef->target)->name = NULL;
  19430. /*
  19431. * TODO: Seems like there's nothing more to do. The normal
  19432. * inheritance mechanism is used. But not 100% sure.
  19433. */
  19434. break;
  19435. case XML_SCHEMA_TYPE_GROUP:
  19436. /*
  19437. * URGENT TODO:
  19438. * SPEC src-redefine:
  19439. * (6.2.2) "The {model group} of the model group definition
  19440. * which corresponds to it per XML Representation of Model
  19441. * Group Definition Schema Components ($3.7.2) must be a
  19442. * `valid restriction` of the {model group} of that model
  19443. * group definition in I, as defined in Particle Valid
  19444. * (Restriction) ($3.9.6)."
  19445. */
  19446. break;
  19447. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19448. /*
  19449. * SPEC src-redefine:
  19450. * (7.2.2) "The {attribute uses} and {attribute wildcard} of
  19451. * the attribute group definition which corresponds to it
  19452. * per XML Representation of Attribute Group Definition Schema
  19453. * Components ($3.6.2) must be `valid restrictions` of the
  19454. * {attribute uses} and {attribute wildcard} of that attribute
  19455. * group definition in I, as defined in clause 2, clause 3 and
  19456. * clause 4 of Derivation Valid (Restriction, Complex)
  19457. * ($3.4.6) (where references to the base type definition are
  19458. * understood as references to the attribute group definition
  19459. * in I)."
  19460. */
  19461. err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
  19462. XML_SCHEMA_ACTION_REDEFINE,
  19463. item, redef->target,
  19464. (WXS_ATTR_GROUP_CAST item)->attrUses,
  19465. (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
  19466. (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
  19467. (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
  19468. if (err == -1)
  19469. return(-1);
  19470. break;
  19471. default:
  19472. break;
  19473. }
  19474. redef = redef->next;
  19475. } while (redef != NULL);
  19476. return(0);
  19477. }
  19478. static int
  19479. xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
  19480. xmlSchemaBucketPtr bucket)
  19481. {
  19482. xmlSchemaBasicItemPtr item;
  19483. int err;
  19484. xmlHashTablePtr *table;
  19485. const xmlChar *name;
  19486. int i;
  19487. #define WXS_GET_GLOBAL_HASH(c, slot) { \
  19488. if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
  19489. table = &(WXS_IMPBUCKET((c))->schema->slot); \
  19490. else \
  19491. table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
  19492. /*
  19493. * Add global components to the schema's hash tables.
  19494. * This is the place where duplicate components will be
  19495. * detected.
  19496. * TODO: I think normally we should support imports of the
  19497. * same namespace from multiple locations. We don't do currently,
  19498. * but if we do then according to:
  19499. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
  19500. * we would need, if imported directly, to import redefined
  19501. * components as well to be able to catch clashing components.
  19502. * (I hope I'll still know what this means after some months :-()
  19503. */
  19504. if (bucket == NULL)
  19505. return(-1);
  19506. if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
  19507. return(0);
  19508. bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
  19509. for (i = 0; i < bucket->globals->nbItems; i++) {
  19510. item = bucket->globals->items[i];
  19511. table = NULL;
  19512. switch (item->type) {
  19513. case XML_SCHEMA_TYPE_COMPLEX:
  19514. case XML_SCHEMA_TYPE_SIMPLE:
  19515. if (WXS_REDEFINED_TYPE(item))
  19516. continue;
  19517. name = (WXS_TYPE_CAST item)->name;
  19518. WXS_GET_GLOBAL_HASH(bucket, typeDecl)
  19519. break;
  19520. case XML_SCHEMA_TYPE_ELEMENT:
  19521. name = (WXS_ELEM_CAST item)->name;
  19522. WXS_GET_GLOBAL_HASH(bucket, elemDecl)
  19523. break;
  19524. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19525. name = (WXS_ATTR_CAST item)->name;
  19526. WXS_GET_GLOBAL_HASH(bucket, attrDecl)
  19527. break;
  19528. case XML_SCHEMA_TYPE_GROUP:
  19529. if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
  19530. continue;
  19531. name = (WXS_MODEL_GROUPDEF_CAST item)->name;
  19532. WXS_GET_GLOBAL_HASH(bucket, groupDecl)
  19533. break;
  19534. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19535. if (WXS_REDEFINED_ATTR_GROUP(item))
  19536. continue;
  19537. name = (WXS_ATTR_GROUP_CAST item)->name;
  19538. WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
  19539. break;
  19540. case XML_SCHEMA_TYPE_IDC_KEY:
  19541. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19542. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19543. name = (WXS_IDC_CAST item)->name;
  19544. WXS_GET_GLOBAL_HASH(bucket, idcDef)
  19545. break;
  19546. case XML_SCHEMA_TYPE_NOTATION:
  19547. name = ((xmlSchemaNotationPtr) item)->name;
  19548. WXS_GET_GLOBAL_HASH(bucket, notaDecl)
  19549. break;
  19550. default:
  19551. PERROR_INT("xmlSchemaAddComponents",
  19552. "Unexpected global component type");
  19553. continue;
  19554. }
  19555. if (*table == NULL) {
  19556. *table = xmlHashCreateDict(10, pctxt->dict);
  19557. if (*table == NULL) {
  19558. PERROR_INT("xmlSchemaAddComponents",
  19559. "failed to create a component hash table");
  19560. return(-1);
  19561. }
  19562. }
  19563. err = xmlHashAddEntry(*table, name, item);
  19564. if (err != 0) {
  19565. xmlChar *str = NULL;
  19566. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19567. XML_SCHEMAP_REDEFINED_TYPE,
  19568. WXS_ITEM_NODE(item),
  19569. WXS_BASIC_CAST item,
  19570. "A global %s '%s' does already exist",
  19571. WXS_ITEM_TYPE_NAME(item),
  19572. xmlSchemaGetComponentQName(&str, item));
  19573. FREE_AND_NULL(str);
  19574. }
  19575. }
  19576. /*
  19577. * Process imported/included schemas.
  19578. */
  19579. if (bucket->relations != NULL) {
  19580. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  19581. do {
  19582. if ((rel->bucket != NULL) &&
  19583. ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
  19584. if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
  19585. return(-1);
  19586. }
  19587. rel = rel->next;
  19588. } while (rel != NULL);
  19589. }
  19590. return(0);
  19591. }
  19592. static int
  19593. xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
  19594. xmlSchemaBucketPtr rootBucket)
  19595. {
  19596. xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
  19597. xmlSchemaTreeItemPtr item, *items;
  19598. int nbItems, i, ret = 0;
  19599. xmlSchemaBucketPtr oldbucket = con->bucket;
  19600. xmlSchemaElementPtr elemDecl;
  19601. #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
  19602. if ((con->pending == NULL) ||
  19603. (con->pending->nbItems == 0))
  19604. return(0);
  19605. /*
  19606. * Since xmlSchemaFixupComplexType() will create new particles
  19607. * (local components), and those particle components need a bucket
  19608. * on the constructor, we'll assure here that the constructor has
  19609. * a bucket.
  19610. * TODO: Think about storing locals _only_ on the main bucket.
  19611. */
  19612. if (con->bucket == NULL)
  19613. con->bucket = rootBucket;
  19614. /* TODO:
  19615. * SPEC (src-redefine):
  19616. * (6.2) "If it has no such self-reference, then all of the
  19617. * following must be true:"
  19618. * (6.2.2) The {model group} of the model group definition which
  19619. * corresponds to it per XML Representation of Model Group
  19620. * Definition Schema Components ($3.7.2) must be a `valid
  19621. * restriction` of the {model group} of that model group definition
  19622. * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
  19623. */
  19624. xmlSchemaCheckSRCRedefineFirst(pctxt);
  19625. /*
  19626. * Add global components to the schemata's hash tables.
  19627. */
  19628. xmlSchemaAddComponents(pctxt, rootBucket);
  19629. pctxt->ctxtType = NULL;
  19630. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19631. nbItems = con->pending->nbItems;
  19632. /*
  19633. * Now that we have parsed *all* the schema document(s) and converted
  19634. * them to schema components, we can resolve references, apply component
  19635. * constraints, create the FSA from the content model, etc.
  19636. */
  19637. /*
  19638. * Resolve references of..
  19639. *
  19640. * 1. element declarations:
  19641. * - the type definition
  19642. * - the substitution group affiliation
  19643. * 2. simple/complex types:
  19644. * - the base type definition
  19645. * - the memberTypes of union types
  19646. * - the itemType of list types
  19647. * 3. attributes declarations and attribute uses:
  19648. * - the type definition
  19649. * - if an attribute use, then the attribute declaration
  19650. * 4. attribute group references:
  19651. * - the attribute group definition
  19652. * 5. particles:
  19653. * - the term of the particle (e.g. a model group)
  19654. * 6. IDC key-references:
  19655. * - the referenced IDC 'key' or 'unique' definition
  19656. * 7. Attribute prohibitions which had a "ref" attribute.
  19657. */
  19658. for (i = 0; i < nbItems; i++) {
  19659. item = items[i];
  19660. switch (item->type) {
  19661. case XML_SCHEMA_TYPE_ELEMENT:
  19662. xmlSchemaResolveElementReferences(
  19663. (xmlSchemaElementPtr) item, pctxt);
  19664. FIXHFAILURE;
  19665. break;
  19666. case XML_SCHEMA_TYPE_COMPLEX:
  19667. case XML_SCHEMA_TYPE_SIMPLE:
  19668. xmlSchemaResolveTypeReferences(
  19669. (xmlSchemaTypePtr) item, pctxt);
  19670. FIXHFAILURE;
  19671. break;
  19672. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19673. xmlSchemaResolveAttrTypeReferences(
  19674. (xmlSchemaAttributePtr) item, pctxt);
  19675. FIXHFAILURE;
  19676. break;
  19677. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19678. xmlSchemaResolveAttrUseReferences(
  19679. (xmlSchemaAttributeUsePtr) item, pctxt);
  19680. FIXHFAILURE;
  19681. break;
  19682. case XML_SCHEMA_EXTRA_QNAMEREF:
  19683. if ((WXS_QNAME_CAST item)->itemType ==
  19684. XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
  19685. {
  19686. xmlSchemaResolveAttrGroupReferences(
  19687. WXS_QNAME_CAST item, pctxt);
  19688. }
  19689. FIXHFAILURE;
  19690. break;
  19691. case XML_SCHEMA_TYPE_SEQUENCE:
  19692. case XML_SCHEMA_TYPE_CHOICE:
  19693. case XML_SCHEMA_TYPE_ALL:
  19694. xmlSchemaResolveModelGroupParticleReferences(pctxt,
  19695. WXS_MODEL_GROUP_CAST item);
  19696. FIXHFAILURE;
  19697. break;
  19698. case XML_SCHEMA_TYPE_IDC_KEY:
  19699. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19700. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19701. xmlSchemaResolveIDCKeyReferences(
  19702. (xmlSchemaIDCPtr) item, pctxt);
  19703. FIXHFAILURE;
  19704. break;
  19705. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  19706. /*
  19707. * Handle attribute prohibition which had a
  19708. * "ref" attribute.
  19709. */
  19710. xmlSchemaResolveAttrUseProhibReferences(
  19711. WXS_ATTR_PROHIB_CAST item, pctxt);
  19712. FIXHFAILURE;
  19713. break;
  19714. default:
  19715. break;
  19716. }
  19717. }
  19718. if (pctxt->nberrors != 0)
  19719. goto exit_error;
  19720. /*
  19721. * Now that all references are resolved we
  19722. * can check for circularity of...
  19723. * 1. the base axis of type definitions
  19724. * 2. nested model group definitions
  19725. * 3. nested attribute group definitions
  19726. * TODO: check for circular substitution groups.
  19727. */
  19728. for (i = 0; i < nbItems; i++) {
  19729. item = items[i];
  19730. /*
  19731. * Let's better stop on the first error here.
  19732. */
  19733. switch (item->type) {
  19734. case XML_SCHEMA_TYPE_COMPLEX:
  19735. case XML_SCHEMA_TYPE_SIMPLE:
  19736. xmlSchemaCheckTypeDefCircular(
  19737. (xmlSchemaTypePtr) item, pctxt);
  19738. FIXHFAILURE;
  19739. if (pctxt->nberrors != 0)
  19740. goto exit_error;
  19741. break;
  19742. case XML_SCHEMA_TYPE_GROUP:
  19743. xmlSchemaCheckGroupDefCircular(
  19744. (xmlSchemaModelGroupDefPtr) item, pctxt);
  19745. FIXHFAILURE;
  19746. if (pctxt->nberrors != 0)
  19747. goto exit_error;
  19748. break;
  19749. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19750. xmlSchemaCheckAttrGroupCircular(
  19751. (xmlSchemaAttributeGroupPtr) item, pctxt);
  19752. FIXHFAILURE;
  19753. if (pctxt->nberrors != 0)
  19754. goto exit_error;
  19755. break;
  19756. default:
  19757. break;
  19758. }
  19759. }
  19760. if (pctxt->nberrors != 0)
  19761. goto exit_error;
  19762. /*
  19763. * Model group definition references:
  19764. * Such a reference is reflected by a particle at the component
  19765. * level. Until now the 'term' of such particles pointed
  19766. * to the model group definition; this was done, in order to
  19767. * ease circularity checks. Now we need to set the 'term' of
  19768. * such particles to the model group of the model group definition.
  19769. */
  19770. for (i = 0; i < nbItems; i++) {
  19771. item = items[i];
  19772. switch (item->type) {
  19773. case XML_SCHEMA_TYPE_SEQUENCE:
  19774. case XML_SCHEMA_TYPE_CHOICE:
  19775. xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
  19776. WXS_MODEL_GROUP_CAST item);
  19777. break;
  19778. default:
  19779. break;
  19780. }
  19781. }
  19782. if (pctxt->nberrors != 0)
  19783. goto exit_error;
  19784. /*
  19785. * Expand attribute group references of attribute group definitions.
  19786. */
  19787. for (i = 0; i < nbItems; i++) {
  19788. item = items[i];
  19789. switch (item->type) {
  19790. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19791. if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
  19792. WXS_ATTR_GROUP_HAS_REFS(item))
  19793. {
  19794. xmlSchemaAttributeGroupExpandRefs(pctxt,
  19795. WXS_ATTR_GROUP_CAST item);
  19796. FIXHFAILURE;
  19797. }
  19798. break;
  19799. default:
  19800. break;
  19801. }
  19802. }
  19803. if (pctxt->nberrors != 0)
  19804. goto exit_error;
  19805. /*
  19806. * First compute the variety of simple types. This is needed as
  19807. * a separate step, since otherwise we won't be able to detect
  19808. * circular union types in all cases.
  19809. */
  19810. for (i = 0; i < nbItems; i++) {
  19811. item = items[i];
  19812. switch (item->type) {
  19813. case XML_SCHEMA_TYPE_SIMPLE:
  19814. if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
  19815. xmlSchemaFixupSimpleTypeStageOne(pctxt,
  19816. (xmlSchemaTypePtr) item);
  19817. FIXHFAILURE;
  19818. }
  19819. break;
  19820. default:
  19821. break;
  19822. }
  19823. }
  19824. if (pctxt->nberrors != 0)
  19825. goto exit_error;
  19826. /*
  19827. * Detect circular union types. Note that this needs the variety to
  19828. * be already computed.
  19829. */
  19830. for (i = 0; i < nbItems; i++) {
  19831. item = items[i];
  19832. switch (item->type) {
  19833. case XML_SCHEMA_TYPE_SIMPLE:
  19834. if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
  19835. xmlSchemaCheckUnionTypeDefCircular(pctxt,
  19836. (xmlSchemaTypePtr) item);
  19837. FIXHFAILURE;
  19838. }
  19839. break;
  19840. default:
  19841. break;
  19842. }
  19843. }
  19844. if (pctxt->nberrors != 0)
  19845. goto exit_error;
  19846. /*
  19847. * Do the complete type fixup for simple types.
  19848. */
  19849. for (i = 0; i < nbItems; i++) {
  19850. item = items[i];
  19851. switch (item->type) {
  19852. case XML_SCHEMA_TYPE_SIMPLE:
  19853. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  19854. xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
  19855. FIXHFAILURE;
  19856. }
  19857. break;
  19858. default:
  19859. break;
  19860. }
  19861. }
  19862. if (pctxt->nberrors != 0)
  19863. goto exit_error;
  19864. /*
  19865. * At this point we need build and check all simple types.
  19866. */
  19867. /*
  19868. * Apply constraints for attribute declarations.
  19869. */
  19870. for (i = 0; i < nbItems; i++) {
  19871. item = items[i];
  19872. switch (item->type) {
  19873. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19874. xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
  19875. FIXHFAILURE;
  19876. break;
  19877. default:
  19878. break;
  19879. }
  19880. }
  19881. if (pctxt->nberrors != 0)
  19882. goto exit_error;
  19883. /*
  19884. * Apply constraints for attribute uses.
  19885. */
  19886. for (i = 0; i < nbItems; i++) {
  19887. item = items[i];
  19888. switch (item->type) {
  19889. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19890. if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
  19891. xmlSchemaCheckAttrUsePropsCorrect(pctxt,
  19892. WXS_ATTR_USE_CAST item);
  19893. FIXHFAILURE;
  19894. }
  19895. break;
  19896. default:
  19897. break;
  19898. }
  19899. }
  19900. if (pctxt->nberrors != 0)
  19901. goto exit_error;
  19902. /*
  19903. * Apply constraints for attribute group definitions.
  19904. */
  19905. for (i = 0; i < nbItems; i++) {
  19906. item = items[i];
  19907. switch (item->type) {
  19908. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19909. if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
  19910. ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
  19911. {
  19912. xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
  19913. FIXHFAILURE;
  19914. }
  19915. break;
  19916. default:
  19917. break;
  19918. }
  19919. }
  19920. if (pctxt->nberrors != 0)
  19921. goto exit_error;
  19922. /*
  19923. * Apply constraints for redefinitions.
  19924. */
  19925. if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
  19926. xmlSchemaCheckSRCRedefineSecond(pctxt);
  19927. if (pctxt->nberrors != 0)
  19928. goto exit_error;
  19929. /*
  19930. * Complex types are built and checked.
  19931. */
  19932. for (i = 0; i < nbItems; i++) {
  19933. item = con->pending->items[i];
  19934. switch (item->type) {
  19935. case XML_SCHEMA_TYPE_COMPLEX:
  19936. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  19937. xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
  19938. FIXHFAILURE;
  19939. }
  19940. break;
  19941. default:
  19942. break;
  19943. }
  19944. }
  19945. if (pctxt->nberrors != 0)
  19946. goto exit_error;
  19947. /*
  19948. * The list could have changed, since xmlSchemaFixupComplexType()
  19949. * will create particles and model groups in some cases.
  19950. */
  19951. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19952. nbItems = con->pending->nbItems;
  19953. /*
  19954. * Apply some constraints for element declarations.
  19955. */
  19956. for (i = 0; i < nbItems; i++) {
  19957. item = items[i];
  19958. switch (item->type) {
  19959. case XML_SCHEMA_TYPE_ELEMENT:
  19960. elemDecl = (xmlSchemaElementPtr) item;
  19961. if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
  19962. {
  19963. xmlSchemaCheckElementDeclComponent(
  19964. (xmlSchemaElementPtr) elemDecl, pctxt);
  19965. FIXHFAILURE;
  19966. }
  19967. #ifdef WXS_ELEM_DECL_CONS_ENABLED
  19968. /*
  19969. * Schema Component Constraint: Element Declarations Consistent
  19970. * Apply this constraint to local types of element declarations.
  19971. */
  19972. if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
  19973. (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
  19974. (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
  19975. {
  19976. xmlSchemaCheckElementDeclConsistent(pctxt,
  19977. WXS_BASIC_CAST elemDecl,
  19978. WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
  19979. NULL, NULL, 0);
  19980. }
  19981. #endif
  19982. break;
  19983. default:
  19984. break;
  19985. }
  19986. }
  19987. if (pctxt->nberrors != 0)
  19988. goto exit_error;
  19989. /*
  19990. * Finally we can build the automaton from the content model of
  19991. * complex types.
  19992. */
  19993. for (i = 0; i < nbItems; i++) {
  19994. item = items[i];
  19995. switch (item->type) {
  19996. case XML_SCHEMA_TYPE_COMPLEX:
  19997. xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
  19998. /* FIXHFAILURE; */
  19999. break;
  20000. default:
  20001. break;
  20002. }
  20003. }
  20004. if (pctxt->nberrors != 0)
  20005. goto exit_error;
  20006. /*
  20007. * URGENT TODO: cos-element-consistent
  20008. */
  20009. goto exit;
  20010. exit_error:
  20011. ret = pctxt->err;
  20012. goto exit;
  20013. exit_failure:
  20014. ret = -1;
  20015. exit:
  20016. /*
  20017. * Reset the constructor. This is needed for XSI acquisition, since
  20018. * those items will be processed over and over again for every XSI
  20019. * if not cleared here.
  20020. */
  20021. con->bucket = oldbucket;
  20022. con->pending->nbItems = 0;
  20023. if (con->substGroups != NULL) {
  20024. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  20025. con->substGroups = NULL;
  20026. }
  20027. if (con->redefs != NULL) {
  20028. xmlSchemaRedefListFree(con->redefs);
  20029. con->redefs = NULL;
  20030. }
  20031. return(ret);
  20032. }
  20033. /**
  20034. * xmlSchemaParse:
  20035. * @ctxt: a schema validation context
  20036. *
  20037. * parse a schema definition resource and build an internal
  20038. * XML Schema structure which can be used to validate instances.
  20039. *
  20040. * Returns the internal XML Schema structure built from the resource or
  20041. * NULL in case of error
  20042. */
  20043. xmlSchemaPtr
  20044. xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
  20045. {
  20046. xmlSchemaPtr mainSchema = NULL;
  20047. xmlSchemaBucketPtr bucket = NULL;
  20048. int res;
  20049. /*
  20050. * This one is used if the schema to be parsed was specified via
  20051. * the API; i.e. not automatically by the validated instance document.
  20052. */
  20053. if (xmlSchemaInitTypes() < 0)
  20054. return (NULL);
  20055. if (ctxt == NULL)
  20056. return (NULL);
  20057. /* TODO: Init the context. Is this all we need?*/
  20058. ctxt->nberrors = 0;
  20059. ctxt->err = 0;
  20060. ctxt->counter = 0;
  20061. /* Create the *main* schema. */
  20062. mainSchema = xmlSchemaNewSchema(ctxt);
  20063. if (mainSchema == NULL)
  20064. goto exit_failure;
  20065. /*
  20066. * Create the schema constructor.
  20067. */
  20068. if (ctxt->constructor == NULL) {
  20069. ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
  20070. if (ctxt->constructor == NULL)
  20071. goto exit_failure;
  20072. /* Take ownership of the constructor to be able to free it. */
  20073. ctxt->ownsConstructor = 1;
  20074. }
  20075. ctxt->constructor->mainSchema = mainSchema;
  20076. /*
  20077. * Locate and add the schema document.
  20078. */
  20079. res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
  20080. ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
  20081. NULL, NULL, &bucket);
  20082. if (res == -1)
  20083. goto exit_failure;
  20084. if (res != 0)
  20085. goto exit;
  20086. if (bucket == NULL) {
  20087. /* TODO: Error code, actually we failed to *locate* the schema. */
  20088. if (ctxt->URL)
  20089. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20090. NULL, NULL,
  20091. "Failed to locate the main schema resource at '%s'",
  20092. ctxt->URL, NULL);
  20093. else
  20094. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20095. NULL, NULL,
  20096. "Failed to locate the main schema resource",
  20097. NULL, NULL);
  20098. goto exit;
  20099. }
  20100. /* Then do the parsing for good. */
  20101. if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
  20102. goto exit_failure;
  20103. if (ctxt->nberrors != 0)
  20104. goto exit;
  20105. mainSchema->doc = bucket->doc;
  20106. mainSchema->preserve = ctxt->preserve;
  20107. ctxt->schema = mainSchema;
  20108. if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
  20109. goto exit_failure;
  20110. /*
  20111. * TODO: This is not nice, since we cannot distinguish from the
  20112. * result if there was an internal error or not.
  20113. */
  20114. exit:
  20115. if (ctxt->nberrors != 0) {
  20116. if (mainSchema) {
  20117. xmlSchemaFree(mainSchema);
  20118. mainSchema = NULL;
  20119. }
  20120. if (ctxt->constructor) {
  20121. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20122. ctxt->constructor = NULL;
  20123. ctxt->ownsConstructor = 0;
  20124. }
  20125. }
  20126. ctxt->schema = NULL;
  20127. return(mainSchema);
  20128. exit_failure:
  20129. /*
  20130. * Quite verbose, but should catch internal errors, which were
  20131. * not communicated.
  20132. */
  20133. if (mainSchema) {
  20134. xmlSchemaFree(mainSchema);
  20135. mainSchema = NULL;
  20136. }
  20137. if (ctxt->constructor) {
  20138. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20139. ctxt->constructor = NULL;
  20140. ctxt->ownsConstructor = 0;
  20141. }
  20142. PERROR_INT2("xmlSchemaParse",
  20143. "An internal error occurred");
  20144. ctxt->schema = NULL;
  20145. return(NULL);
  20146. }
  20147. /**
  20148. * xmlSchemaSetParserErrors:
  20149. * @ctxt: a schema validation context
  20150. * @err: the error callback
  20151. * @warn: the warning callback
  20152. * @ctx: contextual data for the callbacks
  20153. *
  20154. * Set the callback functions used to handle errors for a validation context
  20155. */
  20156. void
  20157. xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20158. xmlSchemaValidityErrorFunc err,
  20159. xmlSchemaValidityWarningFunc warn, void *ctx)
  20160. {
  20161. if (ctxt == NULL)
  20162. return;
  20163. ctxt->error = err;
  20164. ctxt->warning = warn;
  20165. ctxt->errCtxt = ctx;
  20166. if (ctxt->vctxt != NULL)
  20167. xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
  20168. }
  20169. /**
  20170. * xmlSchemaSetParserStructuredErrors:
  20171. * @ctxt: a schema parser context
  20172. * @serror: the structured error function
  20173. * @ctx: the functions context
  20174. *
  20175. * Set the structured error callback
  20176. */
  20177. void
  20178. xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
  20179. xmlStructuredErrorFunc serror,
  20180. void *ctx)
  20181. {
  20182. if (ctxt == NULL)
  20183. return;
  20184. ctxt->serror = serror;
  20185. ctxt->errCtxt = ctx;
  20186. if (ctxt->vctxt != NULL)
  20187. xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
  20188. }
  20189. /**
  20190. * xmlSchemaGetParserErrors:
  20191. * @ctxt: a XMl-Schema parser context
  20192. * @err: the error callback result
  20193. * @warn: the warning callback result
  20194. * @ctx: contextual data for the callbacks result
  20195. *
  20196. * Get the callback information used to handle errors for a parser context
  20197. *
  20198. * Returns -1 in case of failure, 0 otherwise
  20199. */
  20200. int
  20201. xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20202. xmlSchemaValidityErrorFunc * err,
  20203. xmlSchemaValidityWarningFunc * warn, void **ctx)
  20204. {
  20205. if (ctxt == NULL)
  20206. return(-1);
  20207. if (err != NULL)
  20208. *err = ctxt->error;
  20209. if (warn != NULL)
  20210. *warn = ctxt->warning;
  20211. if (ctx != NULL)
  20212. *ctx = ctxt->errCtxt;
  20213. return(0);
  20214. }
  20215. /**
  20216. * xmlSchemaFacetTypeToString:
  20217. * @type: the facet type
  20218. *
  20219. * Convert the xmlSchemaTypeType to a char string.
  20220. *
  20221. * Returns the char string representation of the facet type if the
  20222. * type is a facet and an "Internal Error" string otherwise.
  20223. */
  20224. static const xmlChar *
  20225. xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
  20226. {
  20227. switch (type) {
  20228. case XML_SCHEMA_FACET_PATTERN:
  20229. return (BAD_CAST "pattern");
  20230. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  20231. return (BAD_CAST "maxExclusive");
  20232. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  20233. return (BAD_CAST "maxInclusive");
  20234. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  20235. return (BAD_CAST "minExclusive");
  20236. case XML_SCHEMA_FACET_MININCLUSIVE:
  20237. return (BAD_CAST "minInclusive");
  20238. case XML_SCHEMA_FACET_WHITESPACE:
  20239. return (BAD_CAST "whiteSpace");
  20240. case XML_SCHEMA_FACET_ENUMERATION:
  20241. return (BAD_CAST "enumeration");
  20242. case XML_SCHEMA_FACET_LENGTH:
  20243. return (BAD_CAST "length");
  20244. case XML_SCHEMA_FACET_MAXLENGTH:
  20245. return (BAD_CAST "maxLength");
  20246. case XML_SCHEMA_FACET_MINLENGTH:
  20247. return (BAD_CAST "minLength");
  20248. case XML_SCHEMA_FACET_TOTALDIGITS:
  20249. return (BAD_CAST "totalDigits");
  20250. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  20251. return (BAD_CAST "fractionDigits");
  20252. default:
  20253. break;
  20254. }
  20255. return (BAD_CAST "Internal Error");
  20256. }
  20257. static xmlSchemaWhitespaceValueType
  20258. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
  20259. {
  20260. /*
  20261. * The normalization type can be changed only for types which are derived
  20262. * from xsd:string.
  20263. */
  20264. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  20265. /*
  20266. * Note that we assume a whitespace of preserve for anySimpleType.
  20267. */
  20268. if ((type->builtInType == XML_SCHEMAS_STRING) ||
  20269. (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  20270. return(XML_SCHEMA_WHITESPACE_PRESERVE);
  20271. else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
  20272. return(XML_SCHEMA_WHITESPACE_REPLACE);
  20273. else {
  20274. /*
  20275. * For all `atomic` datatypes other than string (and types `derived`
  20276. * by `restriction` from it) the value of whiteSpace is fixed to
  20277. * collapse
  20278. * Note that this includes built-in list datatypes.
  20279. */
  20280. return(XML_SCHEMA_WHITESPACE_COLLAPSE);
  20281. }
  20282. } else if (WXS_IS_LIST(type)) {
  20283. /*
  20284. * For list types the facet "whiteSpace" is fixed to "collapse".
  20285. */
  20286. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20287. } else if (WXS_IS_UNION(type)) {
  20288. return (XML_SCHEMA_WHITESPACE_UNKNOWN);
  20289. } else if (WXS_IS_ATOMIC(type)) {
  20290. if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
  20291. return (XML_SCHEMA_WHITESPACE_PRESERVE);
  20292. else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
  20293. return (XML_SCHEMA_WHITESPACE_REPLACE);
  20294. else
  20295. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20296. }
  20297. return (-1);
  20298. }
  20299. /************************************************************************
  20300. * *
  20301. * Simple type validation *
  20302. * *
  20303. ************************************************************************/
  20304. /************************************************************************
  20305. * *
  20306. * DOM Validation code *
  20307. * *
  20308. ************************************************************************/
  20309. /**
  20310. * xmlSchemaAssembleByLocation:
  20311. * @pctxt: a schema parser context
  20312. * @vctxt: a schema validation context
  20313. * @schema: the existing schema
  20314. * @node: the node that fired the assembling
  20315. * @nsName: the namespace name of the new schema
  20316. * @location: the location of the schema
  20317. *
  20318. * Expands an existing schema by an additional schema.
  20319. *
  20320. * Returns 0 if the new schema is correct, a positive error code
  20321. * number otherwise and -1 in case of an internal or API error.
  20322. */
  20323. static int
  20324. xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
  20325. xmlSchemaPtr schema,
  20326. xmlNodePtr node,
  20327. const xmlChar *nsName,
  20328. const xmlChar *location)
  20329. {
  20330. int ret = 0;
  20331. xmlSchemaParserCtxtPtr pctxt;
  20332. xmlSchemaBucketPtr bucket = NULL;
  20333. if ((vctxt == NULL) || (schema == NULL))
  20334. return (-1);
  20335. if (vctxt->pctxt == NULL) {
  20336. VERROR_INT("xmlSchemaAssembleByLocation",
  20337. "no parser context available");
  20338. return(-1);
  20339. }
  20340. pctxt = vctxt->pctxt;
  20341. if (pctxt->constructor == NULL) {
  20342. PERROR_INT("xmlSchemaAssembleByLocation",
  20343. "no constructor");
  20344. return(-1);
  20345. }
  20346. /*
  20347. * Acquire the schema document.
  20348. */
  20349. location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  20350. location, node);
  20351. /*
  20352. * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
  20353. * the process will automatically change this to
  20354. * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
  20355. */
  20356. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  20357. location, NULL, NULL, 0, node, NULL, nsName,
  20358. &bucket);
  20359. if (ret != 0)
  20360. return(ret);
  20361. if (bucket == NULL) {
  20362. /*
  20363. * Generate a warning that the document could not be located.
  20364. */
  20365. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20366. node, NULL,
  20367. "The document at location '%s' could not be acquired",
  20368. location, NULL, NULL);
  20369. return(ret);
  20370. }
  20371. /*
  20372. * The first located schema will be handled as if all other
  20373. * schemas imported by XSI were imported by this first schema.
  20374. */
  20375. if ((bucket != NULL) &&
  20376. (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
  20377. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  20378. /*
  20379. * TODO: Is this handled like an import? I.e. is it not an error
  20380. * if the schema cannot be located?
  20381. */
  20382. if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
  20383. return(0);
  20384. /*
  20385. * We will reuse the parser context for every schema imported
  20386. * directly via XSI. So reset the context.
  20387. */
  20388. pctxt->nberrors = 0;
  20389. pctxt->err = 0;
  20390. pctxt->doc = bucket->doc;
  20391. ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
  20392. if (ret == -1) {
  20393. pctxt->doc = NULL;
  20394. goto exit_failure;
  20395. }
  20396. /* Paranoid error channelling. */
  20397. if ((ret == 0) && (pctxt->nberrors != 0))
  20398. ret = pctxt->err;
  20399. if (pctxt->nberrors == 0) {
  20400. /*
  20401. * Only bother to fixup pending components, if there was
  20402. * no error yet.
  20403. * For every XSI acquired schema (and its sub-schemata) we will
  20404. * fixup the components.
  20405. */
  20406. xmlSchemaFixupComponents(pctxt, bucket);
  20407. ret = pctxt->err;
  20408. /*
  20409. * Not nice, but we need somehow to channel the schema parser
  20410. * error to the validation context.
  20411. */
  20412. if ((ret != 0) && (vctxt->err == 0))
  20413. vctxt->err = ret;
  20414. vctxt->nberrors += pctxt->nberrors;
  20415. } else {
  20416. /* Add to validation error sum. */
  20417. vctxt->nberrors += pctxt->nberrors;
  20418. }
  20419. pctxt->doc = NULL;
  20420. return(ret);
  20421. exit_failure:
  20422. pctxt->doc = NULL;
  20423. return (-1);
  20424. }
  20425. static xmlSchemaAttrInfoPtr
  20426. xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
  20427. int metaType)
  20428. {
  20429. if (vctxt->nbAttrInfos == 0)
  20430. return (NULL);
  20431. {
  20432. int i;
  20433. xmlSchemaAttrInfoPtr iattr;
  20434. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  20435. iattr = vctxt->attrInfos[i];
  20436. if (iattr->metaType == metaType)
  20437. return (iattr);
  20438. }
  20439. }
  20440. return (NULL);
  20441. }
  20442. /**
  20443. * xmlSchemaAssembleByXSI:
  20444. * @vctxt: a schema validation context
  20445. *
  20446. * Expands an existing schema by an additional schema using
  20447. * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
  20448. * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
  20449. * must be set to 1.
  20450. *
  20451. * Returns 0 if the new schema is correct, a positive error code
  20452. * number otherwise and -1 in case of an internal or API error.
  20453. */
  20454. static int
  20455. xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
  20456. {
  20457. const xmlChar *cur, *end;
  20458. const xmlChar *nsname = NULL, *location;
  20459. int ret = 0;
  20460. xmlSchemaAttrInfoPtr iattr;
  20461. /*
  20462. * Parse the value; we will assume an even number of values
  20463. * to be given (this is how Xerces and XSV work).
  20464. *
  20465. * URGENT TODO: !! This needs to work for both
  20466. * @noNamespaceSchemaLocation AND @schemaLocation on the same
  20467. * element !!
  20468. */
  20469. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20470. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
  20471. if (iattr == NULL)
  20472. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20473. XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
  20474. if (iattr == NULL)
  20475. return (0);
  20476. cur = iattr->value;
  20477. do {
  20478. /*
  20479. * TODO: Move the string parsing mechanism away from here.
  20480. */
  20481. if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
  20482. /*
  20483. * Get the namespace name.
  20484. */
  20485. while (IS_BLANK_CH(*cur))
  20486. cur++;
  20487. end = cur;
  20488. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20489. end++;
  20490. if (end == cur)
  20491. break;
  20492. /* TODO: Don't use the schema's dict. */
  20493. nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20494. cur = end;
  20495. }
  20496. /*
  20497. * Get the URI.
  20498. */
  20499. while (IS_BLANK_CH(*cur))
  20500. cur++;
  20501. end = cur;
  20502. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20503. end++;
  20504. if (end == cur) {
  20505. if (iattr->metaType ==
  20506. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
  20507. {
  20508. /*
  20509. * If using @schemaLocation then tuples are expected.
  20510. * I.e. the namespace name *and* the document's URI.
  20511. */
  20512. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20513. iattr->node, NULL,
  20514. "The value must consist of tuples: the target namespace "
  20515. "name and the document's URI", NULL, NULL, NULL);
  20516. }
  20517. break;
  20518. }
  20519. /* TODO: Don't use the schema's dict. */
  20520. location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20521. cur = end;
  20522. ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
  20523. iattr->node, nsname, location);
  20524. if (ret == -1) {
  20525. VERROR_INT("xmlSchemaAssembleByXSI",
  20526. "assembling schemata");
  20527. return (-1);
  20528. }
  20529. } while (*cur != 0);
  20530. return (ret);
  20531. }
  20532. static const xmlChar *
  20533. xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
  20534. const xmlChar *prefix)
  20535. {
  20536. if (vctxt->sax != NULL) {
  20537. int i, j;
  20538. xmlSchemaNodeInfoPtr inode;
  20539. for (i = vctxt->depth; i >= 0; i--) {
  20540. if (vctxt->elemInfos[i]->nbNsBindings != 0) {
  20541. inode = vctxt->elemInfos[i];
  20542. for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
  20543. if (((prefix == NULL) &&
  20544. (inode->nsBindings[j] == NULL)) ||
  20545. ((prefix != NULL) && xmlStrEqual(prefix,
  20546. inode->nsBindings[j]))) {
  20547. /*
  20548. * Note that the namespace bindings are already
  20549. * in a string dict.
  20550. */
  20551. return (inode->nsBindings[j+1]);
  20552. }
  20553. }
  20554. }
  20555. }
  20556. return (NULL);
  20557. #ifdef LIBXML_READER_ENABLED
  20558. } else if (vctxt->reader != NULL) {
  20559. xmlChar *nsName;
  20560. nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
  20561. if (nsName != NULL) {
  20562. const xmlChar *ret;
  20563. ret = xmlDictLookup(vctxt->dict, nsName, -1);
  20564. xmlFree(nsName);
  20565. return (ret);
  20566. } else
  20567. return (NULL);
  20568. #endif
  20569. } else {
  20570. xmlNsPtr ns;
  20571. if ((vctxt->inode->node == NULL) ||
  20572. (vctxt->inode->node->doc == NULL)) {
  20573. VERROR_INT("xmlSchemaLookupNamespace",
  20574. "no node or node's doc available");
  20575. return (NULL);
  20576. }
  20577. ns = xmlSearchNs(vctxt->inode->node->doc,
  20578. vctxt->inode->node, prefix);
  20579. if (ns != NULL)
  20580. return (ns->href);
  20581. return (NULL);
  20582. }
  20583. }
  20584. /*
  20585. * This one works on the schema of the validation context.
  20586. */
  20587. static int
  20588. xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
  20589. xmlSchemaPtr schema,
  20590. xmlNodePtr node,
  20591. const xmlChar *value,
  20592. xmlSchemaValPtr *val,
  20593. int valNeeded)
  20594. {
  20595. int ret;
  20596. if (vctxt && (vctxt->schema == NULL)) {
  20597. VERROR_INT("xmlSchemaValidateNotation",
  20598. "a schema is needed on the validation context");
  20599. return (-1);
  20600. }
  20601. ret = xmlValidateQName(value, 1);
  20602. if (ret != 0)
  20603. return (ret);
  20604. {
  20605. xmlChar *localName = NULL;
  20606. xmlChar *prefix = NULL;
  20607. localName = xmlSplitQName2(value, &prefix);
  20608. if (prefix != NULL) {
  20609. const xmlChar *nsName = NULL;
  20610. if (vctxt != NULL)
  20611. nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
  20612. else if (node != NULL) {
  20613. xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
  20614. if (ns != NULL)
  20615. nsName = ns->href;
  20616. } else {
  20617. xmlFree(prefix);
  20618. xmlFree(localName);
  20619. return (1);
  20620. }
  20621. if (nsName == NULL) {
  20622. xmlFree(prefix);
  20623. xmlFree(localName);
  20624. return (1);
  20625. }
  20626. if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
  20627. if ((valNeeded) && (val != NULL)) {
  20628. (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
  20629. xmlStrdup(nsName));
  20630. if (*val == NULL)
  20631. ret = -1;
  20632. }
  20633. } else
  20634. ret = 1;
  20635. xmlFree(prefix);
  20636. xmlFree(localName);
  20637. } else {
  20638. if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
  20639. if (valNeeded && (val != NULL)) {
  20640. (*val) = xmlSchemaNewNOTATIONValue(
  20641. BAD_CAST xmlStrdup(value), NULL);
  20642. if (*val == NULL)
  20643. ret = -1;
  20644. }
  20645. } else
  20646. return (1);
  20647. }
  20648. }
  20649. return (ret);
  20650. }
  20651. static int
  20652. xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
  20653. const xmlChar* lname,
  20654. const xmlChar* nsname)
  20655. {
  20656. int i;
  20657. lname = xmlDictLookup(vctxt->dict, lname, -1);
  20658. if (lname == NULL)
  20659. return(-1);
  20660. if (nsname != NULL) {
  20661. nsname = xmlDictLookup(vctxt->dict, nsname, -1);
  20662. if (nsname == NULL)
  20663. return(-1);
  20664. }
  20665. for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
  20666. if ((vctxt->nodeQNames->items [i] == lname) &&
  20667. (vctxt->nodeQNames->items[i +1] == nsname))
  20668. /* Already there */
  20669. return(i);
  20670. }
  20671. /* Add new entry. */
  20672. i = vctxt->nodeQNames->nbItems;
  20673. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
  20674. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
  20675. return(i);
  20676. }
  20677. /************************************************************************
  20678. * *
  20679. * Validation of identity-constraints (IDC) *
  20680. * *
  20681. ************************************************************************/
  20682. /**
  20683. * xmlSchemaAugmentIDC:
  20684. * @idcDef: the IDC definition
  20685. *
  20686. * Creates an augmented IDC definition item.
  20687. *
  20688. * Returns the item, or NULL on internal errors.
  20689. */
  20690. static void
  20691. xmlSchemaAugmentIDC(void *payload, void *data,
  20692. const xmlChar *name ATTRIBUTE_UNUSED)
  20693. {
  20694. xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
  20695. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20696. xmlSchemaIDCAugPtr aidc;
  20697. aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
  20698. if (aidc == NULL) {
  20699. xmlSchemaVErrMemory(vctxt,
  20700. "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
  20701. NULL);
  20702. return;
  20703. }
  20704. aidc->keyrefDepth = -1;
  20705. aidc->def = idcDef;
  20706. aidc->next = NULL;
  20707. if (vctxt->aidcs == NULL)
  20708. vctxt->aidcs = aidc;
  20709. else {
  20710. aidc->next = vctxt->aidcs;
  20711. vctxt->aidcs = aidc;
  20712. }
  20713. /*
  20714. * Save if we have keyrefs at all.
  20715. */
  20716. if ((vctxt->hasKeyrefs == 0) &&
  20717. (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
  20718. vctxt->hasKeyrefs = 1;
  20719. }
  20720. /**
  20721. * xmlSchemaAugmentImportedIDC:
  20722. * @imported: the imported schema
  20723. *
  20724. * Creates an augmented IDC definition for the imported schema.
  20725. */
  20726. static void
  20727. xmlSchemaAugmentImportedIDC(void *payload, void *data,
  20728. const xmlChar *name ATTRIBUTE_UNUSED) {
  20729. xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
  20730. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20731. if (imported->schema->idcDef != NULL) {
  20732. xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
  20733. }
  20734. }
  20735. /**
  20736. * xmlSchemaIDCNewBinding:
  20737. * @idcDef: the IDC definition of this binding
  20738. *
  20739. * Creates a new IDC binding.
  20740. *
  20741. * Returns the new IDC binding, NULL on internal errors.
  20742. */
  20743. static xmlSchemaPSVIIDCBindingPtr
  20744. xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
  20745. {
  20746. xmlSchemaPSVIIDCBindingPtr ret;
  20747. ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
  20748. sizeof(xmlSchemaPSVIIDCBinding));
  20749. if (ret == NULL) {
  20750. xmlSchemaVErrMemory(NULL,
  20751. "allocating a PSVI IDC binding item", NULL);
  20752. return (NULL);
  20753. }
  20754. memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
  20755. ret->definition = idcDef;
  20756. return (ret);
  20757. }
  20758. /**
  20759. * xmlSchemaIDCStoreNodeTableItem:
  20760. * @vctxt: the WXS validation context
  20761. * @item: the IDC node table item
  20762. *
  20763. * The validation context is used to store IDC node table items.
  20764. * They are stored to avoid copying them if IDC node-tables are merged
  20765. * with corresponding parent IDC node-tables (bubbling).
  20766. *
  20767. * Returns 0 if succeeded, -1 on internal errors.
  20768. */
  20769. static int
  20770. xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
  20771. xmlSchemaPSVIIDCNodePtr item)
  20772. {
  20773. /*
  20774. * Add to global list.
  20775. */
  20776. if (vctxt->idcNodes == NULL) {
  20777. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20778. xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20779. if (vctxt->idcNodes == NULL) {
  20780. xmlSchemaVErrMemory(vctxt,
  20781. "allocating the IDC node table item list", NULL);
  20782. return (-1);
  20783. }
  20784. vctxt->sizeIdcNodes = 20;
  20785. } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
  20786. vctxt->sizeIdcNodes *= 2;
  20787. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20788. xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
  20789. sizeof(xmlSchemaPSVIIDCNodePtr));
  20790. if (vctxt->idcNodes == NULL) {
  20791. xmlSchemaVErrMemory(vctxt,
  20792. "re-allocating the IDC node table item list", NULL);
  20793. return (-1);
  20794. }
  20795. }
  20796. vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
  20797. return (0);
  20798. }
  20799. /**
  20800. * xmlSchemaIDCStoreKey:
  20801. * @vctxt: the WXS validation context
  20802. * @item: the IDC key
  20803. *
  20804. * The validation context is used to store an IDC key.
  20805. *
  20806. * Returns 0 if succeeded, -1 on internal errors.
  20807. */
  20808. static int
  20809. xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
  20810. xmlSchemaPSVIIDCKeyPtr key)
  20811. {
  20812. /*
  20813. * Add to global list.
  20814. */
  20815. if (vctxt->idcKeys == NULL) {
  20816. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20817. xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
  20818. if (vctxt->idcKeys == NULL) {
  20819. xmlSchemaVErrMemory(vctxt,
  20820. "allocating the IDC key storage list", NULL);
  20821. return (-1);
  20822. }
  20823. vctxt->sizeIdcKeys = 40;
  20824. } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
  20825. vctxt->sizeIdcKeys *= 2;
  20826. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20827. xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
  20828. sizeof(xmlSchemaPSVIIDCKeyPtr));
  20829. if (vctxt->idcKeys == NULL) {
  20830. xmlSchemaVErrMemory(vctxt,
  20831. "re-allocating the IDC key storage list", NULL);
  20832. return (-1);
  20833. }
  20834. }
  20835. vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
  20836. return (0);
  20837. }
  20838. /**
  20839. * xmlSchemaIDCAppendNodeTableItem:
  20840. * @bind: the IDC binding
  20841. * @ntItem: the node-table item
  20842. *
  20843. * Appends the IDC node-table item to the binding.
  20844. *
  20845. * Returns 0 on success and -1 on internal errors.
  20846. */
  20847. static int
  20848. xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
  20849. xmlSchemaPSVIIDCNodePtr ntItem)
  20850. {
  20851. if (bind->nodeTable == NULL) {
  20852. bind->sizeNodes = 10;
  20853. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20854. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20855. if (bind->nodeTable == NULL) {
  20856. xmlSchemaVErrMemory(NULL,
  20857. "allocating an array of IDC node-table items", NULL);
  20858. return(-1);
  20859. }
  20860. } else if (bind->sizeNodes <= bind->nbNodes) {
  20861. bind->sizeNodes *= 2;
  20862. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20863. xmlRealloc(bind->nodeTable, bind->sizeNodes *
  20864. sizeof(xmlSchemaPSVIIDCNodePtr));
  20865. if (bind->nodeTable == NULL) {
  20866. xmlSchemaVErrMemory(NULL,
  20867. "re-allocating an array of IDC node-table items", NULL);
  20868. return(-1);
  20869. }
  20870. }
  20871. bind->nodeTable[bind->nbNodes++] = ntItem;
  20872. return(0);
  20873. }
  20874. /**
  20875. * xmlSchemaIDCAcquireBinding:
  20876. * @vctxt: the WXS validation context
  20877. * @matcher: the IDC matcher
  20878. *
  20879. * Looks up an PSVI IDC binding, for the IDC definition and
  20880. * of the given matcher. If none found, a new one is created
  20881. * and added to the IDC table.
  20882. *
  20883. * Returns an IDC binding or NULL on internal errors.
  20884. */
  20885. static xmlSchemaPSVIIDCBindingPtr
  20886. xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
  20887. xmlSchemaIDCMatcherPtr matcher)
  20888. {
  20889. xmlSchemaNodeInfoPtr ielem;
  20890. ielem = vctxt->elemInfos[matcher->depth];
  20891. if (ielem->idcTable == NULL) {
  20892. ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20893. if (ielem->idcTable == NULL)
  20894. return (NULL);
  20895. return(ielem->idcTable);
  20896. } else {
  20897. xmlSchemaPSVIIDCBindingPtr bind = NULL;
  20898. bind = ielem->idcTable;
  20899. do {
  20900. if (bind->definition == matcher->aidc->def)
  20901. return(bind);
  20902. if (bind->next == NULL) {
  20903. bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20904. if (bind->next == NULL)
  20905. return (NULL);
  20906. return(bind->next);
  20907. }
  20908. bind = bind->next;
  20909. } while (bind != NULL);
  20910. }
  20911. return (NULL);
  20912. }
  20913. static xmlSchemaItemListPtr
  20914. xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  20915. xmlSchemaIDCMatcherPtr matcher)
  20916. {
  20917. if (matcher->targets == NULL)
  20918. matcher->targets = xmlSchemaItemListCreate();
  20919. return(matcher->targets);
  20920. }
  20921. /**
  20922. * xmlSchemaIDCFreeKey:
  20923. * @key: the IDC key
  20924. *
  20925. * Frees an IDC key together with its compiled value.
  20926. */
  20927. static void
  20928. xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
  20929. {
  20930. if (key->val != NULL)
  20931. xmlSchemaFreeValue(key->val);
  20932. xmlFree(key);
  20933. }
  20934. /**
  20935. * xmlSchemaIDCFreeBinding:
  20936. *
  20937. * Frees an IDC binding. Note that the node table-items
  20938. * are not freed.
  20939. */
  20940. static void
  20941. xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
  20942. {
  20943. if (bind->nodeTable != NULL)
  20944. xmlFree(bind->nodeTable);
  20945. if (bind->dupls != NULL)
  20946. xmlSchemaItemListFree(bind->dupls);
  20947. xmlFree(bind);
  20948. }
  20949. /**
  20950. * xmlSchemaIDCFreeIDCTable:
  20951. * @bind: the first IDC binding in the list
  20952. *
  20953. * Frees an IDC table, i.e. all the IDC bindings in the list.
  20954. */
  20955. static void
  20956. xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
  20957. {
  20958. xmlSchemaPSVIIDCBindingPtr prev;
  20959. while (bind != NULL) {
  20960. prev = bind;
  20961. bind = bind->next;
  20962. xmlSchemaIDCFreeBinding(prev);
  20963. }
  20964. }
  20965. static void
  20966. xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
  20967. {
  20968. xmlIDCHashEntryPtr e = payload, n;
  20969. while (e) {
  20970. n = e->next;
  20971. xmlFree(e);
  20972. e = n;
  20973. }
  20974. }
  20975. /**
  20976. * xmlSchemaIDCFreeMatcherList:
  20977. * @matcher: the first IDC matcher in the list
  20978. *
  20979. * Frees a list of IDC matchers.
  20980. */
  20981. static void
  20982. xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
  20983. {
  20984. xmlSchemaIDCMatcherPtr next;
  20985. while (matcher != NULL) {
  20986. next = matcher->next;
  20987. if (matcher->keySeqs != NULL) {
  20988. int i;
  20989. for (i = 0; i < matcher->sizeKeySeqs; i++)
  20990. if (matcher->keySeqs[i] != NULL)
  20991. xmlFree(matcher->keySeqs[i]);
  20992. xmlFree(matcher->keySeqs);
  20993. }
  20994. if (matcher->targets != NULL) {
  20995. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  20996. int i;
  20997. xmlSchemaPSVIIDCNodePtr idcNode;
  20998. /*
  20999. * Node-table items for keyrefs are not stored globally
  21000. * to the validation context, since they are not bubbled.
  21001. * We need to free them here.
  21002. */
  21003. for (i = 0; i < matcher->targets->nbItems; i++) {
  21004. idcNode =
  21005. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21006. xmlFree(idcNode->keys);
  21007. xmlFree(idcNode);
  21008. }
  21009. }
  21010. xmlSchemaItemListFree(matcher->targets);
  21011. }
  21012. if (matcher->htab != NULL)
  21013. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21014. xmlFree(matcher);
  21015. matcher = next;
  21016. }
  21017. }
  21018. /**
  21019. * xmlSchemaIDCReleaseMatcherList:
  21020. * @vctxt: the WXS validation context
  21021. * @matcher: the first IDC matcher in the list
  21022. *
  21023. * Caches a list of IDC matchers for reuse.
  21024. */
  21025. static void
  21026. xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
  21027. xmlSchemaIDCMatcherPtr matcher)
  21028. {
  21029. xmlSchemaIDCMatcherPtr next;
  21030. while (matcher != NULL) {
  21031. next = matcher->next;
  21032. if (matcher->keySeqs != NULL) {
  21033. int i;
  21034. /*
  21035. * Don't free the array, but only the content.
  21036. */
  21037. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21038. if (matcher->keySeqs[i] != NULL) {
  21039. xmlFree(matcher->keySeqs[i]);
  21040. matcher->keySeqs[i] = NULL;
  21041. }
  21042. }
  21043. if (matcher->targets) {
  21044. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21045. int i;
  21046. xmlSchemaPSVIIDCNodePtr idcNode;
  21047. /*
  21048. * Node-table items for keyrefs are not stored globally
  21049. * to the validation context, since they are not bubbled.
  21050. * We need to free them here.
  21051. */
  21052. for (i = 0; i < matcher->targets->nbItems; i++) {
  21053. idcNode =
  21054. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21055. xmlFree(idcNode->keys);
  21056. xmlFree(idcNode);
  21057. }
  21058. }
  21059. xmlSchemaItemListFree(matcher->targets);
  21060. matcher->targets = NULL;
  21061. }
  21062. if (matcher->htab != NULL) {
  21063. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21064. matcher->htab = NULL;
  21065. }
  21066. matcher->next = NULL;
  21067. /*
  21068. * Cache the matcher.
  21069. */
  21070. if (vctxt->idcMatcherCache != NULL)
  21071. matcher->nextCached = vctxt->idcMatcherCache;
  21072. vctxt->idcMatcherCache = matcher;
  21073. matcher = next;
  21074. }
  21075. }
  21076. /**
  21077. * xmlSchemaIDCAddStateObject:
  21078. * @vctxt: the WXS validation context
  21079. * @matcher: the IDC matcher
  21080. * @sel: the XPath information
  21081. * @parent: the parent "selector" state object if any
  21082. * @type: "selector" or "field"
  21083. *
  21084. * Creates/reuses and activates state objects for the given
  21085. * XPath information; if the XPath expression consists of unions,
  21086. * multiple state objects are created for every unioned expression.
  21087. *
  21088. * Returns 0 on success and -1 on internal errors.
  21089. */
  21090. static int
  21091. xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
  21092. xmlSchemaIDCMatcherPtr matcher,
  21093. xmlSchemaIDCSelectPtr sel,
  21094. int type)
  21095. {
  21096. xmlSchemaIDCStateObjPtr sto;
  21097. /*
  21098. * Reuse the state objects from the pool.
  21099. */
  21100. if (vctxt->xpathStatePool != NULL) {
  21101. sto = vctxt->xpathStatePool;
  21102. vctxt->xpathStatePool = sto->next;
  21103. sto->next = NULL;
  21104. } else {
  21105. /*
  21106. * Create a new state object.
  21107. */
  21108. sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
  21109. if (sto == NULL) {
  21110. xmlSchemaVErrMemory(NULL,
  21111. "allocating an IDC state object", NULL);
  21112. return (-1);
  21113. }
  21114. memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
  21115. }
  21116. /*
  21117. * Add to global list.
  21118. */
  21119. if (vctxt->xpathStates != NULL)
  21120. sto->next = vctxt->xpathStates;
  21121. vctxt->xpathStates = sto;
  21122. /*
  21123. * Free the old xpath validation context.
  21124. */
  21125. if (sto->xpathCtxt != NULL)
  21126. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  21127. /*
  21128. * Create a new XPath (pattern) validation context.
  21129. */
  21130. sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
  21131. (xmlPatternPtr) sel->xpathComp);
  21132. if (sto->xpathCtxt == NULL) {
  21133. VERROR_INT("xmlSchemaIDCAddStateObject",
  21134. "failed to create an XPath validation context");
  21135. return (-1);
  21136. }
  21137. sto->type = type;
  21138. sto->depth = vctxt->depth;
  21139. sto->matcher = matcher;
  21140. sto->sel = sel;
  21141. sto->nbHistory = 0;
  21142. return (0);
  21143. }
  21144. /**
  21145. * xmlSchemaXPathEvaluate:
  21146. * @vctxt: the WXS validation context
  21147. * @nodeType: the nodeType of the current node
  21148. *
  21149. * Evaluates all active XPath state objects.
  21150. *
  21151. * Returns the number of IC "field" state objects which resolved to
  21152. * this node, 0 if none resolved and -1 on internal errors.
  21153. */
  21154. static int
  21155. xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
  21156. xmlElementType nodeType)
  21157. {
  21158. xmlSchemaIDCStateObjPtr sto, head = NULL, first;
  21159. int res, resolved = 0, depth = vctxt->depth;
  21160. if (vctxt->xpathStates == NULL)
  21161. return (0);
  21162. if (nodeType == XML_ATTRIBUTE_NODE)
  21163. depth++;
  21164. /*
  21165. * Process all active XPath state objects.
  21166. */
  21167. first = vctxt->xpathStates;
  21168. sto = first;
  21169. while (sto != head) {
  21170. if (nodeType == XML_ELEMENT_NODE)
  21171. res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
  21172. vctxt->inode->localName, vctxt->inode->nsName);
  21173. else
  21174. res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
  21175. vctxt->inode->localName, vctxt->inode->nsName);
  21176. if (res == -1) {
  21177. VERROR_INT("xmlSchemaXPathEvaluate",
  21178. "calling xmlStreamPush()");
  21179. return (-1);
  21180. }
  21181. if (res == 0)
  21182. goto next_sto;
  21183. /*
  21184. * Full match.
  21185. */
  21186. /*
  21187. * Register a match in the state object history.
  21188. */
  21189. if (sto->history == NULL) {
  21190. sto->history = (int *) xmlMalloc(5 * sizeof(int));
  21191. if (sto->history == NULL) {
  21192. xmlSchemaVErrMemory(NULL,
  21193. "allocating the state object history", NULL);
  21194. return(-1);
  21195. }
  21196. sto->sizeHistory = 5;
  21197. } else if (sto->sizeHistory <= sto->nbHistory) {
  21198. sto->sizeHistory *= 2;
  21199. sto->history = (int *) xmlRealloc(sto->history,
  21200. sto->sizeHistory * sizeof(int));
  21201. if (sto->history == NULL) {
  21202. xmlSchemaVErrMemory(NULL,
  21203. "re-allocating the state object history", NULL);
  21204. return(-1);
  21205. }
  21206. }
  21207. sto->history[sto->nbHistory++] = depth;
  21208. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21209. xmlSchemaIDCSelectPtr sel;
  21210. /*
  21211. * Activate state objects for the IDC fields of
  21212. * the IDC selector.
  21213. */
  21214. sel = sto->matcher->aidc->def->fields;
  21215. while (sel != NULL) {
  21216. if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
  21217. sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
  21218. return (-1);
  21219. sel = sel->next;
  21220. }
  21221. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21222. /*
  21223. * An IDC key node was found by the IDC field.
  21224. */
  21225. /*
  21226. * Notify that the character value of this node is
  21227. * needed.
  21228. */
  21229. if (resolved == 0) {
  21230. if ((vctxt->inode->flags &
  21231. XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
  21232. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  21233. }
  21234. resolved++;
  21235. }
  21236. next_sto:
  21237. if (sto->next == NULL) {
  21238. /*
  21239. * Evaluate field state objects created on this node as well.
  21240. */
  21241. head = first;
  21242. sto = vctxt->xpathStates;
  21243. } else
  21244. sto = sto->next;
  21245. }
  21246. return (resolved);
  21247. }
  21248. static const xmlChar *
  21249. xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
  21250. xmlChar **buf,
  21251. xmlSchemaPSVIIDCKeyPtr *seq,
  21252. int count, int for_hash)
  21253. {
  21254. int i, res;
  21255. xmlChar *value = NULL;
  21256. *buf = xmlStrdup(BAD_CAST "[");
  21257. for (i = 0; i < count; i++) {
  21258. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21259. if (!for_hash)
  21260. res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
  21261. xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
  21262. &value);
  21263. else {
  21264. res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
  21265. }
  21266. if (res == 0)
  21267. *buf = xmlStrcat(*buf, BAD_CAST value);
  21268. else {
  21269. VERROR_INT("xmlSchemaFormatIDCKeySequence",
  21270. "failed to compute a canonical value");
  21271. *buf = xmlStrcat(*buf, BAD_CAST "???");
  21272. }
  21273. if (i < count -1)
  21274. *buf = xmlStrcat(*buf, BAD_CAST "', ");
  21275. else
  21276. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21277. if (value != NULL) {
  21278. xmlFree(value);
  21279. value = NULL;
  21280. }
  21281. }
  21282. *buf = xmlStrcat(*buf, BAD_CAST "]");
  21283. return (BAD_CAST *buf);
  21284. }
  21285. static const xmlChar *
  21286. xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21287. xmlChar **buf,
  21288. xmlSchemaPSVIIDCKeyPtr *seq,
  21289. int count)
  21290. {
  21291. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
  21292. }
  21293. static const xmlChar *
  21294. xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21295. xmlChar **buf,
  21296. xmlSchemaPSVIIDCKeyPtr *seq,
  21297. int count)
  21298. {
  21299. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
  21300. }
  21301. /**
  21302. * xmlSchemaXPathPop:
  21303. * @vctxt: the WXS validation context
  21304. *
  21305. * Pops all XPath states.
  21306. *
  21307. * Returns 0 on success and -1 on internal errors.
  21308. */
  21309. static int
  21310. xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
  21311. {
  21312. xmlSchemaIDCStateObjPtr sto;
  21313. int res;
  21314. if (vctxt->xpathStates == NULL)
  21315. return(0);
  21316. sto = vctxt->xpathStates;
  21317. do {
  21318. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21319. if (res == -1)
  21320. return (-1);
  21321. sto = sto->next;
  21322. } while (sto != NULL);
  21323. return(0);
  21324. }
  21325. /**
  21326. * xmlSchemaXPathProcessHistory:
  21327. * @vctxt: the WXS validation context
  21328. * @type: the simple/complex type of the current node if any at all
  21329. * @val: the precompiled value
  21330. *
  21331. * Processes and pops the history items of the IDC state objects.
  21332. * IDC key-sequences are validated/created on IDC bindings.
  21333. *
  21334. * Returns 0 on success and -1 on internal errors.
  21335. */
  21336. static int
  21337. xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
  21338. int depth)
  21339. {
  21340. xmlSchemaIDCStateObjPtr sto, nextsto;
  21341. int res, matchDepth;
  21342. xmlSchemaPSVIIDCKeyPtr key = NULL;
  21343. xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
  21344. if (vctxt->xpathStates == NULL)
  21345. return (0);
  21346. sto = vctxt->xpathStates;
  21347. /*
  21348. * Evaluate the state objects.
  21349. */
  21350. while (sto != NULL) {
  21351. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21352. if (res == -1) {
  21353. VERROR_INT("xmlSchemaXPathProcessHistory",
  21354. "calling xmlStreamPop()");
  21355. return (-1);
  21356. }
  21357. if (sto->nbHistory == 0)
  21358. goto deregister_check;
  21359. matchDepth = sto->history[sto->nbHistory -1];
  21360. /*
  21361. * Only matches at the current depth are of interest.
  21362. */
  21363. if (matchDepth != depth) {
  21364. sto = sto->next;
  21365. continue;
  21366. }
  21367. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21368. /*
  21369. * NOTE: According to
  21370. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
  21371. * ... the simple-content of complex types is also allowed.
  21372. */
  21373. if (WXS_IS_COMPLEX(type)) {
  21374. if (WXS_HAS_SIMPLE_CONTENT(type)) {
  21375. /*
  21376. * Sanity check for complex types with simple content.
  21377. */
  21378. simpleType = type->contentTypeDef;
  21379. if (simpleType == NULL) {
  21380. VERROR_INT("xmlSchemaXPathProcessHistory",
  21381. "field resolves to a CT with simple content "
  21382. "but the CT is missing the ST definition");
  21383. return (-1);
  21384. }
  21385. } else
  21386. simpleType = NULL;
  21387. } else
  21388. simpleType = type;
  21389. if (simpleType == NULL) {
  21390. xmlChar *str = NULL;
  21391. /*
  21392. * Not qualified if the field resolves to a node of non
  21393. * simple type.
  21394. */
  21395. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21396. XML_SCHEMAV_CVC_IDC, NULL,
  21397. WXS_BASIC_CAST sto->matcher->aidc->def,
  21398. "The XPath '%s' of a field of %s does evaluate to a node of "
  21399. "non-simple type",
  21400. sto->sel->xpath,
  21401. xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
  21402. FREE_AND_NULL(str);
  21403. sto->nbHistory--;
  21404. goto deregister_check;
  21405. }
  21406. if ((key == NULL) && (vctxt->inode->val == NULL)) {
  21407. /*
  21408. * Failed to provide the normalized value; maybe
  21409. * the value was invalid.
  21410. */
  21411. VERROR(XML_SCHEMAV_CVC_IDC,
  21412. WXS_BASIC_CAST sto->matcher->aidc->def,
  21413. "Warning: No precomputed value available, the value "
  21414. "was either invalid or something strange happened");
  21415. sto->nbHistory--;
  21416. goto deregister_check;
  21417. } else {
  21418. xmlSchemaIDCMatcherPtr matcher = sto->matcher;
  21419. xmlSchemaPSVIIDCKeyPtr *keySeq;
  21420. int pos, idx;
  21421. /*
  21422. * The key will be anchored on the matcher's list of
  21423. * key-sequences. The position in this list is determined
  21424. * by the target node's depth relative to the matcher's
  21425. * depth of creation (i.e. the depth of the scope element).
  21426. *
  21427. * Element Depth Pos List-entries
  21428. * <scope> 0 NULL
  21429. * <bar> 1 NULL
  21430. * <target/> 2 2 target
  21431. * <bar>
  21432. * </scope>
  21433. *
  21434. * The size of the list is only dependent on the depth of
  21435. * the tree.
  21436. * An entry will be NULLed in selector_leave, i.e. when
  21437. * we hit the target's
  21438. */
  21439. pos = sto->depth - matcher->depth;
  21440. idx = sto->sel->index;
  21441. /*
  21442. * Create/grow the array of key-sequences.
  21443. */
  21444. if (matcher->keySeqs == NULL) {
  21445. if (pos > 9)
  21446. matcher->sizeKeySeqs = pos * 2;
  21447. else
  21448. matcher->sizeKeySeqs = 10;
  21449. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21450. xmlMalloc(matcher->sizeKeySeqs *
  21451. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21452. if (matcher->keySeqs == NULL) {
  21453. xmlSchemaVErrMemory(NULL,
  21454. "allocating an array of key-sequences",
  21455. NULL);
  21456. return(-1);
  21457. }
  21458. memset(matcher->keySeqs, 0,
  21459. matcher->sizeKeySeqs *
  21460. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21461. } else if (pos >= matcher->sizeKeySeqs) {
  21462. int i = matcher->sizeKeySeqs;
  21463. matcher->sizeKeySeqs = pos * 2;
  21464. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21465. xmlRealloc(matcher->keySeqs,
  21466. matcher->sizeKeySeqs *
  21467. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21468. if (matcher->keySeqs == NULL) {
  21469. xmlSchemaVErrMemory(NULL,
  21470. "reallocating an array of key-sequences",
  21471. NULL);
  21472. return (-1);
  21473. }
  21474. /*
  21475. * The array needs to be NULLed.
  21476. * TODO: Use memset?
  21477. */
  21478. for (; i < matcher->sizeKeySeqs; i++)
  21479. matcher->keySeqs[i] = NULL;
  21480. }
  21481. /*
  21482. * Get/create the key-sequence.
  21483. */
  21484. keySeq = matcher->keySeqs[pos];
  21485. if (keySeq == NULL) {
  21486. goto create_sequence;
  21487. } else if (keySeq[idx] != NULL) {
  21488. xmlChar *str = NULL;
  21489. /*
  21490. * cvc-identity-constraint:
  21491. * 3 For each node in the `target node set` all
  21492. * of the {fields}, with that node as the context
  21493. * node, evaluate to either an empty node-set or
  21494. * a node-set with exactly one member, which must
  21495. * have a simple type.
  21496. *
  21497. * The key was already set; report an error.
  21498. */
  21499. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21500. XML_SCHEMAV_CVC_IDC, NULL,
  21501. WXS_BASIC_CAST matcher->aidc->def,
  21502. "The XPath '%s' of a field of %s evaluates to a "
  21503. "node-set with more than one member",
  21504. sto->sel->xpath,
  21505. xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
  21506. FREE_AND_NULL(str);
  21507. sto->nbHistory--;
  21508. goto deregister_check;
  21509. } else
  21510. goto create_key;
  21511. create_sequence:
  21512. /*
  21513. * Create a key-sequence.
  21514. */
  21515. keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
  21516. matcher->aidc->def->nbFields *
  21517. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21518. if (keySeq == NULL) {
  21519. xmlSchemaVErrMemory(NULL,
  21520. "allocating an IDC key-sequence", NULL);
  21521. return(-1);
  21522. }
  21523. memset(keySeq, 0, matcher->aidc->def->nbFields *
  21524. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21525. matcher->keySeqs[pos] = keySeq;
  21526. create_key:
  21527. /*
  21528. * Create a key once per node only.
  21529. */
  21530. if (key == NULL) {
  21531. key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
  21532. sizeof(xmlSchemaPSVIIDCKey));
  21533. if (key == NULL) {
  21534. xmlSchemaVErrMemory(NULL,
  21535. "allocating a IDC key", NULL);
  21536. xmlFree(keySeq);
  21537. matcher->keySeqs[pos] = NULL;
  21538. return(-1);
  21539. }
  21540. /*
  21541. * Consume the compiled value.
  21542. */
  21543. key->type = simpleType;
  21544. key->val = vctxt->inode->val;
  21545. vctxt->inode->val = NULL;
  21546. /*
  21547. * Store the key in a global list.
  21548. */
  21549. if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
  21550. xmlSchemaIDCFreeKey(key);
  21551. return (-1);
  21552. }
  21553. }
  21554. keySeq[idx] = key;
  21555. }
  21556. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21557. xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
  21558. /* xmlSchemaPSVIIDCBindingPtr bind; */
  21559. xmlSchemaPSVIIDCNodePtr ntItem;
  21560. xmlSchemaIDCMatcherPtr matcher;
  21561. xmlSchemaIDCPtr idc;
  21562. xmlSchemaItemListPtr targets;
  21563. int pos, i, j, nbKeys;
  21564. /*
  21565. * Here we have the following scenario:
  21566. * An IDC 'selector' state object resolved to a target node,
  21567. * during the time this target node was in the
  21568. * ancestor-or-self axis, the 'field' state object(s) looked
  21569. * out for matching nodes to create a key-sequence for this
  21570. * target node. Now we are back to this target node and need
  21571. * to put the key-sequence, together with the target node
  21572. * itself, into the node-table of the corresponding IDC
  21573. * binding.
  21574. */
  21575. matcher = sto->matcher;
  21576. idc = matcher->aidc->def;
  21577. nbKeys = idc->nbFields;
  21578. pos = depth - matcher->depth;
  21579. /*
  21580. * Check if the matcher has any key-sequences at all, plus
  21581. * if it has a key-sequence for the current target node.
  21582. */
  21583. if ((matcher->keySeqs == NULL) ||
  21584. (matcher->sizeKeySeqs <= pos)) {
  21585. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21586. goto selector_key_error;
  21587. else
  21588. goto selector_leave;
  21589. }
  21590. keySeq = &(matcher->keySeqs[pos]);
  21591. if (*keySeq == NULL) {
  21592. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21593. goto selector_key_error;
  21594. else
  21595. goto selector_leave;
  21596. }
  21597. for (i = 0; i < nbKeys; i++) {
  21598. if ((*keySeq)[i] == NULL) {
  21599. /*
  21600. * Not qualified, if not all fields did resolve.
  21601. */
  21602. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
  21603. /*
  21604. * All fields of a "key" IDC must resolve.
  21605. */
  21606. goto selector_key_error;
  21607. }
  21608. goto selector_leave;
  21609. }
  21610. }
  21611. /*
  21612. * All fields did resolve.
  21613. */
  21614. /*
  21615. * 4.1 If the {identity-constraint category} is unique(/key),
  21616. * then no two members of the `qualified node set` have
  21617. * `key-sequences` whose members are pairwise equal, as
  21618. * defined by Equal in [XML Schemas: Datatypes].
  21619. *
  21620. * Get the IDC binding from the matcher and check for
  21621. * duplicate key-sequences.
  21622. */
  21623. #if 0
  21624. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21625. #endif
  21626. targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
  21627. if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
  21628. (targets->nbItems != 0)) {
  21629. xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
  21630. xmlIDCHashEntryPtr e;
  21631. res = 0;
  21632. if (!matcher->htab)
  21633. e = NULL;
  21634. else {
  21635. xmlChar *value = NULL;
  21636. xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
  21637. e = xmlHashLookup(matcher->htab, value);
  21638. FREE_AND_NULL(value);
  21639. }
  21640. /*
  21641. * Compare the key-sequences, key by key.
  21642. */
  21643. for (;e; e = e->next) {
  21644. bkeySeq =
  21645. ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
  21646. for (j = 0; j < nbKeys; j++) {
  21647. ckey = (*keySeq)[j];
  21648. bkey = bkeySeq[j];
  21649. res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
  21650. if (res == -1) {
  21651. return (-1);
  21652. } else if (res == 0) {
  21653. /*
  21654. * One of the keys differs, so the key-sequence
  21655. * won't be equal; get out.
  21656. */
  21657. break;
  21658. }
  21659. }
  21660. if (res == 1) {
  21661. /*
  21662. * Duplicate key-sequence found.
  21663. */
  21664. break;
  21665. }
  21666. }
  21667. if (e) {
  21668. xmlChar *str = NULL, *strB = NULL;
  21669. /*
  21670. * TODO: Try to report the key-sequence.
  21671. */
  21672. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21673. XML_SCHEMAV_CVC_IDC, NULL,
  21674. WXS_BASIC_CAST idc,
  21675. "Duplicate key-sequence %s in %s",
  21676. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  21677. (*keySeq), nbKeys),
  21678. xmlSchemaGetIDCDesignation(&strB, idc));
  21679. FREE_AND_NULL(str);
  21680. FREE_AND_NULL(strB);
  21681. goto selector_leave;
  21682. }
  21683. }
  21684. /*
  21685. * Add a node-table item to the IDC binding.
  21686. */
  21687. ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
  21688. sizeof(xmlSchemaPSVIIDCNode));
  21689. if (ntItem == NULL) {
  21690. xmlSchemaVErrMemory(NULL,
  21691. "allocating an IDC node-table item", NULL);
  21692. xmlFree(*keySeq);
  21693. *keySeq = NULL;
  21694. return(-1);
  21695. }
  21696. memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
  21697. /*
  21698. * Store the node-table item in a global list.
  21699. */
  21700. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21701. if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
  21702. xmlFree(ntItem);
  21703. xmlFree(*keySeq);
  21704. *keySeq = NULL;
  21705. return (-1);
  21706. }
  21707. ntItem->nodeQNameID = -1;
  21708. } else {
  21709. /*
  21710. * Save a cached QName for this node on the IDC node, to be
  21711. * able to report it, even if the node is not saved.
  21712. */
  21713. ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
  21714. vctxt->inode->localName, vctxt->inode->nsName);
  21715. if (ntItem->nodeQNameID == -1) {
  21716. xmlFree(ntItem);
  21717. xmlFree(*keySeq);
  21718. *keySeq = NULL;
  21719. return (-1);
  21720. }
  21721. }
  21722. /*
  21723. * Init the node-table item: Save the node, position and
  21724. * consume the key-sequence.
  21725. */
  21726. ntItem->node = vctxt->node;
  21727. ntItem->nodeLine = vctxt->inode->nodeLine;
  21728. ntItem->keys = *keySeq;
  21729. *keySeq = NULL;
  21730. #if 0
  21731. if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
  21732. #endif
  21733. if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
  21734. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21735. /*
  21736. * Free the item, since keyref items won't be
  21737. * put on a global list.
  21738. */
  21739. xmlFree(ntItem->keys);
  21740. xmlFree(ntItem);
  21741. }
  21742. return (-1);
  21743. }
  21744. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21745. xmlChar *value = NULL;
  21746. xmlIDCHashEntryPtr r, e;
  21747. if (!matcher->htab)
  21748. matcher->htab = xmlHashCreate(4);
  21749. xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
  21750. e = xmlMalloc(sizeof *e);
  21751. e->index = targets->nbItems - 1;
  21752. r = xmlHashLookup(matcher->htab, value);
  21753. if (r) {
  21754. e->next = r->next;
  21755. r->next = e;
  21756. } else {
  21757. e->next = NULL;
  21758. xmlHashAddEntry(matcher->htab, value, e);
  21759. }
  21760. FREE_AND_NULL(value);
  21761. }
  21762. goto selector_leave;
  21763. selector_key_error:
  21764. {
  21765. xmlChar *str = NULL;
  21766. /*
  21767. * 4.2.1 (KEY) The `target node set` and the
  21768. * `qualified node set` are equal, that is, every
  21769. * member of the `target node set` is also a member
  21770. * of the `qualified node set` and vice versa.
  21771. */
  21772. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21773. XML_SCHEMAV_CVC_IDC, NULL,
  21774. WXS_BASIC_CAST idc,
  21775. "Not all fields of %s evaluate to a node",
  21776. xmlSchemaGetIDCDesignation(&str, idc), NULL);
  21777. FREE_AND_NULL(str);
  21778. }
  21779. selector_leave:
  21780. /*
  21781. * Free the key-sequence if not added to the IDC table.
  21782. */
  21783. if ((keySeq != NULL) && (*keySeq != NULL)) {
  21784. xmlFree(*keySeq);
  21785. *keySeq = NULL;
  21786. }
  21787. } /* if selector */
  21788. sto->nbHistory--;
  21789. deregister_check:
  21790. /*
  21791. * Deregister state objects if they reach the depth of creation.
  21792. */
  21793. if ((sto->nbHistory == 0) && (sto->depth == depth)) {
  21794. if (vctxt->xpathStates != sto) {
  21795. VERROR_INT("xmlSchemaXPathProcessHistory",
  21796. "The state object to be removed is not the first "
  21797. "in the list");
  21798. }
  21799. nextsto = sto->next;
  21800. /*
  21801. * Unlink from the list of active XPath state objects.
  21802. */
  21803. vctxt->xpathStates = sto->next;
  21804. sto->next = vctxt->xpathStatePool;
  21805. /*
  21806. * Link it to the pool of reusable state objects.
  21807. */
  21808. vctxt->xpathStatePool = sto;
  21809. sto = nextsto;
  21810. } else
  21811. sto = sto->next;
  21812. } /* while (sto != NULL) */
  21813. return (0);
  21814. }
  21815. /**
  21816. * xmlSchemaIDCRegisterMatchers:
  21817. * @vctxt: the WXS validation context
  21818. * @elemDecl: the element declaration
  21819. *
  21820. * Creates helper objects to evaluate IDC selectors/fields
  21821. * successively.
  21822. *
  21823. * Returns 0 if OK and -1 on internal errors.
  21824. */
  21825. static int
  21826. xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
  21827. xmlSchemaElementPtr elemDecl)
  21828. {
  21829. xmlSchemaIDCMatcherPtr matcher, last = NULL;
  21830. xmlSchemaIDCPtr idc, refIdc;
  21831. xmlSchemaIDCAugPtr aidc;
  21832. idc = (xmlSchemaIDCPtr) elemDecl->idcs;
  21833. if (idc == NULL)
  21834. return (0);
  21835. if (vctxt->inode->idcMatchers != NULL) {
  21836. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21837. "The chain of IDC matchers is expected to be empty");
  21838. return (-1);
  21839. }
  21840. do {
  21841. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21842. /*
  21843. * Since IDCs bubbles are expensive we need to know the
  21844. * depth at which the bubbles should stop; this will be
  21845. * the depth of the top-most keyref IDC. If no keyref
  21846. * references a key/unique IDC, the keyrefDepth will
  21847. * be -1, indicating that no bubbles are needed.
  21848. */
  21849. refIdc = (xmlSchemaIDCPtr) idc->ref->item;
  21850. if (refIdc != NULL) {
  21851. /*
  21852. * Remember that we have keyrefs on this node.
  21853. */
  21854. vctxt->inode->hasKeyrefs = 1;
  21855. /*
  21856. * Lookup the referenced augmented IDC info.
  21857. */
  21858. aidc = vctxt->aidcs;
  21859. while (aidc != NULL) {
  21860. if (aidc->def == refIdc)
  21861. break;
  21862. aidc = aidc->next;
  21863. }
  21864. if (aidc == NULL) {
  21865. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21866. "Could not find an augmented IDC item for an IDC "
  21867. "definition");
  21868. return (-1);
  21869. }
  21870. if ((aidc->keyrefDepth == -1) ||
  21871. (vctxt->depth < aidc->keyrefDepth))
  21872. aidc->keyrefDepth = vctxt->depth;
  21873. }
  21874. }
  21875. /*
  21876. * Lookup the augmented IDC item for the IDC definition.
  21877. */
  21878. aidc = vctxt->aidcs;
  21879. while (aidc != NULL) {
  21880. if (aidc->def == idc)
  21881. break;
  21882. aidc = aidc->next;
  21883. }
  21884. if (aidc == NULL) {
  21885. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21886. "Could not find an augmented IDC item for an IDC definition");
  21887. return (-1);
  21888. }
  21889. /*
  21890. * Create an IDC matcher for every IDC definition.
  21891. */
  21892. if (vctxt->idcMatcherCache != NULL) {
  21893. /*
  21894. * Reuse a cached matcher.
  21895. */
  21896. matcher = vctxt->idcMatcherCache;
  21897. vctxt->idcMatcherCache = matcher->nextCached;
  21898. matcher->nextCached = NULL;
  21899. } else {
  21900. matcher = (xmlSchemaIDCMatcherPtr)
  21901. xmlMalloc(sizeof(xmlSchemaIDCMatcher));
  21902. if (matcher == NULL) {
  21903. xmlSchemaVErrMemory(vctxt,
  21904. "allocating an IDC matcher", NULL);
  21905. return (-1);
  21906. }
  21907. memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
  21908. }
  21909. if (last == NULL)
  21910. vctxt->inode->idcMatchers = matcher;
  21911. else
  21912. last->next = matcher;
  21913. last = matcher;
  21914. matcher->type = IDC_MATCHER;
  21915. matcher->depth = vctxt->depth;
  21916. matcher->aidc = aidc;
  21917. matcher->idcType = aidc->def->type;
  21918. /*
  21919. * Init the automaton state object.
  21920. */
  21921. if (xmlSchemaIDCAddStateObject(vctxt, matcher,
  21922. idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
  21923. return (-1);
  21924. idc = idc->next;
  21925. } while (idc != NULL);
  21926. return (0);
  21927. }
  21928. static int
  21929. xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
  21930. xmlSchemaNodeInfoPtr ielem)
  21931. {
  21932. xmlSchemaPSVIIDCBindingPtr bind;
  21933. int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
  21934. xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
  21935. xmlSchemaPSVIIDCNodePtr *targets, *dupls;
  21936. xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
  21937. /* vctxt->createIDCNodeTables */
  21938. while (matcher != NULL) {
  21939. /*
  21940. * Skip keyref IDCs and empty IDC target-lists.
  21941. */
  21942. if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
  21943. WXS_ILIST_IS_EMPTY(matcher->targets))
  21944. {
  21945. matcher = matcher->next;
  21946. continue;
  21947. }
  21948. /*
  21949. * If we _want_ the IDC node-table to be created in any case
  21950. * then do so. Otherwise create them only if keyrefs need them.
  21951. */
  21952. if ((! vctxt->createIDCNodeTables) &&
  21953. ((matcher->aidc->keyrefDepth == -1) ||
  21954. (matcher->aidc->keyrefDepth > vctxt->depth)))
  21955. {
  21956. matcher = matcher->next;
  21957. continue;
  21958. }
  21959. /*
  21960. * Get/create the IDC binding on this element for the IDC definition.
  21961. */
  21962. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21963. if (bind == NULL)
  21964. goto internal_error;
  21965. if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
  21966. dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
  21967. nbDupls = bind->dupls->nbItems;
  21968. } else {
  21969. dupls = NULL;
  21970. nbDupls = 0;
  21971. }
  21972. if (bind->nodeTable != NULL) {
  21973. nbNodeTable = bind->nbNodes;
  21974. } else {
  21975. nbNodeTable = 0;
  21976. }
  21977. if ((nbNodeTable == 0) && (nbDupls == 0)) {
  21978. /*
  21979. * Transfer all IDC target-nodes to the IDC node-table.
  21980. */
  21981. bind->nodeTable =
  21982. (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  21983. bind->sizeNodes = matcher->targets->sizeItems;
  21984. bind->nbNodes = matcher->targets->nbItems;
  21985. matcher->targets->items = NULL;
  21986. matcher->targets->sizeItems = 0;
  21987. matcher->targets->nbItems = 0;
  21988. if (matcher->htab) {
  21989. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21990. matcher->htab = NULL;
  21991. }
  21992. } else {
  21993. /*
  21994. * Compare the key-sequences and add to the IDC node-table.
  21995. */
  21996. nbTargets = matcher->targets->nbItems;
  21997. targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  21998. nbFields = matcher->aidc->def->nbFields;
  21999. i = 0;
  22000. do {
  22001. keys = targets[i]->keys;
  22002. if (nbDupls) {
  22003. /*
  22004. * Search in already found duplicates first.
  22005. */
  22006. j = 0;
  22007. do {
  22008. if (nbFields == 1) {
  22009. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22010. dupls[j]->keys[0]->val);
  22011. if (res == -1)
  22012. goto internal_error;
  22013. if (res == 1) {
  22014. /*
  22015. * Equal key-sequence.
  22016. */
  22017. goto next_target;
  22018. }
  22019. } else {
  22020. res = 0;
  22021. ntkeys = dupls[j]->keys;
  22022. for (k = 0; k < nbFields; k++) {
  22023. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22024. ntkeys[k]->val);
  22025. if (res == -1)
  22026. goto internal_error;
  22027. if (res == 0) {
  22028. /*
  22029. * One of the keys differs.
  22030. */
  22031. break;
  22032. }
  22033. }
  22034. if (res == 1) {
  22035. /*
  22036. * Equal key-sequence found.
  22037. */
  22038. goto next_target;
  22039. }
  22040. }
  22041. j++;
  22042. } while (j < nbDupls);
  22043. }
  22044. if (nbNodeTable) {
  22045. j = 0;
  22046. do {
  22047. if (nbFields == 1) {
  22048. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22049. bind->nodeTable[j]->keys[0]->val);
  22050. if (res == -1)
  22051. goto internal_error;
  22052. if (res == 0) {
  22053. /*
  22054. * The key-sequence differs.
  22055. */
  22056. goto next_node_table_entry;
  22057. }
  22058. } else {
  22059. res = 0;
  22060. ntkeys = bind->nodeTable[j]->keys;
  22061. for (k = 0; k < nbFields; k++) {
  22062. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22063. ntkeys[k]->val);
  22064. if (res == -1)
  22065. goto internal_error;
  22066. if (res == 0) {
  22067. /*
  22068. * One of the keys differs.
  22069. */
  22070. goto next_node_table_entry;
  22071. }
  22072. }
  22073. }
  22074. /*
  22075. * Add the duplicate to the list of duplicates.
  22076. */
  22077. if (bind->dupls == NULL) {
  22078. bind->dupls = xmlSchemaItemListCreate();
  22079. if (bind->dupls == NULL)
  22080. goto internal_error;
  22081. }
  22082. if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
  22083. goto internal_error;
  22084. /*
  22085. * Remove the duplicate entry from the IDC node-table.
  22086. */
  22087. bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
  22088. bind->nbNodes--;
  22089. goto next_target;
  22090. next_node_table_entry:
  22091. j++;
  22092. } while (j < nbNodeTable);
  22093. }
  22094. /*
  22095. * If everything is fine, then add the IDC target-node to
  22096. * the IDC node-table.
  22097. */
  22098. if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
  22099. goto internal_error;
  22100. next_target:
  22101. i++;
  22102. } while (i < nbTargets);
  22103. }
  22104. matcher = matcher->next;
  22105. }
  22106. return(0);
  22107. internal_error:
  22108. return(-1);
  22109. }
  22110. /**
  22111. * xmlSchemaBubbleIDCNodeTables:
  22112. * @depth: the current tree depth
  22113. *
  22114. * Merges IDC bindings of an element at @depth into the corresponding IDC
  22115. * bindings of its parent element. If a duplicate note-table entry is found,
  22116. * both, the parent node-table entry and child entry are discarded from the
  22117. * node-table of the parent.
  22118. *
  22119. * Returns 0 if OK and -1 on internal errors.
  22120. */
  22121. static int
  22122. xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
  22123. {
  22124. xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
  22125. xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
  22126. xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
  22127. xmlSchemaIDCAugPtr aidc;
  22128. int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
  22129. bind = vctxt->inode->idcTable;
  22130. if (bind == NULL) {
  22131. /* Fine, no table, no bubbles. */
  22132. return (0);
  22133. }
  22134. parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
  22135. /*
  22136. * Walk all bindings; create new or add to existing bindings.
  22137. * Remove duplicate key-sequences.
  22138. */
  22139. while (bind != NULL) {
  22140. if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
  22141. goto next_binding;
  22142. /*
  22143. * Check if the key/unique IDC table needs to be bubbled.
  22144. */
  22145. if (! vctxt->createIDCNodeTables) {
  22146. aidc = vctxt->aidcs;
  22147. do {
  22148. if (aidc->def == bind->definition) {
  22149. if ((aidc->keyrefDepth == -1) ||
  22150. (aidc->keyrefDepth >= vctxt->depth)) {
  22151. goto next_binding;
  22152. }
  22153. break;
  22154. }
  22155. aidc = aidc->next;
  22156. } while (aidc != NULL);
  22157. }
  22158. if (parTable != NULL)
  22159. parBind = *parTable;
  22160. /*
  22161. * Search a matching parent binding for the
  22162. * IDC definition.
  22163. */
  22164. while (parBind != NULL) {
  22165. if (parBind->definition == bind->definition)
  22166. break;
  22167. parBind = parBind->next;
  22168. }
  22169. if (parBind != NULL) {
  22170. /*
  22171. * Compare every node-table entry of the child node,
  22172. * i.e. the key-sequence within, ...
  22173. */
  22174. oldNum = parBind->nbNodes; /* Skip newly added items. */
  22175. if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
  22176. oldDupls = parBind->dupls->nbItems;
  22177. dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
  22178. } else {
  22179. dupls = NULL;
  22180. oldDupls = 0;
  22181. }
  22182. parNodes = parBind->nodeTable;
  22183. nbFields = bind->definition->nbFields;
  22184. for (i = 0; i < bind->nbNodes; i++) {
  22185. node = bind->nodeTable[i];
  22186. if (node == NULL)
  22187. continue;
  22188. /*
  22189. * ...with every key-sequence of the parent node, already
  22190. * evaluated to be a duplicate key-sequence.
  22191. */
  22192. if (oldDupls) {
  22193. j = 0;
  22194. while (j < oldDupls) {
  22195. if (nbFields == 1) {
  22196. ret = xmlSchemaAreValuesEqual(
  22197. node->keys[0]->val,
  22198. dupls[j]->keys[0]->val);
  22199. if (ret == -1)
  22200. goto internal_error;
  22201. if (ret == 0) {
  22202. j++;
  22203. continue;
  22204. }
  22205. } else {
  22206. parNode = dupls[j];
  22207. for (k = 0; k < nbFields; k++) {
  22208. ret = xmlSchemaAreValuesEqual(
  22209. node->keys[k]->val,
  22210. parNode->keys[k]->val);
  22211. if (ret == -1)
  22212. goto internal_error;
  22213. if (ret == 0)
  22214. break;
  22215. }
  22216. }
  22217. if (ret == 1)
  22218. /* Duplicate found. */
  22219. break;
  22220. j++;
  22221. }
  22222. if (j != oldDupls) {
  22223. /* Duplicate found. Skip this entry. */
  22224. continue;
  22225. }
  22226. }
  22227. /*
  22228. * ... and with every key-sequence of the parent node.
  22229. */
  22230. if (oldNum) {
  22231. j = 0;
  22232. while (j < oldNum) {
  22233. parNode = parNodes[j];
  22234. if (nbFields == 1) {
  22235. ret = xmlSchemaAreValuesEqual(
  22236. node->keys[0]->val,
  22237. parNode->keys[0]->val);
  22238. if (ret == -1)
  22239. goto internal_error;
  22240. if (ret == 0) {
  22241. j++;
  22242. continue;
  22243. }
  22244. } else {
  22245. for (k = 0; k < nbFields; k++) {
  22246. ret = xmlSchemaAreValuesEqual(
  22247. node->keys[k]->val,
  22248. parNode->keys[k]->val);
  22249. if (ret == -1)
  22250. goto internal_error;
  22251. if (ret == 0)
  22252. break;
  22253. }
  22254. }
  22255. if (ret == 1)
  22256. /* Duplicate found. */
  22257. break;
  22258. j++;
  22259. }
  22260. if (j != oldNum) {
  22261. /*
  22262. * Handle duplicates. Move the duplicate in
  22263. * the parent's node-table to the list of
  22264. * duplicates.
  22265. */
  22266. oldNum--;
  22267. parBind->nbNodes--;
  22268. /*
  22269. * Move last old item to pos of duplicate.
  22270. */
  22271. parNodes[j] = parNodes[oldNum];
  22272. if (parBind->nbNodes != oldNum) {
  22273. /*
  22274. * If new items exist, move last new item to
  22275. * last of old items.
  22276. */
  22277. parNodes[oldNum] =
  22278. parNodes[parBind->nbNodes];
  22279. }
  22280. if (parBind->dupls == NULL) {
  22281. parBind->dupls = xmlSchemaItemListCreate();
  22282. if (parBind->dupls == NULL)
  22283. goto internal_error;
  22284. }
  22285. xmlSchemaItemListAdd(parBind->dupls, parNode);
  22286. } else {
  22287. /*
  22288. * Add the node-table entry (node and key-sequence) of
  22289. * the child node to the node table of the parent node.
  22290. */
  22291. if (parBind->nodeTable == NULL) {
  22292. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22293. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  22294. if (parBind->nodeTable == NULL) {
  22295. xmlSchemaVErrMemory(NULL,
  22296. "allocating IDC list of node-table items", NULL);
  22297. goto internal_error;
  22298. }
  22299. parBind->sizeNodes = 1;
  22300. } else if (parBind->nbNodes >= parBind->sizeNodes) {
  22301. parBind->sizeNodes *= 2;
  22302. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22303. xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
  22304. sizeof(xmlSchemaPSVIIDCNodePtr));
  22305. if (parBind->nodeTable == NULL) {
  22306. xmlSchemaVErrMemory(NULL,
  22307. "re-allocating IDC list of node-table items", NULL);
  22308. goto internal_error;
  22309. }
  22310. }
  22311. parNodes = parBind->nodeTable;
  22312. /*
  22313. * Append the new node-table entry to the 'new node-table
  22314. * entries' section.
  22315. */
  22316. parNodes[parBind->nbNodes++] = node;
  22317. }
  22318. }
  22319. }
  22320. } else {
  22321. /*
  22322. * No binding for the IDC was found: create a new one and
  22323. * copy all node-tables.
  22324. */
  22325. parBind = xmlSchemaIDCNewBinding(bind->definition);
  22326. if (parBind == NULL)
  22327. goto internal_error;
  22328. /*
  22329. * TODO: Hmm, how to optimize the initial number of
  22330. * allocated entries?
  22331. */
  22332. if (bind->nbNodes != 0) {
  22333. /*
  22334. * Add all IDC node-table entries.
  22335. */
  22336. if (! vctxt->psviExposeIDCNodeTables) {
  22337. /*
  22338. * Just move the entries.
  22339. * NOTE: this is quite save here, since
  22340. * all the keyref lookups have already been
  22341. * performed.
  22342. */
  22343. parBind->nodeTable = bind->nodeTable;
  22344. bind->nodeTable = NULL;
  22345. parBind->sizeNodes = bind->sizeNodes;
  22346. bind->sizeNodes = 0;
  22347. parBind->nbNodes = bind->nbNodes;
  22348. bind->nbNodes = 0;
  22349. } else {
  22350. /*
  22351. * Copy the entries.
  22352. */
  22353. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22354. xmlMalloc(bind->nbNodes *
  22355. sizeof(xmlSchemaPSVIIDCNodePtr));
  22356. if (parBind->nodeTable == NULL) {
  22357. xmlSchemaVErrMemory(NULL,
  22358. "allocating an array of IDC node-table "
  22359. "items", NULL);
  22360. xmlSchemaIDCFreeBinding(parBind);
  22361. goto internal_error;
  22362. }
  22363. parBind->sizeNodes = bind->nbNodes;
  22364. parBind->nbNodes = bind->nbNodes;
  22365. memcpy(parBind->nodeTable, bind->nodeTable,
  22366. bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
  22367. }
  22368. }
  22369. if (bind->dupls) {
  22370. /*
  22371. * Move the duplicates.
  22372. */
  22373. if (parBind->dupls != NULL)
  22374. xmlSchemaItemListFree(parBind->dupls);
  22375. parBind->dupls = bind->dupls;
  22376. bind->dupls = NULL;
  22377. }
  22378. if (parTable != NULL) {
  22379. if (*parTable == NULL)
  22380. *parTable = parBind;
  22381. else {
  22382. parBind->next = *parTable;
  22383. *parTable = parBind;
  22384. }
  22385. }
  22386. }
  22387. next_binding:
  22388. bind = bind->next;
  22389. }
  22390. return (0);
  22391. internal_error:
  22392. return(-1);
  22393. }
  22394. /**
  22395. * xmlSchemaCheckCVCIDCKeyRef:
  22396. * @vctxt: the WXS validation context
  22397. * @elemDecl: the element declaration
  22398. *
  22399. * Check the cvc-idc-keyref constraints.
  22400. */
  22401. static int
  22402. xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
  22403. {
  22404. xmlSchemaIDCMatcherPtr matcher;
  22405. xmlSchemaPSVIIDCBindingPtr bind;
  22406. matcher = vctxt->inode->idcMatchers;
  22407. /*
  22408. * Find a keyref.
  22409. */
  22410. while (matcher != NULL) {
  22411. if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
  22412. matcher->targets &&
  22413. matcher->targets->nbItems)
  22414. {
  22415. int i, j, k, res, nbFields, hasDupls;
  22416. xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
  22417. xmlSchemaPSVIIDCNodePtr refNode = NULL;
  22418. xmlHashTablePtr table = NULL;
  22419. nbFields = matcher->aidc->def->nbFields;
  22420. /*
  22421. * Find the IDC node-table for the referenced IDC key/unique.
  22422. */
  22423. bind = vctxt->inode->idcTable;
  22424. while (bind != NULL) {
  22425. if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
  22426. bind->definition)
  22427. break;
  22428. bind = bind->next;
  22429. }
  22430. hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
  22431. /*
  22432. * Search for a matching key-sequences.
  22433. */
  22434. if (bind) {
  22435. table = xmlHashCreate(bind->nbNodes * 2);
  22436. for (j = 0; j < bind->nbNodes; j++) {
  22437. xmlChar *value;
  22438. xmlIDCHashEntryPtr r, e;
  22439. keys = bind->nodeTable[j]->keys;
  22440. xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
  22441. e = xmlMalloc(sizeof *e);
  22442. e->index = j;
  22443. r = xmlHashLookup(table, value);
  22444. if (r) {
  22445. e->next = r->next;
  22446. r->next = e;
  22447. } else {
  22448. e->next = NULL;
  22449. xmlHashAddEntry(table, value, e);
  22450. }
  22451. FREE_AND_NULL(value);
  22452. }
  22453. }
  22454. for (i = 0; i < matcher->targets->nbItems; i++) {
  22455. res = 0;
  22456. refNode = matcher->targets->items[i];
  22457. if (bind != NULL) {
  22458. xmlChar *value;
  22459. xmlIDCHashEntryPtr e;
  22460. refKeys = refNode->keys;
  22461. xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
  22462. e = xmlHashLookup(table, value);
  22463. FREE_AND_NULL(value);
  22464. res = 0;
  22465. for (;e; e = e->next) {
  22466. keys = bind->nodeTable[e->index]->keys;
  22467. for (k = 0; k < nbFields; k++) {
  22468. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22469. refKeys[k]->val);
  22470. if (res == 0)
  22471. break;
  22472. else if (res == -1) {
  22473. return (-1);
  22474. }
  22475. }
  22476. if (res == 1) {
  22477. /*
  22478. * Match found.
  22479. */
  22480. break;
  22481. }
  22482. }
  22483. if ((res == 0) && hasDupls) {
  22484. /*
  22485. * Search in duplicates
  22486. */
  22487. for (j = 0; j < bind->dupls->nbItems; j++) {
  22488. keys = ((xmlSchemaPSVIIDCNodePtr)
  22489. bind->dupls->items[j])->keys;
  22490. for (k = 0; k < nbFields; k++) {
  22491. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22492. refKeys[k]->val);
  22493. if (res == 0)
  22494. break;
  22495. else if (res == -1) {
  22496. return (-1);
  22497. }
  22498. }
  22499. if (res == 1) {
  22500. /*
  22501. * Match in duplicates found.
  22502. */
  22503. xmlChar *str = NULL, *strB = NULL;
  22504. xmlSchemaKeyrefErr(vctxt,
  22505. XML_SCHEMAV_CVC_IDC, refNode,
  22506. (xmlSchemaTypePtr) matcher->aidc->def,
  22507. "More than one match found for "
  22508. "key-sequence %s of keyref '%s'",
  22509. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22510. refNode->keys, nbFields),
  22511. xmlSchemaGetComponentQName(&strB,
  22512. matcher->aidc->def));
  22513. FREE_AND_NULL(str);
  22514. FREE_AND_NULL(strB);
  22515. break;
  22516. }
  22517. }
  22518. }
  22519. }
  22520. if (res == 0) {
  22521. xmlChar *str = NULL, *strB = NULL;
  22522. xmlSchemaKeyrefErr(vctxt,
  22523. XML_SCHEMAV_CVC_IDC, refNode,
  22524. (xmlSchemaTypePtr) matcher->aidc->def,
  22525. "No match found for key-sequence %s of keyref '%s'",
  22526. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22527. refNode->keys, nbFields),
  22528. xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
  22529. FREE_AND_NULL(str);
  22530. FREE_AND_NULL(strB);
  22531. }
  22532. }
  22533. if (table) {
  22534. xmlHashFree(table, xmlFreeIDCHashEntry);
  22535. }
  22536. }
  22537. matcher = matcher->next;
  22538. }
  22539. /* TODO: Return an error if any error encountered. */
  22540. return (0);
  22541. }
  22542. /************************************************************************
  22543. * *
  22544. * XML Reader validation code *
  22545. * *
  22546. ************************************************************************/
  22547. static xmlSchemaAttrInfoPtr
  22548. xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
  22549. {
  22550. xmlSchemaAttrInfoPtr iattr;
  22551. /*
  22552. * Grow/create list of attribute infos.
  22553. */
  22554. if (vctxt->attrInfos == NULL) {
  22555. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22556. xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
  22557. vctxt->sizeAttrInfos = 1;
  22558. if (vctxt->attrInfos == NULL) {
  22559. xmlSchemaVErrMemory(vctxt,
  22560. "allocating attribute info list", NULL);
  22561. return (NULL);
  22562. }
  22563. } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
  22564. vctxt->sizeAttrInfos++;
  22565. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22566. xmlRealloc(vctxt->attrInfos,
  22567. vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
  22568. if (vctxt->attrInfos == NULL) {
  22569. xmlSchemaVErrMemory(vctxt,
  22570. "re-allocating attribute info list", NULL);
  22571. return (NULL);
  22572. }
  22573. } else {
  22574. iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
  22575. if (iattr->localName != NULL) {
  22576. VERROR_INT("xmlSchemaGetFreshAttrInfo",
  22577. "attr info not cleared");
  22578. return (NULL);
  22579. }
  22580. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22581. return (iattr);
  22582. }
  22583. /*
  22584. * Create an attribute info.
  22585. */
  22586. iattr = (xmlSchemaAttrInfoPtr)
  22587. xmlMalloc(sizeof(xmlSchemaAttrInfo));
  22588. if (iattr == NULL) {
  22589. xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
  22590. return (NULL);
  22591. }
  22592. memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
  22593. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22594. vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
  22595. return (iattr);
  22596. }
  22597. static int
  22598. xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
  22599. xmlNodePtr attrNode,
  22600. int nodeLine,
  22601. const xmlChar *localName,
  22602. const xmlChar *nsName,
  22603. int ownedNames,
  22604. xmlChar *value,
  22605. int ownedValue)
  22606. {
  22607. xmlSchemaAttrInfoPtr attr;
  22608. attr = xmlSchemaGetFreshAttrInfo(vctxt);
  22609. if (attr == NULL) {
  22610. VERROR_INT("xmlSchemaPushAttribute",
  22611. "calling xmlSchemaGetFreshAttrInfo()");
  22612. return (-1);
  22613. }
  22614. attr->node = attrNode;
  22615. attr->nodeLine = nodeLine;
  22616. attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
  22617. attr->localName = localName;
  22618. attr->nsName = nsName;
  22619. if (ownedNames)
  22620. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  22621. /*
  22622. * Evaluate if it's an XSI attribute.
  22623. */
  22624. if (nsName != NULL) {
  22625. if (xmlStrEqual(localName, BAD_CAST "nil")) {
  22626. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22627. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
  22628. }
  22629. } else if (xmlStrEqual(localName, BAD_CAST "type")) {
  22630. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22631. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
  22632. }
  22633. } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
  22634. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22635. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
  22636. }
  22637. } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
  22638. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22639. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
  22640. }
  22641. } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
  22642. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
  22643. }
  22644. }
  22645. attr->value = value;
  22646. if (ownedValue)
  22647. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  22648. if (attr->metaType != 0)
  22649. attr->state = XML_SCHEMAS_ATTR_META;
  22650. return (0);
  22651. }
  22652. /**
  22653. * xmlSchemaClearElemInfo:
  22654. * @vctxt: the WXS validation context
  22655. * @ielem: the element information item
  22656. */
  22657. static void
  22658. xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
  22659. xmlSchemaNodeInfoPtr ielem)
  22660. {
  22661. ielem->hasKeyrefs = 0;
  22662. ielem->appliedXPath = 0;
  22663. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  22664. FREE_AND_NULL(ielem->localName);
  22665. FREE_AND_NULL(ielem->nsName);
  22666. } else {
  22667. ielem->localName = NULL;
  22668. ielem->nsName = NULL;
  22669. }
  22670. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  22671. FREE_AND_NULL(ielem->value);
  22672. } else {
  22673. ielem->value = NULL;
  22674. }
  22675. if (ielem->val != NULL) {
  22676. /*
  22677. * PSVI TODO: Be careful not to free it when the value is
  22678. * exposed via PSVI.
  22679. */
  22680. xmlSchemaFreeValue(ielem->val);
  22681. ielem->val = NULL;
  22682. }
  22683. if (ielem->idcMatchers != NULL) {
  22684. /*
  22685. * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
  22686. * Does it work?
  22687. */
  22688. xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
  22689. #if 0
  22690. xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
  22691. #endif
  22692. ielem->idcMatchers = NULL;
  22693. }
  22694. if (ielem->idcTable != NULL) {
  22695. /*
  22696. * OPTIMIZE TODO: Use a pool of IDC tables??.
  22697. */
  22698. xmlSchemaIDCFreeIDCTable(ielem->idcTable);
  22699. ielem->idcTable = NULL;
  22700. }
  22701. if (ielem->regexCtxt != NULL) {
  22702. xmlRegFreeExecCtxt(ielem->regexCtxt);
  22703. ielem->regexCtxt = NULL;
  22704. }
  22705. if (ielem->nsBindings != NULL) {
  22706. xmlFree((xmlChar **)ielem->nsBindings);
  22707. ielem->nsBindings = NULL;
  22708. ielem->nbNsBindings = 0;
  22709. ielem->sizeNsBindings = 0;
  22710. }
  22711. }
  22712. /**
  22713. * xmlSchemaGetFreshElemInfo:
  22714. * @vctxt: the schema validation context
  22715. *
  22716. * Creates/reuses and initializes the element info item for
  22717. * the current tree depth.
  22718. *
  22719. * Returns the element info item or NULL on API or internal errors.
  22720. */
  22721. static xmlSchemaNodeInfoPtr
  22722. xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
  22723. {
  22724. xmlSchemaNodeInfoPtr info = NULL;
  22725. if (vctxt->depth > vctxt->sizeElemInfos) {
  22726. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22727. "inconsistent depth encountered");
  22728. return (NULL);
  22729. }
  22730. if (vctxt->elemInfos == NULL) {
  22731. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22732. xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
  22733. if (vctxt->elemInfos == NULL) {
  22734. xmlSchemaVErrMemory(vctxt,
  22735. "allocating the element info array", NULL);
  22736. return (NULL);
  22737. }
  22738. memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
  22739. vctxt->sizeElemInfos = 10;
  22740. } else if (vctxt->sizeElemInfos <= vctxt->depth) {
  22741. int i = vctxt->sizeElemInfos;
  22742. vctxt->sizeElemInfos *= 2;
  22743. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22744. xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
  22745. sizeof(xmlSchemaNodeInfoPtr));
  22746. if (vctxt->elemInfos == NULL) {
  22747. xmlSchemaVErrMemory(vctxt,
  22748. "re-allocating the element info array", NULL);
  22749. return (NULL);
  22750. }
  22751. /*
  22752. * We need the new memory to be NULLed.
  22753. * TODO: Use memset instead?
  22754. */
  22755. for (; i < vctxt->sizeElemInfos; i++)
  22756. vctxt->elemInfos[i] = NULL;
  22757. } else
  22758. info = vctxt->elemInfos[vctxt->depth];
  22759. if (info == NULL) {
  22760. info = (xmlSchemaNodeInfoPtr)
  22761. xmlMalloc(sizeof(xmlSchemaNodeInfo));
  22762. if (info == NULL) {
  22763. xmlSchemaVErrMemory(vctxt,
  22764. "allocating an element info", NULL);
  22765. return (NULL);
  22766. }
  22767. vctxt->elemInfos[vctxt->depth] = info;
  22768. } else {
  22769. if (info->localName != NULL) {
  22770. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22771. "elem info has not been cleared");
  22772. return (NULL);
  22773. }
  22774. }
  22775. memset(info, 0, sizeof(xmlSchemaNodeInfo));
  22776. info->nodeType = XML_ELEMENT_NODE;
  22777. info->depth = vctxt->depth;
  22778. return (info);
  22779. }
  22780. #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
  22781. #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
  22782. #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
  22783. static int
  22784. xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
  22785. xmlNodePtr node,
  22786. xmlSchemaTypePtr type,
  22787. xmlSchemaValType valType,
  22788. const xmlChar * value,
  22789. xmlSchemaValPtr val,
  22790. unsigned long length,
  22791. int fireErrors)
  22792. {
  22793. int ret, error = 0, found;
  22794. xmlSchemaTypePtr tmpType;
  22795. xmlSchemaFacetLinkPtr facetLink;
  22796. xmlSchemaFacetPtr facet;
  22797. unsigned long len = 0;
  22798. xmlSchemaWhitespaceValueType ws;
  22799. /*
  22800. * In Libxml2, derived built-in types have currently no explicit facets.
  22801. */
  22802. if (type->type == XML_SCHEMA_TYPE_BASIC)
  22803. return (0);
  22804. /*
  22805. * NOTE: Do not jump away, if the facetSet of the given type is
  22806. * empty: until now, "pattern" and "enumeration" facets of the
  22807. * *base types* need to be checked as well.
  22808. */
  22809. if (type->facetSet == NULL)
  22810. goto pattern_and_enum;
  22811. if (! WXS_IS_ATOMIC(type)) {
  22812. if (WXS_IS_LIST(type))
  22813. goto WXS_IS_LIST;
  22814. else
  22815. goto pattern_and_enum;
  22816. }
  22817. /*
  22818. * Whitespace handling is only of importance for string-based
  22819. * types.
  22820. */
  22821. tmpType = xmlSchemaGetPrimitiveType(type);
  22822. if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
  22823. WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
  22824. ws = xmlSchemaGetWhiteSpaceFacetValue(type);
  22825. } else
  22826. ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
  22827. /*
  22828. * If the value was not computed (for string or
  22829. * anySimpleType based types), then use the provided
  22830. * type.
  22831. */
  22832. if (val != NULL)
  22833. valType = xmlSchemaGetValType(val);
  22834. ret = 0;
  22835. for (facetLink = type->facetSet; facetLink != NULL;
  22836. facetLink = facetLink->next) {
  22837. /*
  22838. * Skip the pattern "whiteSpace": it is used to
  22839. * format the character content beforehand.
  22840. */
  22841. switch (facetLink->facet->type) {
  22842. case XML_SCHEMA_FACET_WHITESPACE:
  22843. case XML_SCHEMA_FACET_PATTERN:
  22844. case XML_SCHEMA_FACET_ENUMERATION:
  22845. continue;
  22846. case XML_SCHEMA_FACET_LENGTH:
  22847. case XML_SCHEMA_FACET_MINLENGTH:
  22848. case XML_SCHEMA_FACET_MAXLENGTH:
  22849. ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
  22850. valType, value, val, &len, ws);
  22851. break;
  22852. default:
  22853. ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
  22854. valType, value, val, ws);
  22855. break;
  22856. }
  22857. if (ret < 0) {
  22858. AERROR_INT("xmlSchemaValidateFacets",
  22859. "validating against a atomic type facet");
  22860. return (-1);
  22861. } else if (ret > 0) {
  22862. if (fireErrors)
  22863. xmlSchemaFacetErr(actxt, ret, node,
  22864. value, len, type, facetLink->facet, NULL, NULL, NULL);
  22865. else
  22866. return (ret);
  22867. if (error == 0)
  22868. error = ret;
  22869. }
  22870. ret = 0;
  22871. }
  22872. WXS_IS_LIST:
  22873. if (! WXS_IS_LIST(type))
  22874. goto pattern_and_enum;
  22875. /*
  22876. * "length", "minLength" and "maxLength" of list types.
  22877. */
  22878. ret = 0;
  22879. for (facetLink = type->facetSet; facetLink != NULL;
  22880. facetLink = facetLink->next) {
  22881. switch (facetLink->facet->type) {
  22882. case XML_SCHEMA_FACET_LENGTH:
  22883. case XML_SCHEMA_FACET_MINLENGTH:
  22884. case XML_SCHEMA_FACET_MAXLENGTH:
  22885. ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
  22886. value, length, NULL);
  22887. break;
  22888. default:
  22889. continue;
  22890. }
  22891. if (ret < 0) {
  22892. AERROR_INT("xmlSchemaValidateFacets",
  22893. "validating against a list type facet");
  22894. return (-1);
  22895. } else if (ret > 0) {
  22896. if (fireErrors)
  22897. xmlSchemaFacetErr(actxt, ret, node,
  22898. value, length, type, facetLink->facet, NULL, NULL, NULL);
  22899. else
  22900. return (ret);
  22901. if (error == 0)
  22902. error = ret;
  22903. }
  22904. ret = 0;
  22905. }
  22906. pattern_and_enum:
  22907. found = 0;
  22908. /*
  22909. * Process enumerations. Facet values are in the value space
  22910. * of the defining type's base type. This seems to be a bug in the
  22911. * XML Schema 1.0 spec. Use the whitespace type of the base type.
  22912. * Only the first set of enumerations in the ancestor-or-self axis
  22913. * is used for validation.
  22914. */
  22915. ret = 0;
  22916. tmpType = type;
  22917. do {
  22918. for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
  22919. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  22920. continue;
  22921. found = 1;
  22922. ret = xmlSchemaAreValuesEqual(facet->val, val);
  22923. if (ret == 1)
  22924. break;
  22925. else if (ret < 0) {
  22926. AERROR_INT("xmlSchemaValidateFacets",
  22927. "validating against an enumeration facet");
  22928. return (-1);
  22929. }
  22930. }
  22931. if (ret != 0)
  22932. break;
  22933. /*
  22934. * Break on the first set of enumerations. Any additional
  22935. * enumerations which might be existent on the ancestors
  22936. * of the current type are restricted by this set; thus
  22937. * *must* *not* be taken into account.
  22938. */
  22939. if (found)
  22940. break;
  22941. tmpType = tmpType->baseType;
  22942. } while ((tmpType != NULL) &&
  22943. (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  22944. if (found && (ret == 0)) {
  22945. ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
  22946. if (fireErrors) {
  22947. xmlSchemaFacetErr(actxt, ret, node,
  22948. value, 0, type, NULL, NULL, NULL, NULL);
  22949. } else
  22950. return (ret);
  22951. if (error == 0)
  22952. error = ret;
  22953. }
  22954. /*
  22955. * Process patters. Pattern facets are ORed at type level
  22956. * and ANDed if derived. Walk the base type axis.
  22957. */
  22958. tmpType = type;
  22959. facet = NULL;
  22960. do {
  22961. found = 0;
  22962. for (facetLink = tmpType->facetSet; facetLink != NULL;
  22963. facetLink = facetLink->next) {
  22964. if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
  22965. continue;
  22966. found = 1;
  22967. /*
  22968. * NOTE that for patterns, @value needs to be the
  22969. * normalized value.
  22970. */
  22971. ret = xmlRegexpExec(facetLink->facet->regexp, value);
  22972. if (ret == 1)
  22973. break;
  22974. else if (ret < 0) {
  22975. AERROR_INT("xmlSchemaValidateFacets",
  22976. "validating against a pattern facet");
  22977. return (-1);
  22978. } else {
  22979. /*
  22980. * Save the last non-validating facet.
  22981. */
  22982. facet = facetLink->facet;
  22983. }
  22984. }
  22985. if (found && (ret != 1)) {
  22986. ret = XML_SCHEMAV_CVC_PATTERN_VALID;
  22987. if (fireErrors) {
  22988. xmlSchemaFacetErr(actxt, ret, node,
  22989. value, 0, type, facet, NULL, NULL, NULL);
  22990. } else
  22991. return (ret);
  22992. if (error == 0)
  22993. error = ret;
  22994. break;
  22995. }
  22996. tmpType = tmpType->baseType;
  22997. } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  22998. return (error);
  22999. }
  23000. static xmlChar *
  23001. xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
  23002. const xmlChar *value)
  23003. {
  23004. switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
  23005. case XML_SCHEMA_WHITESPACE_COLLAPSE:
  23006. return (xmlSchemaCollapseString(value));
  23007. case XML_SCHEMA_WHITESPACE_REPLACE:
  23008. return (xmlSchemaWhiteSpaceReplace(value));
  23009. default:
  23010. return (NULL);
  23011. }
  23012. }
  23013. static int
  23014. xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
  23015. const xmlChar *value,
  23016. xmlSchemaValPtr *val,
  23017. int valNeeded)
  23018. {
  23019. int ret;
  23020. xmlChar *stripped;
  23021. const xmlChar *nsName;
  23022. xmlChar *local, *prefix = NULL;
  23023. ret = xmlValidateQName(value, 1);
  23024. if (ret != 0) {
  23025. if (ret == -1) {
  23026. VERROR_INT("xmlSchemaValidateQName",
  23027. "calling xmlValidateQName()");
  23028. return (-1);
  23029. }
  23030. return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
  23031. }
  23032. /*
  23033. * NOTE: xmlSplitQName2 will always return a duplicated
  23034. * strings.
  23035. */
  23036. /* TODO: Export and use xmlSchemaStrip instead */
  23037. stripped = xmlSchemaCollapseString(value);
  23038. local = xmlSplitQName2(stripped ? stripped : value, &prefix);
  23039. xmlFree(stripped);
  23040. if (local == NULL)
  23041. local = xmlStrdup(value);
  23042. /*
  23043. * OPTIMIZE TODO: Use flags for:
  23044. * - is there any namespace binding?
  23045. * - is there a default namespace?
  23046. */
  23047. nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23048. if (prefix != NULL) {
  23049. xmlFree(prefix);
  23050. /*
  23051. * A namespace must be found if the prefix is
  23052. * NOT NULL.
  23053. */
  23054. if (nsName == NULL) {
  23055. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23056. xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
  23057. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23058. "The QName value '%s' has no "
  23059. "corresponding namespace declaration in "
  23060. "scope", value, NULL);
  23061. if (local != NULL)
  23062. xmlFree(local);
  23063. return (ret);
  23064. }
  23065. }
  23066. if (valNeeded && val) {
  23067. if (nsName != NULL)
  23068. *val = xmlSchemaNewQNameValue(
  23069. BAD_CAST xmlStrdup(nsName), BAD_CAST local);
  23070. else
  23071. *val = xmlSchemaNewQNameValue(NULL,
  23072. BAD_CAST local);
  23073. } else
  23074. xmlFree(local);
  23075. return (0);
  23076. }
  23077. /*
  23078. * cvc-simple-type
  23079. */
  23080. static int
  23081. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  23082. xmlNodePtr node,
  23083. xmlSchemaTypePtr type,
  23084. const xmlChar *value,
  23085. xmlSchemaValPtr *retVal,
  23086. int fireErrors,
  23087. int normalize,
  23088. int isNormalized)
  23089. {
  23090. int ret = 0, valNeeded = (retVal) ? 1 : 0;
  23091. xmlSchemaValPtr val = NULL;
  23092. /* xmlSchemaWhitespaceValueType ws; */
  23093. xmlChar *normValue = NULL;
  23094. #define NORMALIZE(atype) \
  23095. if ((! isNormalized) && \
  23096. (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
  23097. normValue = xmlSchemaNormalizeValue(atype, value); \
  23098. if (normValue != NULL) \
  23099. value = normValue; \
  23100. isNormalized = 1; \
  23101. }
  23102. if ((retVal != NULL) && (*retVal != NULL)) {
  23103. xmlSchemaFreeValue(*retVal);
  23104. *retVal = NULL;
  23105. }
  23106. /*
  23107. * 3.14.4 Simple Type Definition Validation Rules
  23108. * Validation Rule: String Valid
  23109. */
  23110. /*
  23111. * 1 It is schema-valid with respect to that definition as defined
  23112. * by Datatype Valid in [XML Schemas: Datatypes].
  23113. */
  23114. /*
  23115. * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
  23116. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
  23117. * the string must be a `declared entity name`.
  23118. */
  23119. /*
  23120. * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
  23121. * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
  23122. * then every whitespace-delimited substring of the string must be a `declared
  23123. * entity name`.
  23124. */
  23125. /*
  23126. * 2.3 otherwise no further condition applies.
  23127. */
  23128. if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
  23129. valNeeded = 1;
  23130. if (value == NULL)
  23131. value = BAD_CAST "";
  23132. if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
  23133. xmlSchemaTypePtr biType; /* The built-in type. */
  23134. /*
  23135. * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
  23136. * a literal in the `lexical space` of {base type definition}"
  23137. */
  23138. /*
  23139. * Whitespace-normalize.
  23140. */
  23141. NORMALIZE(type);
  23142. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  23143. /*
  23144. * Get the built-in type.
  23145. */
  23146. biType = type->baseType;
  23147. while ((biType != NULL) &&
  23148. (biType->type != XML_SCHEMA_TYPE_BASIC))
  23149. biType = biType->baseType;
  23150. if (biType == NULL) {
  23151. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23152. "could not get the built-in type");
  23153. goto internal_error;
  23154. }
  23155. } else
  23156. biType = type;
  23157. /*
  23158. * NOTATIONs need to be processed here, since they need
  23159. * to lookup in the hashtable of NOTATION declarations of the schema.
  23160. */
  23161. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  23162. switch (biType->builtInType) {
  23163. case XML_SCHEMAS_NOTATION:
  23164. ret = xmlSchemaValidateNotation(
  23165. (xmlSchemaValidCtxtPtr) actxt,
  23166. ((xmlSchemaValidCtxtPtr) actxt)->schema,
  23167. NULL, value, &val, valNeeded);
  23168. break;
  23169. case XML_SCHEMAS_QNAME:
  23170. ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
  23171. value, &val, valNeeded);
  23172. break;
  23173. default:
  23174. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23175. if (valNeeded)
  23176. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23177. value, &val, node);
  23178. else
  23179. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23180. value, NULL, node);
  23181. break;
  23182. }
  23183. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  23184. switch (biType->builtInType) {
  23185. case XML_SCHEMAS_NOTATION:
  23186. ret = xmlSchemaValidateNotation(NULL,
  23187. ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
  23188. value, &val, valNeeded);
  23189. break;
  23190. default:
  23191. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23192. if (valNeeded)
  23193. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23194. value, &val, node);
  23195. else
  23196. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23197. value, NULL, node);
  23198. break;
  23199. }
  23200. } else {
  23201. /*
  23202. * Validation via a public API is not implemented yet.
  23203. */
  23204. TODO
  23205. goto internal_error;
  23206. }
  23207. if (ret != 0) {
  23208. if (ret < 0) {
  23209. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23210. "validating against a built-in type");
  23211. goto internal_error;
  23212. }
  23213. if (WXS_IS_LIST(type))
  23214. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23215. else
  23216. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23217. }
  23218. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23219. /*
  23220. * Check facets.
  23221. */
  23222. ret = xmlSchemaValidateFacets(actxt, node, type,
  23223. (xmlSchemaValType) biType->builtInType, value, val,
  23224. 0, fireErrors);
  23225. if (ret != 0) {
  23226. if (ret < 0) {
  23227. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23228. "validating facets of atomic simple type");
  23229. goto internal_error;
  23230. }
  23231. if (WXS_IS_LIST(type))
  23232. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23233. else
  23234. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23235. }
  23236. }
  23237. else if (fireErrors && (ret > 0))
  23238. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23239. } else if (WXS_IS_LIST(type)) {
  23240. xmlSchemaTypePtr itemType;
  23241. const xmlChar *cur, *end;
  23242. xmlChar *tmpValue = NULL;
  23243. unsigned long len = 0;
  23244. xmlSchemaValPtr prevVal = NULL, curVal = NULL;
  23245. /* 1.2.2 if {variety} is `list` then the string must be a sequence
  23246. * of white space separated tokens, each of which `match`es a literal
  23247. * in the `lexical space` of {item type definition}
  23248. */
  23249. /*
  23250. * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
  23251. * the list type has an enum or pattern facet.
  23252. */
  23253. NORMALIZE(type);
  23254. /*
  23255. * VAL TODO: Optimize validation of empty values.
  23256. * VAL TODO: We do not have computed values for lists.
  23257. */
  23258. itemType = WXS_LIST_ITEMTYPE(type);
  23259. cur = value;
  23260. do {
  23261. while (IS_BLANK_CH(*cur))
  23262. cur++;
  23263. end = cur;
  23264. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  23265. end++;
  23266. if (end == cur)
  23267. break;
  23268. tmpValue = xmlStrndup(cur, end - cur);
  23269. len++;
  23270. if (valNeeded)
  23271. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23272. tmpValue, &curVal, fireErrors, 0, 1);
  23273. else
  23274. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23275. tmpValue, NULL, fireErrors, 0, 1);
  23276. FREE_AND_NULL(tmpValue);
  23277. if (curVal != NULL) {
  23278. /*
  23279. * Add to list of computed values.
  23280. */
  23281. if (val == NULL)
  23282. val = curVal;
  23283. else
  23284. xmlSchemaValueAppend(prevVal, curVal);
  23285. prevVal = curVal;
  23286. curVal = NULL;
  23287. }
  23288. if (ret != 0) {
  23289. if (ret < 0) {
  23290. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23291. "validating an item of list simple type");
  23292. goto internal_error;
  23293. }
  23294. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23295. break;
  23296. }
  23297. cur = end;
  23298. } while (*cur != 0);
  23299. FREE_AND_NULL(tmpValue);
  23300. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23301. /*
  23302. * Apply facets (pattern, enumeration).
  23303. */
  23304. ret = xmlSchemaValidateFacets(actxt, node, type,
  23305. XML_SCHEMAS_UNKNOWN, value, val,
  23306. len, fireErrors);
  23307. if (ret != 0) {
  23308. if (ret < 0) {
  23309. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23310. "validating facets of list simple type");
  23311. goto internal_error;
  23312. }
  23313. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23314. }
  23315. }
  23316. if (fireErrors && (ret > 0)) {
  23317. /*
  23318. * Report the normalized value.
  23319. */
  23320. normalize = 1;
  23321. NORMALIZE(type);
  23322. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23323. }
  23324. } else if (WXS_IS_UNION(type)) {
  23325. xmlSchemaTypeLinkPtr memberLink;
  23326. /*
  23327. * TODO: For all datatypes `derived` by `union` whiteSpace does
  23328. * not apply directly; however, the normalization behavior of `union`
  23329. * types is controlled by the value of whiteSpace on that one of the
  23330. * `memberTypes` against which the `union` is successfully validated.
  23331. *
  23332. * This means that the value is normalized by the first validating
  23333. * member type, then the facets of the union type are applied. This
  23334. * needs changing of the value!
  23335. */
  23336. /*
  23337. * 1.2.3 if {variety} is `union` then the string must `match` a
  23338. * literal in the `lexical space` of at least one member of
  23339. * {member type definitions}
  23340. */
  23341. memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
  23342. if (memberLink == NULL) {
  23343. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23344. "union simple type has no member types");
  23345. goto internal_error;
  23346. }
  23347. /*
  23348. * Always normalize union type values, since we currently
  23349. * cannot store the whitespace information with the value
  23350. * itself; otherwise a later value-comparison would be
  23351. * not possible.
  23352. */
  23353. while (memberLink != NULL) {
  23354. if (valNeeded)
  23355. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23356. memberLink->type, value, &val, 0, 1, 0);
  23357. else
  23358. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23359. memberLink->type, value, NULL, 0, 1, 0);
  23360. if (ret <= 0)
  23361. break;
  23362. memberLink = memberLink->next;
  23363. }
  23364. if (ret != 0) {
  23365. if (ret < 0) {
  23366. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23367. "validating members of union simple type");
  23368. goto internal_error;
  23369. }
  23370. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23371. }
  23372. /*
  23373. * Apply facets (pattern, enumeration).
  23374. */
  23375. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23376. /*
  23377. * The normalization behavior of `union` types is controlled by
  23378. * the value of whiteSpace on that one of the `memberTypes`
  23379. * against which the `union` is successfully validated.
  23380. */
  23381. NORMALIZE(memberLink->type);
  23382. ret = xmlSchemaValidateFacets(actxt, node, type,
  23383. XML_SCHEMAS_UNKNOWN, value, val,
  23384. 0, fireErrors);
  23385. if (ret != 0) {
  23386. if (ret < 0) {
  23387. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23388. "validating facets of union simple type");
  23389. goto internal_error;
  23390. }
  23391. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23392. }
  23393. }
  23394. if (fireErrors && (ret > 0))
  23395. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23396. }
  23397. if (normValue != NULL)
  23398. xmlFree(normValue);
  23399. if (ret == 0) {
  23400. if (retVal != NULL)
  23401. *retVal = val;
  23402. else if (val != NULL)
  23403. xmlSchemaFreeValue(val);
  23404. } else if (val != NULL)
  23405. xmlSchemaFreeValue(val);
  23406. return (ret);
  23407. internal_error:
  23408. if (normValue != NULL)
  23409. xmlFree(normValue);
  23410. if (val != NULL)
  23411. xmlSchemaFreeValue(val);
  23412. return (-1);
  23413. }
  23414. static int
  23415. xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
  23416. const xmlChar *value,
  23417. const xmlChar **nsName,
  23418. const xmlChar **localName)
  23419. {
  23420. int ret = 0;
  23421. if ((nsName == NULL) || (localName == NULL))
  23422. return (-1);
  23423. *nsName = NULL;
  23424. *localName = NULL;
  23425. ret = xmlValidateQName(value, 1);
  23426. if (ret == -1)
  23427. return (-1);
  23428. if (ret > 0) {
  23429. xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
  23430. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23431. value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
  23432. return (1);
  23433. }
  23434. {
  23435. xmlChar *local = NULL;
  23436. xmlChar *prefix;
  23437. /*
  23438. * NOTE: xmlSplitQName2 will return a duplicated
  23439. * string.
  23440. */
  23441. local = xmlSplitQName2(value, &prefix);
  23442. if (local == NULL)
  23443. *localName = xmlDictLookup(vctxt->dict, value, -1);
  23444. else {
  23445. *localName = xmlDictLookup(vctxt->dict, local, -1);
  23446. xmlFree(local);
  23447. }
  23448. *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23449. if (prefix != NULL) {
  23450. xmlFree(prefix);
  23451. /*
  23452. * A namespace must be found if the prefix is NOT NULL.
  23453. */
  23454. if (*nsName == NULL) {
  23455. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23456. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23457. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23458. "The QName value '%s' has no "
  23459. "corresponding namespace declaration in scope",
  23460. value, NULL);
  23461. return (2);
  23462. }
  23463. }
  23464. }
  23465. return (0);
  23466. }
  23467. static int
  23468. xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
  23469. xmlSchemaAttrInfoPtr iattr,
  23470. xmlSchemaTypePtr *localType,
  23471. xmlSchemaElementPtr elemDecl)
  23472. {
  23473. int ret = 0;
  23474. /*
  23475. * cvc-elt (3.3.4) : (4)
  23476. * AND
  23477. * Schema-Validity Assessment (Element) (cvc-assess-elt)
  23478. * (1.2.1.2.1) - (1.2.1.2.4)
  23479. * Handle 'xsi:type'.
  23480. */
  23481. if (localType == NULL)
  23482. return (-1);
  23483. *localType = NULL;
  23484. if (iattr == NULL)
  23485. return (0);
  23486. else {
  23487. const xmlChar *nsName = NULL, *local = NULL;
  23488. /*
  23489. * TODO: We should report a *warning* that the type was overridden
  23490. * by the instance.
  23491. */
  23492. ACTIVATE_ATTRIBUTE(iattr);
  23493. /*
  23494. * (cvc-elt) (3.3.4) : (4.1)
  23495. * (cvc-assess-elt) (1.2.1.2.2)
  23496. */
  23497. ret = xmlSchemaVExpandQName(vctxt, iattr->value,
  23498. &nsName, &local);
  23499. if (ret != 0) {
  23500. if (ret < 0) {
  23501. VERROR_INT("xmlSchemaValidateElementByDeclaration",
  23502. "calling xmlSchemaQNameExpand() to validate the "
  23503. "attribute 'xsi:type'");
  23504. goto internal_error;
  23505. }
  23506. goto exit;
  23507. }
  23508. /*
  23509. * (cvc-elt) (3.3.4) : (4.2)
  23510. * (cvc-assess-elt) (1.2.1.2.3)
  23511. */
  23512. *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
  23513. if (*localType == NULL) {
  23514. xmlChar *str = NULL;
  23515. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23516. XML_SCHEMAV_CVC_ELT_4_2, NULL,
  23517. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23518. "The QName value '%s' of the xsi:type attribute does not "
  23519. "resolve to a type definition",
  23520. xmlSchemaFormatQName(&str, nsName, local), NULL);
  23521. FREE_AND_NULL(str);
  23522. ret = vctxt->err;
  23523. goto exit;
  23524. }
  23525. if (elemDecl != NULL) {
  23526. int set = 0;
  23527. /*
  23528. * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
  23529. * "The `local type definition` must be validly
  23530. * derived from the {type definition} given the union of
  23531. * the {disallowed substitutions} and the {type definition}'s
  23532. * {prohibited substitutions}, as defined in
  23533. * Type Derivation OK (Complex) ($3.4.6)
  23534. * (if it is a complex type definition),
  23535. * or given {disallowed substitutions} as defined in Type
  23536. * Derivation OK (Simple) ($3.14.6) (if it is a simple type
  23537. * definition)."
  23538. *
  23539. * {disallowed substitutions}: the "block" on the element decl.
  23540. * {prohibited substitutions}: the "block" on the type def.
  23541. */
  23542. /*
  23543. * OPTIMIZE TODO: We could map types already evaluated
  23544. * to be validly derived from other types to avoid checking
  23545. * this over and over for the same types.
  23546. */
  23547. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
  23548. (elemDecl->subtypes->flags &
  23549. XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
  23550. set |= SUBSET_EXTENSION;
  23551. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
  23552. (elemDecl->subtypes->flags &
  23553. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
  23554. set |= SUBSET_RESTRICTION;
  23555. /*
  23556. * REMOVED and CHANGED since this produced a parser context
  23557. * which adds to the string dict of the schema. So this would
  23558. * change the schema and we don't want this. We don't need
  23559. * the parser context anymore.
  23560. *
  23561. * if ((vctxt->pctxt == NULL) &&
  23562. * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  23563. * return (-1);
  23564. */
  23565. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
  23566. elemDecl->subtypes, set) != 0) {
  23567. xmlChar *str = NULL;
  23568. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23569. XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
  23570. "The type definition '%s', specified by xsi:type, is "
  23571. "blocked or not validly derived from the type definition "
  23572. "of the element declaration",
  23573. xmlSchemaFormatQName(&str,
  23574. (*localType)->targetNamespace,
  23575. (*localType)->name),
  23576. NULL);
  23577. FREE_AND_NULL(str);
  23578. ret = vctxt->err;
  23579. *localType = NULL;
  23580. }
  23581. }
  23582. }
  23583. exit:
  23584. ACTIVATE_ELEM;
  23585. return (ret);
  23586. internal_error:
  23587. ACTIVATE_ELEM;
  23588. return (-1);
  23589. }
  23590. static int
  23591. xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
  23592. {
  23593. xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
  23594. xmlSchemaTypePtr actualType;
  23595. /*
  23596. * cvc-elt (3.3.4) : 1
  23597. */
  23598. if (elemDecl == NULL) {
  23599. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
  23600. "No matching declaration available");
  23601. return (vctxt->err);
  23602. }
  23603. actualType = WXS_ELEM_TYPEDEF(elemDecl);
  23604. /*
  23605. * cvc-elt (3.3.4) : 2
  23606. */
  23607. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
  23608. VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
  23609. "The element declaration is abstract");
  23610. return (vctxt->err);
  23611. }
  23612. if (actualType == NULL) {
  23613. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23614. "The type definition is absent");
  23615. return (XML_SCHEMAV_CVC_TYPE_1);
  23616. }
  23617. if (vctxt->nbAttrInfos != 0) {
  23618. int ret;
  23619. xmlSchemaAttrInfoPtr iattr;
  23620. /*
  23621. * cvc-elt (3.3.4) : 3
  23622. * Handle 'xsi:nil'.
  23623. */
  23624. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23625. XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
  23626. if (iattr) {
  23627. ACTIVATE_ATTRIBUTE(iattr);
  23628. /*
  23629. * Validate the value.
  23630. */
  23631. ret = xmlSchemaVCheckCVCSimpleType(
  23632. ACTXT_CAST vctxt, NULL,
  23633. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  23634. iattr->value, &(iattr->val), 1, 0, 0);
  23635. ACTIVATE_ELEM;
  23636. if (ret < 0) {
  23637. VERROR_INT("xmlSchemaValidateElemDecl",
  23638. "calling xmlSchemaVCheckCVCSimpleType() to "
  23639. "validate the attribute 'xsi:nil'");
  23640. return (-1);
  23641. }
  23642. if (ret == 0) {
  23643. if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
  23644. /*
  23645. * cvc-elt (3.3.4) : 3.1
  23646. */
  23647. VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
  23648. "The element is not 'nillable'");
  23649. /* Does not return an error on purpose. */
  23650. } else {
  23651. if (xmlSchemaValueGetAsBoolean(iattr->val)) {
  23652. /*
  23653. * cvc-elt (3.3.4) : 3.2.2
  23654. */
  23655. if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
  23656. (elemDecl->value != NULL)) {
  23657. VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
  23658. "The element cannot be 'nilled' because "
  23659. "there is a fixed value constraint defined "
  23660. "for it");
  23661. /* Does not return an error on purpose. */
  23662. } else
  23663. vctxt->inode->flags |=
  23664. XML_SCHEMA_ELEM_INFO_NILLED;
  23665. }
  23666. }
  23667. }
  23668. }
  23669. /*
  23670. * cvc-elt (3.3.4) : 4
  23671. * Handle 'xsi:type'.
  23672. */
  23673. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23674. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  23675. if (iattr) {
  23676. xmlSchemaTypePtr localType = NULL;
  23677. ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
  23678. elemDecl);
  23679. if (ret != 0) {
  23680. if (ret == -1) {
  23681. VERROR_INT("xmlSchemaValidateElemDecl",
  23682. "calling xmlSchemaProcessXSIType() to "
  23683. "process the attribute 'xsi:type'");
  23684. return (-1);
  23685. }
  23686. /* Does not return an error on purpose. */
  23687. }
  23688. if (localType != NULL) {
  23689. vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
  23690. actualType = localType;
  23691. }
  23692. }
  23693. }
  23694. /*
  23695. * IDC: Register identity-constraint XPath matchers.
  23696. */
  23697. if ((elemDecl->idcs != NULL) &&
  23698. (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
  23699. return (-1);
  23700. /*
  23701. * No actual type definition.
  23702. */
  23703. if (actualType == NULL) {
  23704. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23705. "The type definition is absent");
  23706. return (XML_SCHEMAV_CVC_TYPE_1);
  23707. }
  23708. /*
  23709. * Remember the actual type definition.
  23710. */
  23711. vctxt->inode->typeDef = actualType;
  23712. return (0);
  23713. }
  23714. static int
  23715. xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
  23716. {
  23717. xmlSchemaAttrInfoPtr iattr;
  23718. int ret = 0, i;
  23719. /*
  23720. * SPEC cvc-type (3.1.1)
  23721. * "The attributes of must be empty, excepting those whose namespace
  23722. * name is identical to http://www.w3.org/2001/XMLSchema-instance and
  23723. * whose local name is one of type, nil, schemaLocation or
  23724. * noNamespaceSchemaLocation."
  23725. */
  23726. if (vctxt->nbAttrInfos == 0)
  23727. return (0);
  23728. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23729. iattr = vctxt->attrInfos[i];
  23730. if (! iattr->metaType) {
  23731. ACTIVATE_ATTRIBUTE(iattr)
  23732. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  23733. XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
  23734. ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
  23735. }
  23736. }
  23737. ACTIVATE_ELEM
  23738. return (ret);
  23739. }
  23740. /*
  23741. * Cleanup currently used attribute infos.
  23742. */
  23743. static void
  23744. xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
  23745. {
  23746. int i;
  23747. xmlSchemaAttrInfoPtr attr;
  23748. if (vctxt->nbAttrInfos == 0)
  23749. return;
  23750. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23751. attr = vctxt->attrInfos[i];
  23752. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  23753. if (attr->localName != NULL)
  23754. xmlFree((xmlChar *) attr->localName);
  23755. if (attr->nsName != NULL)
  23756. xmlFree((xmlChar *) attr->nsName);
  23757. }
  23758. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  23759. if (attr->value != NULL)
  23760. xmlFree((xmlChar *) attr->value);
  23761. }
  23762. if (attr->val != NULL) {
  23763. xmlSchemaFreeValue(attr->val);
  23764. attr->val = NULL;
  23765. }
  23766. memset(attr, 0, sizeof(xmlSchemaAttrInfo));
  23767. }
  23768. vctxt->nbAttrInfos = 0;
  23769. }
  23770. /*
  23771. * 3.4.4 Complex Type Definition Validation Rules
  23772. * Element Locally Valid (Complex Type) (cvc-complex-type)
  23773. * 3.2.4 Attribute Declaration Validation Rules
  23774. * Validation Rule: Attribute Locally Valid (cvc-attribute)
  23775. * Attribute Locally Valid (Use) (cvc-au)
  23776. *
  23777. * Only "assessed" attribute information items will be visible to
  23778. * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
  23779. */
  23780. static int
  23781. xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
  23782. {
  23783. xmlSchemaTypePtr type = vctxt->inode->typeDef;
  23784. xmlSchemaItemListPtr attrUseList;
  23785. xmlSchemaAttributeUsePtr attrUse = NULL;
  23786. xmlSchemaAttributePtr attrDecl = NULL;
  23787. xmlSchemaAttrInfoPtr iattr, tmpiattr;
  23788. int i, j, found, nbAttrs, nbUses;
  23789. int xpathRes = 0, res, wildIDs = 0, fixed;
  23790. xmlNodePtr defAttrOwnerElem = NULL;
  23791. /*
  23792. * SPEC (cvc-attribute)
  23793. * (1) "The declaration must not be `absent` (see Missing
  23794. * Sub-components ($5.3) for how this can fail to be
  23795. * the case)."
  23796. * (2) "Its {type definition} must not be absent."
  23797. *
  23798. * NOTE (1) + (2): This is not handled here, since we currently do not
  23799. * allow validation against schemas which have missing sub-components.
  23800. *
  23801. * SPEC (cvc-complex-type)
  23802. * (3) "For each attribute information item in the element information
  23803. * item's [attributes] excepting those whose [namespace name] is
  23804. * identical to http://www.w3.org/2001/XMLSchema-instance and whose
  23805. * [local name] is one of type, nil, schemaLocation or
  23806. * noNamespaceSchemaLocation, the appropriate case among the following
  23807. * must be true:
  23808. *
  23809. */
  23810. attrUseList = (xmlSchemaItemListPtr) type->attrUses;
  23811. /*
  23812. * @nbAttrs is the number of attributes present in the instance.
  23813. */
  23814. nbAttrs = vctxt->nbAttrInfos;
  23815. if (attrUseList != NULL)
  23816. nbUses = attrUseList->nbItems;
  23817. else
  23818. nbUses = 0;
  23819. for (i = 0; i < nbUses; i++) {
  23820. found = 0;
  23821. attrUse = attrUseList->items[i];
  23822. attrDecl = WXS_ATTRUSE_DECL(attrUse);
  23823. for (j = 0; j < nbAttrs; j++) {
  23824. iattr = vctxt->attrInfos[j];
  23825. /*
  23826. * SPEC (cvc-complex-type) (3)
  23827. * Skip meta attributes.
  23828. */
  23829. if (iattr->metaType)
  23830. continue;
  23831. if (iattr->localName[0] != attrDecl->name[0])
  23832. continue;
  23833. if (!xmlStrEqual(iattr->localName, attrDecl->name))
  23834. continue;
  23835. if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
  23836. continue;
  23837. found = 1;
  23838. /*
  23839. * SPEC (cvc-complex-type)
  23840. * (3.1) "If there is among the {attribute uses} an attribute
  23841. * use with an {attribute declaration} whose {name} matches
  23842. * the attribute information item's [local name] and whose
  23843. * {target namespace} is identical to the attribute information
  23844. * item's [namespace name] (where an `absent` {target namespace}
  23845. * is taken to be identical to a [namespace name] with no value),
  23846. * then the attribute information must be `valid` with respect
  23847. * to that attribute use as per Attribute Locally Valid (Use)
  23848. * ($3.5.4). In this case the {attribute declaration} of that
  23849. * attribute use is the `context-determined declaration` for the
  23850. * attribute information item with respect to Schema-Validity
  23851. * Assessment (Attribute) ($3.2.4) and
  23852. * Assessment Outcome (Attribute) ($3.2.5).
  23853. */
  23854. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  23855. iattr->use = attrUse;
  23856. /*
  23857. * Context-determined declaration.
  23858. */
  23859. iattr->decl = attrDecl;
  23860. iattr->typeDef = attrDecl->subtypes;
  23861. break;
  23862. }
  23863. if (found)
  23864. continue;
  23865. if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
  23866. /*
  23867. * Handle non-existent, required attributes.
  23868. *
  23869. * SPEC (cvc-complex-type)
  23870. * (4) "The {attribute declaration} of each attribute use in
  23871. * the {attribute uses} whose {required} is true matches one
  23872. * of the attribute information items in the element information
  23873. * item's [attributes] as per clause 3.1 above."
  23874. */
  23875. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23876. if (tmpiattr == NULL) {
  23877. VERROR_INT(
  23878. "xmlSchemaVAttributesComplex",
  23879. "calling xmlSchemaGetFreshAttrInfo()");
  23880. return (-1);
  23881. }
  23882. tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
  23883. tmpiattr->use = attrUse;
  23884. tmpiattr->decl = attrDecl;
  23885. } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  23886. ((attrUse->defValue != NULL) ||
  23887. (attrDecl->defValue != NULL))) {
  23888. /*
  23889. * Handle non-existent, optional, default/fixed attributes.
  23890. */
  23891. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23892. if (tmpiattr == NULL) {
  23893. VERROR_INT(
  23894. "xmlSchemaVAttributesComplex",
  23895. "calling xmlSchemaGetFreshAttrInfo()");
  23896. return (-1);
  23897. }
  23898. tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
  23899. tmpiattr->use = attrUse;
  23900. tmpiattr->decl = attrDecl;
  23901. tmpiattr->typeDef = attrDecl->subtypes;
  23902. tmpiattr->localName = attrDecl->name;
  23903. tmpiattr->nsName = attrDecl->targetNamespace;
  23904. }
  23905. }
  23906. if (vctxt->nbAttrInfos == 0)
  23907. return (0);
  23908. /*
  23909. * Validate against the wildcard.
  23910. */
  23911. if (type->attributeWildcard != NULL) {
  23912. /*
  23913. * SPEC (cvc-complex-type)
  23914. * (3.2.1) "There must be an {attribute wildcard}."
  23915. */
  23916. for (i = 0; i < nbAttrs; i++) {
  23917. iattr = vctxt->attrInfos[i];
  23918. /*
  23919. * SPEC (cvc-complex-type) (3)
  23920. * Skip meta attributes.
  23921. */
  23922. if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
  23923. continue;
  23924. /*
  23925. * SPEC (cvc-complex-type)
  23926. * (3.2.2) "The attribute information item must be `valid` with
  23927. * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
  23928. *
  23929. * SPEC Item Valid (Wildcard) (cvc-wildcard)
  23930. * "... its [namespace name] must be `valid` with respect to
  23931. * the wildcard constraint, as defined in Wildcard allows
  23932. * Namespace Name ($3.10.4)."
  23933. */
  23934. if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
  23935. iattr->nsName) == 0) {
  23936. /*
  23937. * Handle processContents.
  23938. *
  23939. * SPEC (cvc-wildcard):
  23940. * processContents | context-determined declaration:
  23941. * "strict" "mustFind"
  23942. * "lax" "none"
  23943. * "skip" "skip"
  23944. */
  23945. if (type->attributeWildcard->processContents ==
  23946. XML_SCHEMAS_ANY_SKIP) {
  23947. /*
  23948. * context-determined declaration = "skip"
  23949. *
  23950. * SPEC PSVI Assessment Outcome (Attribute)
  23951. * [validity] = "notKnown"
  23952. * [validation attempted] = "none"
  23953. */
  23954. iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
  23955. continue;
  23956. }
  23957. /*
  23958. * Find an attribute declaration.
  23959. */
  23960. iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
  23961. iattr->localName, iattr->nsName);
  23962. if (iattr->decl != NULL) {
  23963. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  23964. /*
  23965. * SPEC (cvc-complex-type)
  23966. * (5) "Let [Definition:] the wild IDs be the set of
  23967. * all attribute information item to which clause 3.2
  23968. * applied and whose `validation` resulted in a
  23969. * `context-determined declaration` of mustFind or no
  23970. * `context-determined declaration` at all, and whose
  23971. * [local name] and [namespace name] resolve (as
  23972. * defined by QName resolution (Instance) ($3.15.4)) to
  23973. * an attribute declaration whose {type definition} is
  23974. * or is derived from ID. Then all of the following
  23975. * must be true:"
  23976. */
  23977. iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
  23978. if (xmlSchemaIsDerivedFromBuiltInType(
  23979. iattr->typeDef, XML_SCHEMAS_ID)) {
  23980. /*
  23981. * SPEC (5.1) "There must be no more than one
  23982. * item in `wild IDs`."
  23983. */
  23984. if (wildIDs != 0) {
  23985. /* VAL TODO */
  23986. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
  23987. TODO
  23988. continue;
  23989. }
  23990. wildIDs++;
  23991. /*
  23992. * SPEC (cvc-complex-type)
  23993. * (5.2) "If `wild IDs` is non-empty, there must not
  23994. * be any attribute uses among the {attribute uses}
  23995. * whose {attribute declaration}'s {type definition}
  23996. * is or is derived from ID."
  23997. */
  23998. if (attrUseList != NULL) {
  23999. for (j = 0; j < attrUseList->nbItems; j++) {
  24000. if (xmlSchemaIsDerivedFromBuiltInType(
  24001. WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
  24002. XML_SCHEMAS_ID)) {
  24003. /* URGENT VAL TODO: implement */
  24004. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
  24005. TODO
  24006. break;
  24007. }
  24008. }
  24009. }
  24010. }
  24011. } else if (type->attributeWildcard->processContents ==
  24012. XML_SCHEMAS_ANY_LAX) {
  24013. iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
  24014. /*
  24015. * SPEC PSVI Assessment Outcome (Attribute)
  24016. * [validity] = "notKnown"
  24017. * [validation attempted] = "none"
  24018. */
  24019. } else {
  24020. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
  24021. }
  24022. }
  24023. }
  24024. }
  24025. if (vctxt->nbAttrInfos == 0)
  24026. return (0);
  24027. /*
  24028. * Get the owner element; needed for creation of default attributes.
  24029. * This fixes bug #341337, reported by David Grohmann.
  24030. */
  24031. if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
  24032. xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
  24033. if (ielem && ielem->node && ielem->node->doc)
  24034. defAttrOwnerElem = ielem->node;
  24035. }
  24036. /*
  24037. * Validate values, create default attributes, evaluate IDCs.
  24038. */
  24039. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24040. iattr = vctxt->attrInfos[i];
  24041. /*
  24042. * VAL TODO: Note that we won't try to resolve IDCs to
  24043. * "lax" and "skip" validated attributes. Check what to
  24044. * do in this case.
  24045. */
  24046. if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
  24047. (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
  24048. continue;
  24049. /*
  24050. * VAL TODO: What to do if the type definition is missing?
  24051. */
  24052. if (iattr->typeDef == NULL) {
  24053. iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
  24054. continue;
  24055. }
  24056. ACTIVATE_ATTRIBUTE(iattr);
  24057. fixed = 0;
  24058. xpathRes = 0;
  24059. if (vctxt->xpathStates != NULL) {
  24060. /*
  24061. * Evaluate IDCs.
  24062. */
  24063. xpathRes = xmlSchemaXPathEvaluate(vctxt,
  24064. XML_ATTRIBUTE_NODE);
  24065. if (xpathRes == -1) {
  24066. VERROR_INT("xmlSchemaVAttributesComplex",
  24067. "calling xmlSchemaXPathEvaluate()");
  24068. goto internal_error;
  24069. }
  24070. }
  24071. if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
  24072. /*
  24073. * Default/fixed attributes.
  24074. * We need the value only if we need to resolve IDCs or
  24075. * will create default attributes.
  24076. */
  24077. if ((xpathRes) || (defAttrOwnerElem)) {
  24078. if (iattr->use->defValue != NULL) {
  24079. iattr->value = (xmlChar *) iattr->use->defValue;
  24080. iattr->val = iattr->use->defVal;
  24081. } else {
  24082. iattr->value = (xmlChar *) iattr->decl->defValue;
  24083. iattr->val = iattr->decl->defVal;
  24084. }
  24085. /*
  24086. * IDCs will consume the precomputed default value,
  24087. * so we need to clone it.
  24088. */
  24089. if (iattr->val == NULL) {
  24090. VERROR_INT("xmlSchemaVAttributesComplex",
  24091. "default/fixed value on an attribute use was "
  24092. "not precomputed");
  24093. goto internal_error;
  24094. }
  24095. iattr->val = xmlSchemaCopyValue(iattr->val);
  24096. if (iattr->val == NULL) {
  24097. VERROR_INT("xmlSchemaVAttributesComplex",
  24098. "calling xmlSchemaCopyValue()");
  24099. goto internal_error;
  24100. }
  24101. }
  24102. /*
  24103. * PSVI: Add the default attribute to the current element.
  24104. * VAL TODO: Should we use the *normalized* value? This currently
  24105. * uses the *initial* value.
  24106. */
  24107. if (defAttrOwnerElem) {
  24108. xmlChar *normValue;
  24109. const xmlChar *value;
  24110. value = iattr->value;
  24111. /*
  24112. * Normalize the value.
  24113. */
  24114. normValue = xmlSchemaNormalizeValue(iattr->typeDef,
  24115. iattr->value);
  24116. if (normValue != NULL)
  24117. value = BAD_CAST normValue;
  24118. if (iattr->nsName == NULL) {
  24119. if (xmlNewProp(defAttrOwnerElem,
  24120. iattr->localName, value) == NULL) {
  24121. VERROR_INT("xmlSchemaVAttributesComplex",
  24122. "calling xmlNewProp()");
  24123. if (normValue != NULL)
  24124. xmlFree(normValue);
  24125. goto internal_error;
  24126. }
  24127. } else {
  24128. xmlNsPtr ns;
  24129. ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
  24130. defAttrOwnerElem, iattr->nsName);
  24131. if (ns == NULL) {
  24132. xmlChar prefix[12];
  24133. int counter = 0;
  24134. /*
  24135. * Create a namespace declaration on the validation
  24136. * root node if no namespace declaration is in scope.
  24137. */
  24138. do {
  24139. snprintf((char *) prefix, 12, "p%d", counter++);
  24140. ns = xmlSearchNs(defAttrOwnerElem->doc,
  24141. defAttrOwnerElem, BAD_CAST prefix);
  24142. if (counter > 1000) {
  24143. VERROR_INT(
  24144. "xmlSchemaVAttributesComplex",
  24145. "could not compute a ns prefix for a "
  24146. "default/fixed attribute");
  24147. if (normValue != NULL)
  24148. xmlFree(normValue);
  24149. goto internal_error;
  24150. }
  24151. } while (ns != NULL);
  24152. ns = xmlNewNs(vctxt->validationRoot,
  24153. iattr->nsName, BAD_CAST prefix);
  24154. }
  24155. /*
  24156. * TODO:
  24157. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
  24158. * If we have QNames: do we need to ensure there's a
  24159. * prefix defined for the QName?
  24160. */
  24161. xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
  24162. }
  24163. if (normValue != NULL)
  24164. xmlFree(normValue);
  24165. }
  24166. /*
  24167. * Go directly to IDC evaluation.
  24168. */
  24169. goto eval_idcs;
  24170. }
  24171. /*
  24172. * Validate the value.
  24173. */
  24174. if (vctxt->value != NULL) {
  24175. /*
  24176. * Free last computed value; just for safety reasons.
  24177. */
  24178. xmlSchemaFreeValue(vctxt->value);
  24179. vctxt->value = NULL;
  24180. }
  24181. /*
  24182. * Note that the attribute *use* can be unavailable, if
  24183. * the attribute was a wild attribute.
  24184. */
  24185. if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
  24186. ((iattr->use != NULL) &&
  24187. (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
  24188. fixed = 1;
  24189. else
  24190. fixed = 0;
  24191. /*
  24192. * SPEC (cvc-attribute)
  24193. * (3) "The item's `normalized value` must be locally `valid`
  24194. * with respect to that {type definition} as per
  24195. * String Valid ($3.14.4)."
  24196. *
  24197. * VAL TODO: Do we already have the
  24198. * "normalized attribute value" here?
  24199. */
  24200. if (xpathRes || fixed) {
  24201. iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  24202. /*
  24203. * Request a computed value.
  24204. */
  24205. res = xmlSchemaVCheckCVCSimpleType(
  24206. ACTXT_CAST vctxt,
  24207. iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
  24208. 1, 1, 0);
  24209. } else {
  24210. res = xmlSchemaVCheckCVCSimpleType(
  24211. ACTXT_CAST vctxt,
  24212. iattr->node, iattr->typeDef, iattr->value, NULL,
  24213. 1, 0, 0);
  24214. }
  24215. if (res != 0) {
  24216. if (res == -1) {
  24217. VERROR_INT("xmlSchemaVAttributesComplex",
  24218. "calling xmlSchemaStreamValidateSimpleTypeValue()");
  24219. goto internal_error;
  24220. }
  24221. iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
  24222. /*
  24223. * SPEC PSVI Assessment Outcome (Attribute)
  24224. * [validity] = "invalid"
  24225. */
  24226. goto eval_idcs;
  24227. }
  24228. if (fixed) {
  24229. /*
  24230. * SPEC Attribute Locally Valid (Use) (cvc-au)
  24231. * "For an attribute information item to be `valid`
  24232. * with respect to an attribute use its *normalized*
  24233. * value must match the *canonical* lexical
  24234. * representation of the attribute use's {value
  24235. * constraint}value, if it is present and fixed."
  24236. *
  24237. * VAL TODO: The requirement for the *canonical* value
  24238. * will be removed in XML Schema 1.1.
  24239. */
  24240. /*
  24241. * SPEC Attribute Locally Valid (cvc-attribute)
  24242. * (4) "The item's *actual* value must match the *value* of
  24243. * the {value constraint}, if it is present and fixed."
  24244. */
  24245. if (iattr->val == NULL) {
  24246. /* VAL TODO: A value was not precomputed. */
  24247. TODO
  24248. goto eval_idcs;
  24249. }
  24250. if ((iattr->use != NULL) &&
  24251. (iattr->use->defValue != NULL)) {
  24252. if (iattr->use->defVal == NULL) {
  24253. /* VAL TODO: A default value was not precomputed. */
  24254. TODO
  24255. goto eval_idcs;
  24256. }
  24257. iattr->vcValue = iattr->use->defValue;
  24258. /*
  24259. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24260. (xmlSchemaWhitespaceValueType) ws,
  24261. attr->use->defVal,
  24262. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24263. */
  24264. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
  24265. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24266. } else {
  24267. if (iattr->decl->defVal == NULL) {
  24268. /* VAL TODO: A default value was not precomputed. */
  24269. TODO
  24270. goto eval_idcs;
  24271. }
  24272. iattr->vcValue = iattr->decl->defValue;
  24273. /*
  24274. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24275. (xmlSchemaWhitespaceValueType) ws,
  24276. attrDecl->defVal,
  24277. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24278. */
  24279. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
  24280. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24281. }
  24282. /*
  24283. * [validity] = "valid"
  24284. */
  24285. }
  24286. eval_idcs:
  24287. /*
  24288. * Evaluate IDCs.
  24289. */
  24290. if (xpathRes) {
  24291. if (xmlSchemaXPathProcessHistory(vctxt,
  24292. vctxt->depth +1) == -1) {
  24293. VERROR_INT("xmlSchemaVAttributesComplex",
  24294. "calling xmlSchemaXPathEvaluate()");
  24295. goto internal_error;
  24296. }
  24297. } else if (vctxt->xpathStates != NULL)
  24298. xmlSchemaXPathPop(vctxt);
  24299. }
  24300. /*
  24301. * Report errors.
  24302. */
  24303. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24304. iattr = vctxt->attrInfos[i];
  24305. if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
  24306. (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
  24307. (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
  24308. (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
  24309. continue;
  24310. ACTIVATE_ATTRIBUTE(iattr);
  24311. switch (iattr->state) {
  24312. case XML_SCHEMAS_ATTR_ERR_MISSING: {
  24313. xmlChar *str = NULL;
  24314. ACTIVATE_ELEM;
  24315. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24316. XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
  24317. "The attribute '%s' is required but missing",
  24318. xmlSchemaFormatQName(&str,
  24319. iattr->decl->targetNamespace,
  24320. iattr->decl->name),
  24321. NULL);
  24322. FREE_AND_NULL(str)
  24323. break;
  24324. }
  24325. case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
  24326. VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
  24327. "The type definition is absent");
  24328. break;
  24329. case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
  24330. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24331. XML_SCHEMAV_CVC_AU, NULL, NULL,
  24332. "The value '%s' does not match the fixed "
  24333. "value constraint '%s'",
  24334. iattr->value, iattr->vcValue);
  24335. break;
  24336. case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
  24337. VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
  24338. "No matching global attribute declaration available, but "
  24339. "demanded by the strict wildcard");
  24340. break;
  24341. case XML_SCHEMAS_ATTR_UNKNOWN:
  24342. if (iattr->metaType)
  24343. break;
  24344. /*
  24345. * MAYBE VAL TODO: One might report different error messages
  24346. * for the following errors.
  24347. */
  24348. if (type->attributeWildcard == NULL) {
  24349. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24350. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
  24351. } else {
  24352. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24353. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
  24354. }
  24355. break;
  24356. default:
  24357. break;
  24358. }
  24359. }
  24360. ACTIVATE_ELEM;
  24361. return (0);
  24362. internal_error:
  24363. ACTIVATE_ELEM;
  24364. return (-1);
  24365. }
  24366. static int
  24367. xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
  24368. int *skip)
  24369. {
  24370. xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
  24371. /*
  24372. * The namespace of the element was already identified to be
  24373. * matching the wildcard.
  24374. */
  24375. if ((skip == NULL) || (wild == NULL) ||
  24376. (wild->type != XML_SCHEMA_TYPE_ANY)) {
  24377. VERROR_INT("xmlSchemaValidateElemWildcard",
  24378. "bad arguments");
  24379. return (-1);
  24380. }
  24381. *skip = 0;
  24382. if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
  24383. /*
  24384. * URGENT VAL TODO: Either we need to position the stream to the
  24385. * next sibling, or walk the whole subtree.
  24386. */
  24387. *skip = 1;
  24388. return (0);
  24389. }
  24390. {
  24391. xmlSchemaElementPtr decl = NULL;
  24392. decl = xmlSchemaGetElem(vctxt->schema,
  24393. vctxt->inode->localName, vctxt->inode->nsName);
  24394. if (decl != NULL) {
  24395. vctxt->inode->decl = decl;
  24396. return (0);
  24397. }
  24398. }
  24399. if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
  24400. /* VAL TODO: Change to proper error code. */
  24401. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
  24402. "No matching global element declaration available, but "
  24403. "demanded by the strict wildcard");
  24404. return (vctxt->err);
  24405. }
  24406. if (vctxt->nbAttrInfos != 0) {
  24407. xmlSchemaAttrInfoPtr iattr;
  24408. /*
  24409. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24410. * (1.2.1.2.1) - (1.2.1.2.3 )
  24411. *
  24412. * Use the xsi:type attribute for the type definition.
  24413. */
  24414. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  24415. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  24416. if (iattr != NULL) {
  24417. if (xmlSchemaProcessXSIType(vctxt, iattr,
  24418. &(vctxt->inode->typeDef), NULL) == -1) {
  24419. VERROR_INT("xmlSchemaValidateElemWildcard",
  24420. "calling xmlSchemaProcessXSIType() to "
  24421. "process the attribute 'xsi:nil'");
  24422. return (-1);
  24423. }
  24424. /*
  24425. * Don't return an error on purpose.
  24426. */
  24427. return (0);
  24428. }
  24429. }
  24430. /*
  24431. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24432. *
  24433. * Fallback to "anyType".
  24434. */
  24435. vctxt->inode->typeDef =
  24436. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  24437. return (0);
  24438. }
  24439. /*
  24440. * xmlSchemaCheckCOSValidDefault:
  24441. *
  24442. * This will be called if: not nilled, no content and a default/fixed
  24443. * value is provided.
  24444. */
  24445. static int
  24446. xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
  24447. const xmlChar *value,
  24448. xmlSchemaValPtr *val)
  24449. {
  24450. int ret = 0;
  24451. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24452. /*
  24453. * cos-valid-default:
  24454. * Schema Component Constraint: Element Default Valid (Immediate)
  24455. * For a string to be a valid default with respect to a type
  24456. * definition the appropriate case among the following must be true:
  24457. */
  24458. if WXS_IS_COMPLEX(inode->typeDef) {
  24459. /*
  24460. * Complex type.
  24461. *
  24462. * SPEC (2.1) "its {content type} must be a simple type definition
  24463. * or mixed."
  24464. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  24465. * type}'s particle must be `emptiable` as defined by
  24466. * Particle Emptiable ($3.9.6)."
  24467. */
  24468. if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
  24469. ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
  24470. (! WXS_EMPTIABLE(inode->typeDef)))) {
  24471. ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
  24472. /* NOTE that this covers (2.2.2) as well. */
  24473. VERROR(ret, NULL,
  24474. "For a string to be a valid default, the type definition "
  24475. "must be a simple type or a complex type with simple content "
  24476. "or mixed content and a particle emptiable");
  24477. return(ret);
  24478. }
  24479. }
  24480. /*
  24481. * 1 If the type definition is a simple type definition, then the string
  24482. * must be `valid` with respect to that definition as defined by String
  24483. * Valid ($3.14.4).
  24484. *
  24485. * AND
  24486. *
  24487. * 2.2.1 If the {content type} is a simple type definition, then the
  24488. * string must be `valid` with respect to that simple type definition
  24489. * as defined by String Valid ($3.14.4).
  24490. */
  24491. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24492. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24493. NULL, inode->typeDef, value, val, 1, 1, 0);
  24494. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24495. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24496. NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
  24497. }
  24498. if (ret < 0) {
  24499. VERROR_INT("xmlSchemaCheckCOSValidDefault",
  24500. "calling xmlSchemaVCheckCVCSimpleType()");
  24501. }
  24502. return (ret);
  24503. }
  24504. static void
  24505. xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
  24506. const xmlChar * name ATTRIBUTE_UNUSED,
  24507. void *transdata, void *inputdata)
  24508. {
  24509. xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
  24510. xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
  24511. inode->decl = item;
  24512. }
  24513. static int
  24514. xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
  24515. {
  24516. vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
  24517. if (vctxt->inode == NULL) {
  24518. VERROR_INT("xmlSchemaValidatorPushElem",
  24519. "calling xmlSchemaGetFreshElemInfo()");
  24520. return (-1);
  24521. }
  24522. vctxt->nbAttrInfos = 0;
  24523. return (0);
  24524. }
  24525. static int
  24526. xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
  24527. xmlSchemaNodeInfoPtr inode,
  24528. xmlSchemaTypePtr type,
  24529. const xmlChar *value)
  24530. {
  24531. if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
  24532. return (xmlSchemaVCheckCVCSimpleType(
  24533. ACTXT_CAST vctxt, NULL,
  24534. type, value, &(inode->val), 1, 1, 0));
  24535. else
  24536. return (xmlSchemaVCheckCVCSimpleType(
  24537. ACTXT_CAST vctxt, NULL,
  24538. type, value, NULL, 1, 0, 0));
  24539. }
  24540. /*
  24541. * Process END of element.
  24542. */
  24543. static int
  24544. xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
  24545. {
  24546. int ret = 0;
  24547. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24548. if (vctxt->nbAttrInfos != 0)
  24549. xmlSchemaClearAttrInfos(vctxt);
  24550. if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
  24551. /*
  24552. * This element was not expected;
  24553. * we will not validate child elements of broken parents.
  24554. * Skip validation of all content of the parent.
  24555. */
  24556. vctxt->skipDepth = vctxt->depth -1;
  24557. goto end_elem;
  24558. }
  24559. if ((inode->typeDef == NULL) ||
  24560. (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
  24561. /*
  24562. * 1. the type definition might be missing if the element was
  24563. * error prone
  24564. * 2. it might be abstract.
  24565. */
  24566. goto end_elem;
  24567. }
  24568. /*
  24569. * Check the content model.
  24570. */
  24571. if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
  24572. (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
  24573. /*
  24574. * Workaround for "anyType".
  24575. */
  24576. if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
  24577. goto character_content;
  24578. if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
  24579. xmlChar *values[10];
  24580. int terminal, nbval = 10, nbneg;
  24581. if (inode->regexCtxt == NULL) {
  24582. /*
  24583. * Create the regex context.
  24584. */
  24585. inode->regexCtxt =
  24586. xmlRegNewExecCtxt(inode->typeDef->contModel,
  24587. xmlSchemaVContentModelCallback, vctxt);
  24588. if (inode->regexCtxt == NULL) {
  24589. VERROR_INT("xmlSchemaValidatorPopElem",
  24590. "failed to create a regex context");
  24591. goto internal_error;
  24592. }
  24593. }
  24594. /*
  24595. * Do not check further content if the node has been nilled
  24596. */
  24597. if (INODE_NILLED(inode)) {
  24598. ret = 0;
  24599. goto skip_nilled;
  24600. }
  24601. /*
  24602. * Get hold of the still expected content, since a further
  24603. * call to xmlRegExecPushString() will lose this information.
  24604. */
  24605. xmlRegExecNextValues(inode->regexCtxt,
  24606. &nbval, &nbneg, &values[0], &terminal);
  24607. ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
  24608. if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
  24609. /*
  24610. * Still missing something.
  24611. */
  24612. ret = 1;
  24613. inode->flags |=
  24614. XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  24615. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  24616. XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
  24617. "Missing child element(s)",
  24618. nbval, nbneg, values);
  24619. } else {
  24620. /*
  24621. * Content model is satisfied.
  24622. */
  24623. ret = 0;
  24624. }
  24625. }
  24626. }
  24627. skip_nilled:
  24628. if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
  24629. goto end_elem;
  24630. character_content:
  24631. if (vctxt->value != NULL) {
  24632. xmlSchemaFreeValue(vctxt->value);
  24633. vctxt->value = NULL;
  24634. }
  24635. /*
  24636. * Check character content.
  24637. */
  24638. if (inode->decl == NULL) {
  24639. /*
  24640. * Speedup if no declaration exists.
  24641. */
  24642. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24643. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24644. inode, inode->typeDef, inode->value);
  24645. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24646. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24647. inode, inode->typeDef->contentTypeDef,
  24648. inode->value);
  24649. }
  24650. if (ret < 0) {
  24651. VERROR_INT("xmlSchemaValidatorPopElem",
  24652. "calling xmlSchemaVCheckCVCSimpleType()");
  24653. goto internal_error;
  24654. }
  24655. goto end_elem;
  24656. }
  24657. /*
  24658. * cvc-elt (3.3.4) : 5
  24659. * The appropriate case among the following must be true:
  24660. */
  24661. /*
  24662. * cvc-elt (3.3.4) : 5.1
  24663. * If the declaration has a {value constraint},
  24664. * the item has neither element nor character [children] and
  24665. * clause 3.2 has not applied, then all of the following must be true:
  24666. */
  24667. if ((inode->decl->value != NULL) &&
  24668. (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
  24669. (! INODE_NILLED(inode))) {
  24670. /*
  24671. * cvc-elt (3.3.4) : 5.1.1
  24672. * If the `actual type definition` is a `local type definition`
  24673. * then the canonical lexical representation of the {value constraint}
  24674. * value must be a valid default for the `actual type definition` as
  24675. * defined in Element Default Valid (Immediate) ($3.3.6).
  24676. */
  24677. /*
  24678. * NOTE: 'local' above means types acquired by xsi:type.
  24679. * NOTE: Although the *canonical* value is stated, it is not
  24680. * relevant if canonical or not. Additionally XML Schema 1.1
  24681. * will removed this requirement as well.
  24682. */
  24683. if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
  24684. ret = xmlSchemaCheckCOSValidDefault(vctxt,
  24685. inode->decl->value, &(inode->val));
  24686. if (ret != 0) {
  24687. if (ret < 0) {
  24688. VERROR_INT("xmlSchemaValidatorPopElem",
  24689. "calling xmlSchemaCheckCOSValidDefault()");
  24690. goto internal_error;
  24691. }
  24692. goto end_elem;
  24693. }
  24694. /*
  24695. * Stop here, to avoid redundant validation of the value
  24696. * (see following).
  24697. */
  24698. goto default_psvi;
  24699. }
  24700. /*
  24701. * cvc-elt (3.3.4) : 5.1.2
  24702. * The element information item with the canonical lexical
  24703. * representation of the {value constraint} value used as its
  24704. * `normalized value` must be `valid` with respect to the
  24705. * `actual type definition` as defined by Element Locally Valid (Type)
  24706. * ($3.3.4).
  24707. */
  24708. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24709. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24710. inode, inode->typeDef, inode->decl->value);
  24711. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24712. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24713. inode, inode->typeDef->contentTypeDef,
  24714. inode->decl->value);
  24715. }
  24716. if (ret != 0) {
  24717. if (ret < 0) {
  24718. VERROR_INT("xmlSchemaValidatorPopElem",
  24719. "calling xmlSchemaVCheckCVCSimpleType()");
  24720. goto internal_error;
  24721. }
  24722. goto end_elem;
  24723. }
  24724. default_psvi:
  24725. /*
  24726. * PSVI: Create a text node on the instance element.
  24727. */
  24728. if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
  24729. (inode->node != NULL)) {
  24730. xmlNodePtr textChild;
  24731. xmlChar *normValue;
  24732. /*
  24733. * VAL TODO: Normalize the value.
  24734. */
  24735. normValue = xmlSchemaNormalizeValue(inode->typeDef,
  24736. inode->decl->value);
  24737. if (normValue != NULL) {
  24738. textChild = xmlNewDocText(inode->node->doc,
  24739. BAD_CAST normValue);
  24740. xmlFree(normValue);
  24741. } else
  24742. textChild = xmlNewDocText(inode->node->doc,
  24743. inode->decl->value);
  24744. if (textChild == NULL) {
  24745. VERROR_INT("xmlSchemaValidatorPopElem",
  24746. "calling xmlNewDocText()");
  24747. goto internal_error;
  24748. } else
  24749. xmlAddChild(inode->node, textChild);
  24750. }
  24751. } else if (! INODE_NILLED(inode)) {
  24752. /*
  24753. * 5.2.1 The element information item must be `valid` with respect
  24754. * to the `actual type definition` as defined by Element Locally
  24755. * Valid (Type) ($3.3.4).
  24756. */
  24757. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24758. /*
  24759. * SPEC (cvc-type) (3.1)
  24760. * "If the type definition is a simple type definition, ..."
  24761. * (3.1.3) "If clause 3.2 of Element Locally Valid
  24762. * (Element) ($3.3.4) did not apply, then the `normalized value`
  24763. * must be `valid` with respect to the type definition as defined
  24764. * by String Valid ($3.14.4).
  24765. */
  24766. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24767. inode, inode->typeDef, inode->value);
  24768. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24769. /*
  24770. * SPEC (cvc-type) (3.2) "If the type definition is a complex type
  24771. * definition, then the element information item must be
  24772. * `valid` with respect to the type definition as per
  24773. * Element Locally Valid (Complex Type) ($3.4.4);"
  24774. *
  24775. * SPEC (cvc-complex-type) (2.2)
  24776. * "If the {content type} is a simple type definition, ...
  24777. * the `normalized value` of the element information item is
  24778. * `valid` with respect to that simple type definition as
  24779. * defined by String Valid ($3.14.4)."
  24780. */
  24781. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24782. inode, inode->typeDef->contentTypeDef, inode->value);
  24783. }
  24784. if (ret != 0) {
  24785. if (ret < 0) {
  24786. VERROR_INT("xmlSchemaValidatorPopElem",
  24787. "calling xmlSchemaVCheckCVCSimpleType()");
  24788. goto internal_error;
  24789. }
  24790. goto end_elem;
  24791. }
  24792. /*
  24793. * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
  24794. * not applied, all of the following must be true:
  24795. */
  24796. if ((inode->decl->value != NULL) &&
  24797. (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
  24798. /*
  24799. * TODO: We will need a computed value, when comparison is
  24800. * done on computed values.
  24801. */
  24802. /*
  24803. * 5.2.2.1 The element information item must have no element
  24804. * information item [children].
  24805. */
  24806. if (inode->flags &
  24807. XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
  24808. ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
  24809. VERROR(ret, NULL,
  24810. "The content must not contain element nodes since "
  24811. "there is a fixed value constraint");
  24812. goto end_elem;
  24813. } else {
  24814. /*
  24815. * 5.2.2.2 The appropriate case among the following must
  24816. * be true:
  24817. */
  24818. if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
  24819. /*
  24820. * 5.2.2.2.1 If the {content type} of the `actual type
  24821. * definition` is mixed, then the *initial value* of the
  24822. * item must match the canonical lexical representation
  24823. * of the {value constraint} value.
  24824. *
  24825. * ... the *initial value* of an element information
  24826. * item is the string composed of, in order, the
  24827. * [character code] of each character information item in
  24828. * the [children] of that element information item.
  24829. */
  24830. if (! xmlStrEqual(inode->value, inode->decl->value)){
  24831. /*
  24832. * VAL TODO: Report invalid & expected values as well.
  24833. * VAL TODO: Implement the canonical stuff.
  24834. */
  24835. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
  24836. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24837. ret, NULL, NULL,
  24838. "The initial value '%s' does not match the fixed "
  24839. "value constraint '%s'",
  24840. inode->value, inode->decl->value);
  24841. goto end_elem;
  24842. }
  24843. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24844. /*
  24845. * 5.2.2.2.2 If the {content type} of the `actual type
  24846. * definition` is a simple type definition, then the
  24847. * *actual value* of the item must match the canonical
  24848. * lexical representation of the {value constraint} value.
  24849. */
  24850. /*
  24851. * VAL TODO: *actual value* is the normalized value, impl.
  24852. * this.
  24853. * VAL TODO: Report invalid & expected values as well.
  24854. * VAL TODO: Implement a comparison with the computed values.
  24855. */
  24856. if (! xmlStrEqual(inode->value,
  24857. inode->decl->value)) {
  24858. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
  24859. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24860. ret, NULL, NULL,
  24861. "The actual value '%s' does not match the fixed "
  24862. "value constraint '%s'",
  24863. inode->value,
  24864. inode->decl->value);
  24865. goto end_elem;
  24866. }
  24867. }
  24868. }
  24869. }
  24870. }
  24871. end_elem:
  24872. if (vctxt->depth < 0) {
  24873. /* TODO: raise error? */
  24874. return (0);
  24875. }
  24876. if (vctxt->depth == vctxt->skipDepth)
  24877. vctxt->skipDepth = -1;
  24878. /*
  24879. * Evaluate the history of XPath state objects.
  24880. */
  24881. if (inode->appliedXPath &&
  24882. (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
  24883. goto internal_error;
  24884. /*
  24885. * MAYBE TODO:
  24886. * SPEC (6) "The element information item must be `valid` with
  24887. * respect to each of the {identity-constraint definitions} as per
  24888. * Identity-constraint Satisfied ($3.11.4)."
  24889. */
  24890. /*
  24891. * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
  24892. * need to be built in any case.
  24893. * We will currently build IDC node-tables and bubble them only if
  24894. * keyrefs do exist.
  24895. */
  24896. /*
  24897. * Add the current IDC target-nodes to the IDC node-tables.
  24898. */
  24899. if ((inode->idcMatchers != NULL) &&
  24900. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  24901. {
  24902. if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
  24903. goto internal_error;
  24904. }
  24905. /*
  24906. * Validate IDC keyrefs.
  24907. */
  24908. if (vctxt->inode->hasKeyrefs)
  24909. if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
  24910. goto internal_error;
  24911. /*
  24912. * Merge/free the IDC table.
  24913. */
  24914. if (inode->idcTable != NULL) {
  24915. if ((vctxt->depth > 0) &&
  24916. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  24917. {
  24918. /*
  24919. * Merge the IDC node table with the table of the parent node.
  24920. */
  24921. if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
  24922. goto internal_error;
  24923. }
  24924. }
  24925. /*
  24926. * Clear the current ielem.
  24927. * VAL TODO: Don't free the PSVI IDC tables if they are
  24928. * requested for the PSVI.
  24929. */
  24930. xmlSchemaClearElemInfo(vctxt, inode);
  24931. /*
  24932. * Skip further processing if we are on the validation root.
  24933. */
  24934. if (vctxt->depth == 0) {
  24935. vctxt->depth--;
  24936. vctxt->inode = NULL;
  24937. return (0);
  24938. }
  24939. /*
  24940. * Reset the keyrefDepth if needed.
  24941. */
  24942. if (vctxt->aidcs != NULL) {
  24943. xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
  24944. do {
  24945. if (aidc->keyrefDepth == vctxt->depth) {
  24946. /*
  24947. * A 'keyrefDepth' of a key/unique IDC matches the current
  24948. * depth, this means that we are leaving the scope of the
  24949. * top-most keyref IDC which refers to this IDC.
  24950. */
  24951. aidc->keyrefDepth = -1;
  24952. }
  24953. aidc = aidc->next;
  24954. } while (aidc != NULL);
  24955. }
  24956. vctxt->depth--;
  24957. vctxt->inode = vctxt->elemInfos[vctxt->depth];
  24958. /*
  24959. * VAL TODO: 7 If the element information item is the `validation root`, it must be
  24960. * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
  24961. */
  24962. return (ret);
  24963. internal_error:
  24964. vctxt->err = -1;
  24965. return (-1);
  24966. }
  24967. /*
  24968. * 3.4.4 Complex Type Definition Validation Rules
  24969. * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
  24970. */
  24971. static int
  24972. xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
  24973. {
  24974. xmlSchemaNodeInfoPtr pielem;
  24975. xmlSchemaTypePtr ptype;
  24976. int ret = 0;
  24977. if (vctxt->depth <= 0) {
  24978. VERROR_INT("xmlSchemaValidateChildElem",
  24979. "not intended for the validation root");
  24980. return (-1);
  24981. }
  24982. pielem = vctxt->elemInfos[vctxt->depth -1];
  24983. if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  24984. pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  24985. /*
  24986. * Handle 'nilled' elements.
  24987. */
  24988. if (INODE_NILLED(pielem)) {
  24989. /*
  24990. * SPEC (cvc-elt) (3.3.4) : (3.2.1)
  24991. */
  24992. ACTIVATE_PARENT_ELEM;
  24993. ret = XML_SCHEMAV_CVC_ELT_3_2_1;
  24994. VERROR(ret, NULL,
  24995. "Neither character nor element content is allowed, "
  24996. "because the element was 'nilled'");
  24997. ACTIVATE_ELEM;
  24998. goto unexpected_elem;
  24999. }
  25000. ptype = pielem->typeDef;
  25001. if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
  25002. /*
  25003. * Workaround for "anyType": we have currently no content model
  25004. * assigned for "anyType", so handle it explicitly.
  25005. * "anyType" has an unbounded, lax "any" wildcard.
  25006. */
  25007. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25008. vctxt->inode->localName,
  25009. vctxt->inode->nsName);
  25010. if (vctxt->inode->decl == NULL) {
  25011. xmlSchemaAttrInfoPtr iattr;
  25012. /*
  25013. * Process "xsi:type".
  25014. * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
  25015. */
  25016. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  25017. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  25018. if (iattr != NULL) {
  25019. ret = xmlSchemaProcessXSIType(vctxt, iattr,
  25020. &(vctxt->inode->typeDef), NULL);
  25021. if (ret != 0) {
  25022. if (ret == -1) {
  25023. VERROR_INT("xmlSchemaValidateChildElem",
  25024. "calling xmlSchemaProcessXSIType() to "
  25025. "process the attribute 'xsi:nil'");
  25026. return (-1);
  25027. }
  25028. return (ret);
  25029. }
  25030. } else {
  25031. /*
  25032. * Fallback to "anyType".
  25033. *
  25034. * SPEC (cvc-assess-elt)
  25035. * "If the item cannot be `strictly assessed`, [...]
  25036. * an element information item's schema validity may be laxly
  25037. * assessed if its `context-determined declaration` is not
  25038. * skip by `validating` with respect to the `ur-type
  25039. * definition` as per Element Locally Valid (Type) ($3.3.4)."
  25040. */
  25041. vctxt->inode->typeDef =
  25042. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  25043. }
  25044. }
  25045. return (0);
  25046. }
  25047. switch (ptype->contentType) {
  25048. case XML_SCHEMA_CONTENT_EMPTY:
  25049. /*
  25050. * SPEC (2.1) "If the {content type} is empty, then the
  25051. * element information item has no character or element
  25052. * information item [children]."
  25053. */
  25054. ACTIVATE_PARENT_ELEM
  25055. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
  25056. VERROR(ret, NULL,
  25057. "Element content is not allowed, "
  25058. "because the content type is empty");
  25059. ACTIVATE_ELEM
  25060. goto unexpected_elem;
  25061. break;
  25062. case XML_SCHEMA_CONTENT_MIXED:
  25063. case XML_SCHEMA_CONTENT_ELEMENTS: {
  25064. xmlRegExecCtxtPtr regexCtxt;
  25065. xmlChar *values[10];
  25066. int terminal, nbval = 10, nbneg;
  25067. /* VAL TODO: Optimized "anyType" validation.*/
  25068. if (ptype->contModel == NULL) {
  25069. VERROR_INT("xmlSchemaValidateChildElem",
  25070. "type has elem content but no content model");
  25071. return (-1);
  25072. }
  25073. /*
  25074. * Safety belt for evaluation if the cont. model was already
  25075. * examined to be invalid.
  25076. */
  25077. if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
  25078. VERROR_INT("xmlSchemaValidateChildElem",
  25079. "validating elem, but elem content is already invalid");
  25080. return (-1);
  25081. }
  25082. regexCtxt = pielem->regexCtxt;
  25083. if (regexCtxt == NULL) {
  25084. /*
  25085. * Create the regex context.
  25086. */
  25087. regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
  25088. xmlSchemaVContentModelCallback, vctxt);
  25089. if (regexCtxt == NULL) {
  25090. VERROR_INT("xmlSchemaValidateChildElem",
  25091. "failed to create a regex context");
  25092. return (-1);
  25093. }
  25094. pielem->regexCtxt = regexCtxt;
  25095. }
  25096. /*
  25097. * SPEC (2.4) "If the {content type} is element-only or mixed,
  25098. * then the sequence of the element information item's
  25099. * element information item [children], if any, taken in
  25100. * order, is `valid` with respect to the {content type}'s
  25101. * particle, as defined in Element Sequence Locally Valid
  25102. * (Particle) ($3.9.4)."
  25103. */
  25104. ret = xmlRegExecPushString2(regexCtxt,
  25105. vctxt->inode->localName,
  25106. vctxt->inode->nsName,
  25107. vctxt->inode);
  25108. if (vctxt->err == XML_SCHEMAV_INTERNAL) {
  25109. VERROR_INT("xmlSchemaValidateChildElem",
  25110. "calling xmlRegExecPushString2()");
  25111. return (-1);
  25112. }
  25113. if (ret < 0) {
  25114. xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
  25115. &values[0], &terminal);
  25116. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  25117. XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
  25118. "This element is not expected",
  25119. nbval, nbneg, values);
  25120. ret = vctxt->err;
  25121. goto unexpected_elem;
  25122. } else
  25123. ret = 0;
  25124. }
  25125. break;
  25126. case XML_SCHEMA_CONTENT_SIMPLE:
  25127. case XML_SCHEMA_CONTENT_BASIC:
  25128. ACTIVATE_PARENT_ELEM
  25129. if (WXS_IS_COMPLEX(ptype)) {
  25130. /*
  25131. * SPEC (cvc-complex-type) (2.2)
  25132. * "If the {content type} is a simple type definition, then
  25133. * the element information item has no element information
  25134. * item [children], ..."
  25135. */
  25136. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
  25137. VERROR(ret, NULL, "Element content is not allowed, "
  25138. "because the content type is a simple type definition");
  25139. } else {
  25140. /*
  25141. * SPEC (cvc-type) (3.1.2) "The element information item must
  25142. * have no element information item [children]."
  25143. */
  25144. ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
  25145. VERROR(ret, NULL, "Element content is not allowed, "
  25146. "because the type definition is simple");
  25147. }
  25148. ACTIVATE_ELEM
  25149. ret = vctxt->err;
  25150. goto unexpected_elem;
  25151. break;
  25152. default:
  25153. break;
  25154. }
  25155. return (ret);
  25156. unexpected_elem:
  25157. /*
  25158. * Pop this element and set the skipDepth to skip
  25159. * all further content of the parent element.
  25160. */
  25161. vctxt->skipDepth = vctxt->depth;
  25162. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
  25163. pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  25164. return (ret);
  25165. }
  25166. #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
  25167. #define XML_SCHEMA_PUSH_TEXT_CREATED 2
  25168. #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
  25169. static int
  25170. xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
  25171. int nodeType, const xmlChar *value, int len,
  25172. int mode, int *consumed)
  25173. {
  25174. /*
  25175. * Unfortunately we have to duplicate the text sometimes.
  25176. * OPTIMIZE: Maybe we could skip it, if:
  25177. * 1. content type is simple
  25178. * 2. whitespace is "collapse"
  25179. * 3. it consists of whitespace only
  25180. *
  25181. * Process character content.
  25182. */
  25183. if (consumed != NULL)
  25184. *consumed = 0;
  25185. if (INODE_NILLED(vctxt->inode)) {
  25186. /*
  25187. * SPEC cvc-elt (3.3.4 - 3.2.1)
  25188. * "The element information item must have no character or
  25189. * element information item [children]."
  25190. */
  25191. VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
  25192. "Neither character nor element content is allowed "
  25193. "because the element is 'nilled'");
  25194. return (vctxt->err);
  25195. }
  25196. /*
  25197. * SPEC (2.1) "If the {content type} is empty, then the
  25198. * element information item has no character or element
  25199. * information item [children]."
  25200. */
  25201. if (vctxt->inode->typeDef->contentType ==
  25202. XML_SCHEMA_CONTENT_EMPTY) {
  25203. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
  25204. "Character content is not allowed, "
  25205. "because the content type is empty");
  25206. return (vctxt->err);
  25207. }
  25208. if (vctxt->inode->typeDef->contentType ==
  25209. XML_SCHEMA_CONTENT_ELEMENTS) {
  25210. if ((nodeType != XML_TEXT_NODE) ||
  25211. (! xmlSchemaIsBlank((xmlChar *) value, len))) {
  25212. /*
  25213. * SPEC cvc-complex-type (2.3)
  25214. * "If the {content type} is element-only, then the
  25215. * element information item has no character information
  25216. * item [children] other than those whose [character
  25217. * code] is defined as a white space in [XML 1.0 (Second
  25218. * Edition)]."
  25219. */
  25220. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
  25221. "Character content other than whitespace is not allowed "
  25222. "because the content type is 'element-only'");
  25223. return (vctxt->err);
  25224. }
  25225. return (0);
  25226. }
  25227. if ((value == NULL) || (value[0] == 0))
  25228. return (0);
  25229. /*
  25230. * Save the value.
  25231. * NOTE that even if the content type is *mixed*, we need the
  25232. * *initial value* for default/fixed value constraints.
  25233. */
  25234. if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  25235. ((vctxt->inode->decl == NULL) ||
  25236. (vctxt->inode->decl->value == NULL)))
  25237. return (0);
  25238. if (vctxt->inode->value == NULL) {
  25239. /*
  25240. * Set the value.
  25241. */
  25242. switch (mode) {
  25243. case XML_SCHEMA_PUSH_TEXT_PERSIST:
  25244. /*
  25245. * When working on a tree.
  25246. */
  25247. vctxt->inode->value = value;
  25248. break;
  25249. case XML_SCHEMA_PUSH_TEXT_CREATED:
  25250. /*
  25251. * When working with the reader.
  25252. * The value will be freed by the element info.
  25253. */
  25254. vctxt->inode->value = value;
  25255. if (consumed != NULL)
  25256. *consumed = 1;
  25257. vctxt->inode->flags |=
  25258. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25259. break;
  25260. case XML_SCHEMA_PUSH_TEXT_VOLATILE:
  25261. /*
  25262. * When working with SAX.
  25263. * The value will be freed by the element info.
  25264. */
  25265. if (len != -1)
  25266. vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
  25267. else
  25268. vctxt->inode->value = BAD_CAST xmlStrdup(value);
  25269. vctxt->inode->flags |=
  25270. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25271. break;
  25272. default:
  25273. break;
  25274. }
  25275. } else {
  25276. if (len < 0)
  25277. len = xmlStrlen(value);
  25278. /*
  25279. * Concat the value.
  25280. */
  25281. if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  25282. vctxt->inode->value = BAD_CAST xmlStrncat(
  25283. (xmlChar *) vctxt->inode->value, value, len);
  25284. } else {
  25285. vctxt->inode->value =
  25286. BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
  25287. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25288. }
  25289. }
  25290. return (0);
  25291. }
  25292. static int
  25293. xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
  25294. {
  25295. int ret = 0;
  25296. if ((vctxt->skipDepth != -1) &&
  25297. (vctxt->depth >= vctxt->skipDepth)) {
  25298. VERROR_INT("xmlSchemaValidateElem",
  25299. "in skip-state");
  25300. goto internal_error;
  25301. }
  25302. if (vctxt->xsiAssemble) {
  25303. /*
  25304. * We will stop validation if there was an error during
  25305. * dynamic schema construction.
  25306. * Note that we simply set @skipDepth to 0, this could
  25307. * mean that a streaming document via SAX would be
  25308. * still read to the end but it won't be validated any more.
  25309. * TODO: If we are sure how to stop the validation at once
  25310. * for all input scenarios, then this should be changed to
  25311. * instantly stop the validation.
  25312. */
  25313. ret = xmlSchemaAssembleByXSI(vctxt);
  25314. if (ret != 0) {
  25315. if (ret == -1)
  25316. goto internal_error;
  25317. vctxt->skipDepth = 0;
  25318. return(ret);
  25319. }
  25320. /*
  25321. * Augment the IDC definitions for the main schema and all imported ones
  25322. * NOTE: main schema is the first in the imported list
  25323. */
  25324. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  25325. vctxt);
  25326. }
  25327. if (vctxt->depth > 0) {
  25328. /*
  25329. * Validate this element against the content model
  25330. * of the parent.
  25331. */
  25332. ret = xmlSchemaValidateChildElem(vctxt);
  25333. if (ret != 0) {
  25334. if (ret < 0) {
  25335. VERROR_INT("xmlSchemaValidateElem",
  25336. "calling xmlSchemaStreamValidateChildElement()");
  25337. goto internal_error;
  25338. }
  25339. goto exit;
  25340. }
  25341. if (vctxt->depth == vctxt->skipDepth)
  25342. goto exit;
  25343. if ((vctxt->inode->decl == NULL) &&
  25344. (vctxt->inode->typeDef == NULL)) {
  25345. VERROR_INT("xmlSchemaValidateElem",
  25346. "the child element was valid but neither the "
  25347. "declaration nor the type was set");
  25348. goto internal_error;
  25349. }
  25350. } else {
  25351. /*
  25352. * Get the declaration of the validation root.
  25353. */
  25354. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25355. vctxt->inode->localName,
  25356. vctxt->inode->nsName);
  25357. if (vctxt->inode->decl == NULL) {
  25358. ret = XML_SCHEMAV_CVC_ELT_1;
  25359. VERROR(ret, NULL,
  25360. "No matching global declaration available "
  25361. "for the validation root");
  25362. goto exit;
  25363. }
  25364. }
  25365. if (vctxt->inode->decl == NULL)
  25366. goto type_validation;
  25367. if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
  25368. int skip;
  25369. /*
  25370. * Wildcards.
  25371. */
  25372. ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
  25373. if (ret != 0) {
  25374. if (ret < 0) {
  25375. VERROR_INT("xmlSchemaValidateElem",
  25376. "calling xmlSchemaValidateElemWildcard()");
  25377. goto internal_error;
  25378. }
  25379. goto exit;
  25380. }
  25381. if (skip) {
  25382. vctxt->skipDepth = vctxt->depth;
  25383. goto exit;
  25384. }
  25385. /*
  25386. * The declaration might be set by the wildcard validation,
  25387. * when the processContents is "lax" or "strict".
  25388. */
  25389. if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
  25390. /*
  25391. * Clear the "decl" field to not confuse further processing.
  25392. */
  25393. vctxt->inode->decl = NULL;
  25394. goto type_validation;
  25395. }
  25396. }
  25397. /*
  25398. * Validate against the declaration.
  25399. */
  25400. ret = xmlSchemaValidateElemDecl(vctxt);
  25401. if (ret != 0) {
  25402. if (ret < 0) {
  25403. VERROR_INT("xmlSchemaValidateElem",
  25404. "calling xmlSchemaValidateElemDecl()");
  25405. goto internal_error;
  25406. }
  25407. goto exit;
  25408. }
  25409. /*
  25410. * Validate against the type definition.
  25411. */
  25412. type_validation:
  25413. if (vctxt->inode->typeDef == NULL) {
  25414. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25415. ret = XML_SCHEMAV_CVC_TYPE_1;
  25416. VERROR(ret, NULL,
  25417. "The type definition is absent");
  25418. goto exit;
  25419. }
  25420. if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
  25421. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25422. ret = XML_SCHEMAV_CVC_TYPE_2;
  25423. VERROR(ret, NULL,
  25424. "The type definition is abstract");
  25425. goto exit;
  25426. }
  25427. /*
  25428. * Evaluate IDCs. Do it here, since new IDC matchers are registered
  25429. * during validation against the declaration. This must be done
  25430. * _before_ attribute validation.
  25431. */
  25432. if (vctxt->xpathStates != NULL) {
  25433. ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
  25434. vctxt->inode->appliedXPath = 1;
  25435. if (ret == -1) {
  25436. VERROR_INT("xmlSchemaValidateElem",
  25437. "calling xmlSchemaXPathEvaluate()");
  25438. goto internal_error;
  25439. }
  25440. }
  25441. /*
  25442. * Validate attributes.
  25443. */
  25444. if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
  25445. if ((vctxt->nbAttrInfos != 0) ||
  25446. (vctxt->inode->typeDef->attrUses != NULL)) {
  25447. ret = xmlSchemaVAttributesComplex(vctxt);
  25448. }
  25449. } else if (vctxt->nbAttrInfos != 0) {
  25450. ret = xmlSchemaVAttributesSimple(vctxt);
  25451. }
  25452. /*
  25453. * Clear registered attributes.
  25454. */
  25455. if (vctxt->nbAttrInfos != 0)
  25456. xmlSchemaClearAttrInfos(vctxt);
  25457. if (ret == -1) {
  25458. VERROR_INT("xmlSchemaValidateElem",
  25459. "calling attributes validation");
  25460. goto internal_error;
  25461. }
  25462. /*
  25463. * Don't return an error if attributes are invalid on purpose.
  25464. */
  25465. ret = 0;
  25466. exit:
  25467. if (ret != 0)
  25468. vctxt->skipDepth = vctxt->depth;
  25469. return (ret);
  25470. internal_error:
  25471. return (-1);
  25472. }
  25473. #ifdef XML_SCHEMA_READER_ENABLED
  25474. static int
  25475. xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
  25476. {
  25477. const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
  25478. int depth, nodeType, ret = 0, consumed;
  25479. xmlSchemaNodeInfoPtr ielem;
  25480. vctxt->depth = -1;
  25481. ret = xmlTextReaderRead(vctxt->reader);
  25482. /*
  25483. * Move to the document element.
  25484. */
  25485. while (ret == 1) {
  25486. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25487. if (nodeType == XML_ELEMENT_NODE)
  25488. goto root_found;
  25489. ret = xmlTextReaderRead(vctxt->reader);
  25490. }
  25491. goto exit;
  25492. root_found:
  25493. do {
  25494. depth = xmlTextReaderDepth(vctxt->reader);
  25495. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25496. if (nodeType == XML_ELEMENT_NODE) {
  25497. vctxt->depth++;
  25498. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25499. VERROR_INT("xmlSchemaVReaderWalk",
  25500. "calling xmlSchemaValidatorPushElem()");
  25501. goto internal_error;
  25502. }
  25503. ielem = vctxt->inode;
  25504. ielem->localName = xmlTextReaderLocalName(vctxt->reader);
  25505. ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
  25506. ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  25507. /*
  25508. * Is the element empty?
  25509. */
  25510. ret = xmlTextReaderIsEmptyElement(vctxt->reader);
  25511. if (ret == -1) {
  25512. VERROR_INT("xmlSchemaVReaderWalk",
  25513. "calling xmlTextReaderIsEmptyElement()");
  25514. goto internal_error;
  25515. }
  25516. if (ret) {
  25517. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25518. }
  25519. /*
  25520. * Register attributes.
  25521. */
  25522. vctxt->nbAttrInfos = 0;
  25523. ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
  25524. if (ret == -1) {
  25525. VERROR_INT("xmlSchemaVReaderWalk",
  25526. "calling xmlTextReaderMoveToFirstAttribute()");
  25527. goto internal_error;
  25528. }
  25529. if (ret == 1) {
  25530. do {
  25531. /*
  25532. * VAL TODO: How do we know that the reader works on a
  25533. * node tree, to be able to pass a node here?
  25534. */
  25535. if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
  25536. (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
  25537. xmlTextReaderNamespaceUri(vctxt->reader), 1,
  25538. xmlTextReaderValue(vctxt->reader), 1) == -1) {
  25539. VERROR_INT("xmlSchemaVReaderWalk",
  25540. "calling xmlSchemaValidatorPushAttribute()");
  25541. goto internal_error;
  25542. }
  25543. ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
  25544. if (ret == -1) {
  25545. VERROR_INT("xmlSchemaVReaderWalk",
  25546. "calling xmlTextReaderMoveToFirstAttribute()");
  25547. goto internal_error;
  25548. }
  25549. } while (ret == 1);
  25550. /*
  25551. * Back to element position.
  25552. */
  25553. ret = xmlTextReaderMoveToElement(vctxt->reader);
  25554. if (ret == -1) {
  25555. VERROR_INT("xmlSchemaVReaderWalk",
  25556. "calling xmlTextReaderMoveToElement()");
  25557. goto internal_error;
  25558. }
  25559. }
  25560. /*
  25561. * Validate the element.
  25562. */
  25563. ret= xmlSchemaValidateElem(vctxt);
  25564. if (ret != 0) {
  25565. if (ret == -1) {
  25566. VERROR_INT("xmlSchemaVReaderWalk",
  25567. "calling xmlSchemaValidateElem()");
  25568. goto internal_error;
  25569. }
  25570. goto exit;
  25571. }
  25572. if (vctxt->depth == vctxt->skipDepth) {
  25573. int curDepth;
  25574. /*
  25575. * Skip all content.
  25576. */
  25577. if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
  25578. ret = xmlTextReaderRead(vctxt->reader);
  25579. curDepth = xmlTextReaderDepth(vctxt->reader);
  25580. while ((ret == 1) && (curDepth != depth)) {
  25581. ret = xmlTextReaderRead(vctxt->reader);
  25582. curDepth = xmlTextReaderDepth(vctxt->reader);
  25583. }
  25584. if (ret < 0) {
  25585. /*
  25586. * VAL TODO: A reader error occurred; what to do here?
  25587. */
  25588. ret = 1;
  25589. goto exit;
  25590. }
  25591. }
  25592. goto leave_elem;
  25593. }
  25594. /*
  25595. * READER VAL TODO: Is an END_ELEM really never called
  25596. * if the elem is empty?
  25597. */
  25598. if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25599. goto leave_elem;
  25600. } else if (nodeType == END_ELEM) {
  25601. /*
  25602. * Process END of element.
  25603. */
  25604. leave_elem:
  25605. ret = xmlSchemaValidatorPopElem(vctxt);
  25606. if (ret != 0) {
  25607. if (ret < 0) {
  25608. VERROR_INT("xmlSchemaVReaderWalk",
  25609. "calling xmlSchemaValidatorPopElem()");
  25610. goto internal_error;
  25611. }
  25612. goto exit;
  25613. }
  25614. if (vctxt->depth >= 0)
  25615. ielem = vctxt->inode;
  25616. else
  25617. ielem = NULL;
  25618. } else if ((nodeType == XML_TEXT_NODE) ||
  25619. (nodeType == XML_CDATA_SECTION_NODE) ||
  25620. (nodeType == WHTSP) ||
  25621. (nodeType == SIGN_WHTSP)) {
  25622. /*
  25623. * Process character content.
  25624. */
  25625. xmlChar *value;
  25626. if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
  25627. nodeType = XML_TEXT_NODE;
  25628. value = xmlTextReaderValue(vctxt->reader);
  25629. ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
  25630. -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
  25631. if (! consumed)
  25632. xmlFree(value);
  25633. if (ret == -1) {
  25634. VERROR_INT("xmlSchemaVReaderWalk",
  25635. "calling xmlSchemaVPushText()");
  25636. goto internal_error;
  25637. }
  25638. } else if ((nodeType == XML_ENTITY_NODE) ||
  25639. (nodeType == XML_ENTITY_REF_NODE)) {
  25640. /*
  25641. * VAL TODO: What to do with entities?
  25642. */
  25643. TODO
  25644. }
  25645. /*
  25646. * Read next node.
  25647. */
  25648. ret = xmlTextReaderRead(vctxt->reader);
  25649. } while (ret == 1);
  25650. exit:
  25651. return (ret);
  25652. internal_error:
  25653. return (-1);
  25654. }
  25655. #endif
  25656. /************************************************************************
  25657. * *
  25658. * SAX validation handlers *
  25659. * *
  25660. ************************************************************************/
  25661. /*
  25662. * Process text content.
  25663. */
  25664. static void
  25665. xmlSchemaSAXHandleText(void *ctx,
  25666. const xmlChar * ch,
  25667. int len)
  25668. {
  25669. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25670. if (vctxt->depth < 0)
  25671. return;
  25672. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25673. return;
  25674. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25675. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25676. if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
  25677. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25678. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25679. "calling xmlSchemaVPushText()");
  25680. vctxt->err = -1;
  25681. xmlStopParser(vctxt->parserCtxt);
  25682. }
  25683. }
  25684. /*
  25685. * Process CDATA content.
  25686. */
  25687. static void
  25688. xmlSchemaSAXHandleCDataSection(void *ctx,
  25689. const xmlChar * ch,
  25690. int len)
  25691. {
  25692. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25693. if (vctxt->depth < 0)
  25694. return;
  25695. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25696. return;
  25697. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25698. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25699. if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
  25700. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25701. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25702. "calling xmlSchemaVPushText()");
  25703. vctxt->err = -1;
  25704. xmlStopParser(vctxt->parserCtxt);
  25705. }
  25706. }
  25707. static void
  25708. xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
  25709. const xmlChar * name ATTRIBUTE_UNUSED)
  25710. {
  25711. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25712. if (vctxt->depth < 0)
  25713. return;
  25714. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25715. return;
  25716. /* SAX VAL TODO: What to do here? */
  25717. TODO
  25718. }
  25719. static void
  25720. xmlSchemaSAXHandleStartElementNs(void *ctx,
  25721. const xmlChar * localname,
  25722. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25723. const xmlChar * URI,
  25724. int nb_namespaces,
  25725. const xmlChar ** namespaces,
  25726. int nb_attributes,
  25727. int nb_defaulted ATTRIBUTE_UNUSED,
  25728. const xmlChar ** attributes)
  25729. {
  25730. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25731. int ret;
  25732. xmlSchemaNodeInfoPtr ielem;
  25733. int i, j;
  25734. /*
  25735. * SAX VAL TODO: What to do with nb_defaulted?
  25736. */
  25737. /*
  25738. * Skip elements if inside a "skip" wildcard or invalid.
  25739. */
  25740. vctxt->depth++;
  25741. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25742. return;
  25743. /*
  25744. * Push the element.
  25745. */
  25746. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25747. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25748. "calling xmlSchemaValidatorPushElem()");
  25749. goto internal_error;
  25750. }
  25751. ielem = vctxt->inode;
  25752. /*
  25753. * TODO: Is this OK?
  25754. */
  25755. ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
  25756. ielem->localName = localname;
  25757. ielem->nsName = URI;
  25758. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25759. /*
  25760. * Register namespaces on the elem info.
  25761. */
  25762. if (nb_namespaces != 0) {
  25763. /*
  25764. * Although the parser builds its own namespace list,
  25765. * we have no access to it, so we'll use an own one.
  25766. */
  25767. for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
  25768. /*
  25769. * Store prefix and namespace name.
  25770. */
  25771. if (ielem->nsBindings == NULL) {
  25772. ielem->nsBindings =
  25773. (const xmlChar **) xmlMalloc(10 *
  25774. sizeof(const xmlChar *));
  25775. if (ielem->nsBindings == NULL) {
  25776. xmlSchemaVErrMemory(vctxt,
  25777. "allocating namespace bindings for SAX validation",
  25778. NULL);
  25779. goto internal_error;
  25780. }
  25781. ielem->nbNsBindings = 0;
  25782. ielem->sizeNsBindings = 5;
  25783. } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
  25784. ielem->sizeNsBindings *= 2;
  25785. ielem->nsBindings =
  25786. (const xmlChar **) xmlRealloc(
  25787. (void *) ielem->nsBindings,
  25788. ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
  25789. if (ielem->nsBindings == NULL) {
  25790. xmlSchemaVErrMemory(vctxt,
  25791. "re-allocating namespace bindings for SAX validation",
  25792. NULL);
  25793. goto internal_error;
  25794. }
  25795. }
  25796. ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
  25797. if (namespaces[j+1][0] == 0) {
  25798. /*
  25799. * Handle xmlns="".
  25800. */
  25801. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
  25802. } else
  25803. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
  25804. namespaces[j+1];
  25805. ielem->nbNsBindings++;
  25806. }
  25807. }
  25808. /*
  25809. * Register attributes.
  25810. * SAX VAL TODO: We are not adding namespace declaration
  25811. * attributes yet.
  25812. */
  25813. if (nb_attributes != 0) {
  25814. int valueLen, k, l;
  25815. xmlChar *value;
  25816. for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
  25817. /*
  25818. * Duplicate the value, changing any &#38; to a literal ampersand.
  25819. *
  25820. * libxml2 differs from normal SAX here in that it escapes all ampersands
  25821. * as &#38; instead of delivering the raw converted string. Changing the
  25822. * behavior at this point would break applications that use this API, so
  25823. * we are forced to work around it.
  25824. */
  25825. valueLen = attributes[j+4] - attributes[j+3];
  25826. value = xmlMallocAtomic(valueLen + 1);
  25827. if (value == NULL) {
  25828. xmlSchemaVErrMemory(vctxt,
  25829. "allocating string for decoded attribute",
  25830. NULL);
  25831. goto internal_error;
  25832. }
  25833. for (k = 0, l = 0; k < valueLen; l++) {
  25834. if (k < valueLen - 4 &&
  25835. attributes[j+3][k+0] == '&' &&
  25836. attributes[j+3][k+1] == '#' &&
  25837. attributes[j+3][k+2] == '3' &&
  25838. attributes[j+3][k+3] == '8' &&
  25839. attributes[j+3][k+4] == ';') {
  25840. value[l] = '&';
  25841. k += 5;
  25842. } else {
  25843. value[l] = attributes[j+3][k];
  25844. k++;
  25845. }
  25846. }
  25847. value[l] = '\0';
  25848. /*
  25849. * TODO: Set the node line.
  25850. */
  25851. ret = xmlSchemaValidatorPushAttribute(vctxt,
  25852. NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
  25853. value, 1);
  25854. if (ret == -1) {
  25855. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25856. "calling xmlSchemaValidatorPushAttribute()");
  25857. goto internal_error;
  25858. }
  25859. }
  25860. }
  25861. /*
  25862. * Validate the element.
  25863. */
  25864. ret = xmlSchemaValidateElem(vctxt);
  25865. if (ret != 0) {
  25866. if (ret == -1) {
  25867. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25868. "calling xmlSchemaValidateElem()");
  25869. goto internal_error;
  25870. }
  25871. goto exit;
  25872. }
  25873. exit:
  25874. return;
  25875. internal_error:
  25876. vctxt->err = -1;
  25877. xmlStopParser(vctxt->parserCtxt);
  25878. return;
  25879. }
  25880. static void
  25881. xmlSchemaSAXHandleEndElementNs(void *ctx,
  25882. const xmlChar * localname ATTRIBUTE_UNUSED,
  25883. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25884. const xmlChar * URI ATTRIBUTE_UNUSED)
  25885. {
  25886. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25887. int res;
  25888. /*
  25889. * Skip elements if inside a "skip" wildcard or if invalid.
  25890. */
  25891. if (vctxt->skipDepth != -1) {
  25892. if (vctxt->depth > vctxt->skipDepth) {
  25893. vctxt->depth--;
  25894. return;
  25895. } else
  25896. vctxt->skipDepth = -1;
  25897. }
  25898. /*
  25899. * SAX VAL TODO: Just a temporary check.
  25900. */
  25901. if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
  25902. (!xmlStrEqual(vctxt->inode->nsName, URI))) {
  25903. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  25904. "elem pop mismatch");
  25905. }
  25906. res = xmlSchemaValidatorPopElem(vctxt);
  25907. if (res != 0) {
  25908. if (res < 0) {
  25909. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  25910. "calling xmlSchemaValidatorPopElem()");
  25911. goto internal_error;
  25912. }
  25913. goto exit;
  25914. }
  25915. exit:
  25916. return;
  25917. internal_error:
  25918. vctxt->err = -1;
  25919. xmlStopParser(vctxt->parserCtxt);
  25920. return;
  25921. }
  25922. /************************************************************************
  25923. * *
  25924. * Validation interfaces *
  25925. * *
  25926. ************************************************************************/
  25927. /**
  25928. * xmlSchemaNewValidCtxt:
  25929. * @schema: a precompiled XML Schemas
  25930. *
  25931. * Create an XML Schemas validation context based on the given schema.
  25932. *
  25933. * Returns the validation context or NULL in case of error
  25934. */
  25935. xmlSchemaValidCtxtPtr
  25936. xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
  25937. {
  25938. xmlSchemaValidCtxtPtr ret;
  25939. ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
  25940. if (ret == NULL) {
  25941. xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
  25942. return (NULL);
  25943. }
  25944. memset(ret, 0, sizeof(xmlSchemaValidCtxt));
  25945. ret->type = XML_SCHEMA_CTXT_VALIDATOR;
  25946. ret->dict = xmlDictCreate();
  25947. ret->nodeQNames = xmlSchemaItemListCreate();
  25948. ret->schema = schema;
  25949. return (ret);
  25950. }
  25951. /**
  25952. * xmlSchemaValidateSetFilename:
  25953. * @vctxt: the schema validation context
  25954. * @filename: the file name
  25955. *
  25956. * Workaround to provide file error reporting information when this is
  25957. * not provided by current APIs
  25958. */
  25959. void
  25960. xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
  25961. if (vctxt == NULL)
  25962. return;
  25963. if (vctxt->filename != NULL)
  25964. xmlFree(vctxt->filename);
  25965. if (filename != NULL)
  25966. vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
  25967. else
  25968. vctxt->filename = NULL;
  25969. }
  25970. /**
  25971. * xmlSchemaClearValidCtxt:
  25972. * @vctxt: the schema validation context
  25973. *
  25974. * Free the resources associated to the schema validation context;
  25975. * leaves some fields alive intended for reuse of the context.
  25976. */
  25977. static void
  25978. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
  25979. {
  25980. if (vctxt == NULL)
  25981. return;
  25982. /*
  25983. * TODO: Should we clear the flags?
  25984. * Might be problematic if one reuses the context
  25985. * and assumes that the options remain the same.
  25986. */
  25987. vctxt->flags = 0;
  25988. vctxt->validationRoot = NULL;
  25989. vctxt->doc = NULL;
  25990. #ifdef LIBXML_READER_ENABLED
  25991. vctxt->reader = NULL;
  25992. #endif
  25993. vctxt->hasKeyrefs = 0;
  25994. if (vctxt->value != NULL) {
  25995. xmlSchemaFreeValue(vctxt->value);
  25996. vctxt->value = NULL;
  25997. }
  25998. /*
  25999. * Augmented IDC information.
  26000. */
  26001. if (vctxt->aidcs != NULL) {
  26002. xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
  26003. do {
  26004. next = cur->next;
  26005. xmlFree(cur);
  26006. cur = next;
  26007. } while (cur != NULL);
  26008. vctxt->aidcs = NULL;
  26009. }
  26010. if (vctxt->idcNodes != NULL) {
  26011. int i;
  26012. xmlSchemaPSVIIDCNodePtr item;
  26013. for (i = 0; i < vctxt->nbIdcNodes; i++) {
  26014. item = vctxt->idcNodes[i];
  26015. xmlFree(item->keys);
  26016. xmlFree(item);
  26017. }
  26018. xmlFree(vctxt->idcNodes);
  26019. vctxt->idcNodes = NULL;
  26020. vctxt->nbIdcNodes = 0;
  26021. vctxt->sizeIdcNodes = 0;
  26022. }
  26023. if (vctxt->idcKeys != NULL) {
  26024. int i;
  26025. for (i = 0; i < vctxt->nbIdcKeys; i++)
  26026. xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
  26027. xmlFree(vctxt->idcKeys);
  26028. vctxt->idcKeys = NULL;
  26029. vctxt->nbIdcKeys = 0;
  26030. vctxt->sizeIdcKeys = 0;
  26031. }
  26032. /*
  26033. * Note that we won't delete the XPath state pool here.
  26034. */
  26035. if (vctxt->xpathStates != NULL) {
  26036. xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
  26037. vctxt->xpathStates = NULL;
  26038. }
  26039. /*
  26040. * Attribute info.
  26041. */
  26042. if (vctxt->nbAttrInfos != 0) {
  26043. xmlSchemaClearAttrInfos(vctxt);
  26044. }
  26045. /*
  26046. * Element info.
  26047. */
  26048. if (vctxt->elemInfos != NULL) {
  26049. int i;
  26050. xmlSchemaNodeInfoPtr ei;
  26051. for (i = 0; i < vctxt->sizeElemInfos; i++) {
  26052. ei = vctxt->elemInfos[i];
  26053. if (ei == NULL)
  26054. break;
  26055. xmlSchemaClearElemInfo(vctxt, ei);
  26056. }
  26057. }
  26058. xmlSchemaItemListClear(vctxt->nodeQNames);
  26059. /* Recreate the dict. */
  26060. xmlDictFree(vctxt->dict);
  26061. /*
  26062. * TODO: Is is save to recreate it? Do we have a scenario
  26063. * where the user provides the dict?
  26064. */
  26065. vctxt->dict = xmlDictCreate();
  26066. if (vctxt->filename != NULL) {
  26067. xmlFree(vctxt->filename);
  26068. vctxt->filename = NULL;
  26069. }
  26070. /*
  26071. * Note that some cleanup functions can move items to the cache,
  26072. * so the cache shouldn't be freed too early.
  26073. */
  26074. if (vctxt->idcMatcherCache != NULL) {
  26075. xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
  26076. while (matcher) {
  26077. tmp = matcher;
  26078. matcher = matcher->nextCached;
  26079. xmlSchemaIDCFreeMatcherList(tmp);
  26080. }
  26081. vctxt->idcMatcherCache = NULL;
  26082. }
  26083. }
  26084. /**
  26085. * xmlSchemaFreeValidCtxt:
  26086. * @ctxt: the schema validation context
  26087. *
  26088. * Free the resources associated to the schema validation context
  26089. */
  26090. void
  26091. xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
  26092. {
  26093. if (ctxt == NULL)
  26094. return;
  26095. if (ctxt->value != NULL)
  26096. xmlSchemaFreeValue(ctxt->value);
  26097. if (ctxt->pctxt != NULL)
  26098. xmlSchemaFreeParserCtxt(ctxt->pctxt);
  26099. if (ctxt->idcNodes != NULL) {
  26100. int i;
  26101. xmlSchemaPSVIIDCNodePtr item;
  26102. for (i = 0; i < ctxt->nbIdcNodes; i++) {
  26103. item = ctxt->idcNodes[i];
  26104. xmlFree(item->keys);
  26105. xmlFree(item);
  26106. }
  26107. xmlFree(ctxt->idcNodes);
  26108. }
  26109. if (ctxt->idcKeys != NULL) {
  26110. int i;
  26111. for (i = 0; i < ctxt->nbIdcKeys; i++)
  26112. xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
  26113. xmlFree(ctxt->idcKeys);
  26114. }
  26115. if (ctxt->xpathStates != NULL) {
  26116. xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
  26117. ctxt->xpathStates = NULL;
  26118. }
  26119. if (ctxt->xpathStatePool != NULL) {
  26120. xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
  26121. ctxt->xpathStatePool = NULL;
  26122. }
  26123. /*
  26124. * Augmented IDC information.
  26125. */
  26126. if (ctxt->aidcs != NULL) {
  26127. xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
  26128. do {
  26129. next = cur->next;
  26130. xmlFree(cur);
  26131. cur = next;
  26132. } while (cur != NULL);
  26133. }
  26134. if (ctxt->attrInfos != NULL) {
  26135. int i;
  26136. xmlSchemaAttrInfoPtr attr;
  26137. /* Just a paranoid call to the cleanup. */
  26138. if (ctxt->nbAttrInfos != 0)
  26139. xmlSchemaClearAttrInfos(ctxt);
  26140. for (i = 0; i < ctxt->sizeAttrInfos; i++) {
  26141. attr = ctxt->attrInfos[i];
  26142. xmlFree(attr);
  26143. }
  26144. xmlFree(ctxt->attrInfos);
  26145. }
  26146. if (ctxt->elemInfos != NULL) {
  26147. int i;
  26148. xmlSchemaNodeInfoPtr ei;
  26149. for (i = 0; i < ctxt->sizeElemInfos; i++) {
  26150. ei = ctxt->elemInfos[i];
  26151. if (ei == NULL)
  26152. break;
  26153. xmlSchemaClearElemInfo(ctxt, ei);
  26154. xmlFree(ei);
  26155. }
  26156. xmlFree(ctxt->elemInfos);
  26157. }
  26158. if (ctxt->nodeQNames != NULL)
  26159. xmlSchemaItemListFree(ctxt->nodeQNames);
  26160. if (ctxt->dict != NULL)
  26161. xmlDictFree(ctxt->dict);
  26162. if (ctxt->filename != NULL)
  26163. xmlFree(ctxt->filename);
  26164. xmlFree(ctxt);
  26165. }
  26166. /**
  26167. * xmlSchemaIsValid:
  26168. * @ctxt: the schema validation context
  26169. *
  26170. * Check if any error was detected during validation.
  26171. *
  26172. * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
  26173. * of internal error.
  26174. */
  26175. int
  26176. xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
  26177. {
  26178. if (ctxt == NULL)
  26179. return(-1);
  26180. return(ctxt->err == 0);
  26181. }
  26182. /**
  26183. * xmlSchemaSetValidErrors:
  26184. * @ctxt: a schema validation context
  26185. * @err: the error function
  26186. * @warn: the warning function
  26187. * @ctx: the functions context
  26188. *
  26189. * Set the error and warning callback information
  26190. */
  26191. void
  26192. xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26193. xmlSchemaValidityErrorFunc err,
  26194. xmlSchemaValidityWarningFunc warn, void *ctx)
  26195. {
  26196. if (ctxt == NULL)
  26197. return;
  26198. ctxt->error = err;
  26199. ctxt->warning = warn;
  26200. ctxt->errCtxt = ctx;
  26201. if (ctxt->pctxt != NULL)
  26202. xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
  26203. }
  26204. /**
  26205. * xmlSchemaSetValidStructuredErrors:
  26206. * @ctxt: a schema validation context
  26207. * @serror: the structured error function
  26208. * @ctx: the functions context
  26209. *
  26210. * Set the structured error callback
  26211. */
  26212. void
  26213. xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
  26214. xmlStructuredErrorFunc serror, void *ctx)
  26215. {
  26216. if (ctxt == NULL)
  26217. return;
  26218. ctxt->serror = serror;
  26219. ctxt->error = NULL;
  26220. ctxt->warning = NULL;
  26221. ctxt->errCtxt = ctx;
  26222. if (ctxt->pctxt != NULL)
  26223. xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
  26224. }
  26225. /**
  26226. * xmlSchemaGetValidErrors:
  26227. * @ctxt: a XML-Schema validation context
  26228. * @err: the error function result
  26229. * @warn: the warning function result
  26230. * @ctx: the functions context result
  26231. *
  26232. * Get the error and warning callback information
  26233. *
  26234. * Returns -1 in case of error and 0 otherwise
  26235. */
  26236. int
  26237. xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26238. xmlSchemaValidityErrorFunc * err,
  26239. xmlSchemaValidityWarningFunc * warn, void **ctx)
  26240. {
  26241. if (ctxt == NULL)
  26242. return (-1);
  26243. if (err != NULL)
  26244. *err = ctxt->error;
  26245. if (warn != NULL)
  26246. *warn = ctxt->warning;
  26247. if (ctx != NULL)
  26248. *ctx = ctxt->errCtxt;
  26249. return (0);
  26250. }
  26251. /**
  26252. * xmlSchemaSetValidOptions:
  26253. * @ctxt: a schema validation context
  26254. * @options: a combination of xmlSchemaValidOption
  26255. *
  26256. * Sets the options to be used during the validation.
  26257. *
  26258. * Returns 0 in case of success, -1 in case of an
  26259. * API error.
  26260. */
  26261. int
  26262. xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
  26263. int options)
  26264. {
  26265. int i;
  26266. if (ctxt == NULL)
  26267. return (-1);
  26268. /*
  26269. * WARNING: Change the start value if adding to the
  26270. * xmlSchemaValidOption.
  26271. * TODO: Is there an other, more easy to maintain,
  26272. * way?
  26273. */
  26274. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  26275. if (options & 1<<i)
  26276. return (-1);
  26277. }
  26278. ctxt->options = options;
  26279. return (0);
  26280. }
  26281. /**
  26282. * xmlSchemaValidCtxtGetOptions:
  26283. * @ctxt: a schema validation context
  26284. *
  26285. * Get the validation context options.
  26286. *
  26287. * Returns the option combination or -1 on error.
  26288. */
  26289. int
  26290. xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
  26291. {
  26292. if (ctxt == NULL)
  26293. return (-1);
  26294. else
  26295. return (ctxt->options);
  26296. }
  26297. static int
  26298. xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
  26299. {
  26300. xmlAttrPtr attr;
  26301. int ret = 0;
  26302. xmlSchemaNodeInfoPtr ielem = NULL;
  26303. xmlNodePtr node, valRoot;
  26304. const xmlChar *nsName;
  26305. /* DOC VAL TODO: Move this to the start function. */
  26306. if (vctxt->validationRoot != NULL)
  26307. valRoot = vctxt->validationRoot;
  26308. else
  26309. valRoot = xmlDocGetRootElement(vctxt->doc);
  26310. if (valRoot == NULL) {
  26311. /* VAL TODO: Error code? */
  26312. VERROR(1, NULL, "The document has no document element");
  26313. return (1);
  26314. }
  26315. vctxt->depth = -1;
  26316. vctxt->validationRoot = valRoot;
  26317. node = valRoot;
  26318. while (node != NULL) {
  26319. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26320. goto next_sibling;
  26321. if (node->type == XML_ELEMENT_NODE) {
  26322. /*
  26323. * Init the node-info.
  26324. */
  26325. vctxt->depth++;
  26326. if (xmlSchemaValidatorPushElem(vctxt) == -1)
  26327. goto internal_error;
  26328. ielem = vctxt->inode;
  26329. ielem->node = node;
  26330. ielem->nodeLine = node->line;
  26331. ielem->localName = node->name;
  26332. if (node->ns != NULL)
  26333. ielem->nsName = node->ns->href;
  26334. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26335. /*
  26336. * Register attributes.
  26337. * DOC VAL TODO: We do not register namespace declaration
  26338. * attributes yet.
  26339. */
  26340. vctxt->nbAttrInfos = 0;
  26341. if (node->properties != NULL) {
  26342. attr = node->properties;
  26343. do {
  26344. if (attr->ns != NULL)
  26345. nsName = attr->ns->href;
  26346. else
  26347. nsName = NULL;
  26348. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26349. (xmlNodePtr) attr,
  26350. /*
  26351. * Note that we give it the line number of the
  26352. * parent element.
  26353. */
  26354. ielem->nodeLine,
  26355. attr->name, nsName, 0,
  26356. xmlNodeListGetString(attr->doc, attr->children, 1), 1);
  26357. if (ret == -1) {
  26358. VERROR_INT("xmlSchemaDocWalk",
  26359. "calling xmlSchemaValidatorPushAttribute()");
  26360. goto internal_error;
  26361. }
  26362. attr = attr->next;
  26363. } while (attr);
  26364. }
  26365. /*
  26366. * Validate the element.
  26367. */
  26368. ret = xmlSchemaValidateElem(vctxt);
  26369. if (ret != 0) {
  26370. if (ret == -1) {
  26371. VERROR_INT("xmlSchemaDocWalk",
  26372. "calling xmlSchemaValidateElem()");
  26373. goto internal_error;
  26374. }
  26375. /*
  26376. * Don't stop validation; just skip the content
  26377. * of this element.
  26378. */
  26379. goto leave_node;
  26380. }
  26381. if ((vctxt->skipDepth != -1) &&
  26382. (vctxt->depth >= vctxt->skipDepth))
  26383. goto leave_node;
  26384. } else if ((node->type == XML_TEXT_NODE) ||
  26385. (node->type == XML_CDATA_SECTION_NODE)) {
  26386. /*
  26387. * Process character content.
  26388. */
  26389. if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
  26390. ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26391. ret = xmlSchemaVPushText(vctxt, node->type, node->content,
  26392. -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
  26393. if (ret < 0) {
  26394. VERROR_INT("xmlSchemaVDocWalk",
  26395. "calling xmlSchemaVPushText()");
  26396. goto internal_error;
  26397. }
  26398. /*
  26399. * DOC VAL TODO: Should we skip further validation of the
  26400. * element content here?
  26401. */
  26402. } else if ((node->type == XML_ENTITY_NODE) ||
  26403. (node->type == XML_ENTITY_REF_NODE)) {
  26404. /*
  26405. * DOC VAL TODO: What to do with entities?
  26406. */
  26407. VERROR_INT("xmlSchemaVDocWalk",
  26408. "there is at least one entity reference in the node-tree "
  26409. "currently being validated. Processing of entities with "
  26410. "this XML Schema processor is not supported (yet). Please "
  26411. "substitute entities before validation.");
  26412. goto internal_error;
  26413. } else {
  26414. goto leave_node;
  26415. /*
  26416. * DOC VAL TODO: XInclude nodes, etc.
  26417. */
  26418. }
  26419. /*
  26420. * Walk the doc.
  26421. */
  26422. if (node->children != NULL) {
  26423. node = node->children;
  26424. continue;
  26425. }
  26426. leave_node:
  26427. if (node->type == XML_ELEMENT_NODE) {
  26428. /*
  26429. * Leaving the scope of an element.
  26430. */
  26431. if (node != vctxt->inode->node) {
  26432. VERROR_INT("xmlSchemaVDocWalk",
  26433. "element position mismatch");
  26434. goto internal_error;
  26435. }
  26436. ret = xmlSchemaValidatorPopElem(vctxt);
  26437. if (ret != 0) {
  26438. if (ret < 0) {
  26439. VERROR_INT("xmlSchemaVDocWalk",
  26440. "calling xmlSchemaValidatorPopElem()");
  26441. goto internal_error;
  26442. }
  26443. }
  26444. if (node == valRoot)
  26445. goto exit;
  26446. }
  26447. next_sibling:
  26448. if (node->next != NULL)
  26449. node = node->next;
  26450. else {
  26451. node = node->parent;
  26452. goto leave_node;
  26453. }
  26454. }
  26455. exit:
  26456. return (ret);
  26457. internal_error:
  26458. return (-1);
  26459. }
  26460. static int
  26461. xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
  26462. /*
  26463. * Some initialization.
  26464. */
  26465. vctxt->err = 0;
  26466. vctxt->nberrors = 0;
  26467. vctxt->depth = -1;
  26468. vctxt->skipDepth = -1;
  26469. vctxt->hasKeyrefs = 0;
  26470. #ifdef ENABLE_IDC_NODE_TABLES_TEST
  26471. vctxt->createIDCNodeTables = 1;
  26472. #else
  26473. vctxt->createIDCNodeTables = 0;
  26474. #endif
  26475. /*
  26476. * Create a schema + parser if necessary.
  26477. */
  26478. if (vctxt->schema == NULL) {
  26479. xmlSchemaParserCtxtPtr pctxt;
  26480. vctxt->xsiAssemble = 1;
  26481. /*
  26482. * If not schema was given then we will create a schema
  26483. * dynamically using XSI schema locations.
  26484. *
  26485. * Create the schema parser context.
  26486. */
  26487. if ((vctxt->pctxt == NULL) &&
  26488. (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  26489. return (-1);
  26490. pctxt = vctxt->pctxt;
  26491. pctxt->xsiAssemble = 1;
  26492. /*
  26493. * Create the schema.
  26494. */
  26495. vctxt->schema = xmlSchemaNewSchema(pctxt);
  26496. if (vctxt->schema == NULL)
  26497. return (-1);
  26498. /*
  26499. * Create the schema construction context.
  26500. */
  26501. pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
  26502. if (pctxt->constructor == NULL)
  26503. return(-1);
  26504. pctxt->constructor->mainSchema = vctxt->schema;
  26505. /*
  26506. * Take ownership of the constructor to be able to free it.
  26507. */
  26508. pctxt->ownsConstructor = 1;
  26509. }
  26510. /*
  26511. * Augment the IDC definitions for the main schema and all imported ones
  26512. * NOTE: main schema if the first in the imported list
  26513. */
  26514. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  26515. vctxt);
  26516. return(0);
  26517. }
  26518. static void
  26519. xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
  26520. if (vctxt->xsiAssemble) {
  26521. if (vctxt->schema != NULL) {
  26522. xmlSchemaFree(vctxt->schema);
  26523. vctxt->schema = NULL;
  26524. }
  26525. }
  26526. xmlSchemaClearValidCtxt(vctxt);
  26527. }
  26528. static int
  26529. xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
  26530. {
  26531. int ret = 0;
  26532. if (xmlSchemaPreRun(vctxt) < 0)
  26533. return(-1);
  26534. if (vctxt->doc != NULL) {
  26535. /*
  26536. * Tree validation.
  26537. */
  26538. ret = xmlSchemaVDocWalk(vctxt);
  26539. #ifdef LIBXML_READER_ENABLED
  26540. } else if (vctxt->reader != NULL) {
  26541. /*
  26542. * XML Reader validation.
  26543. */
  26544. #ifdef XML_SCHEMA_READER_ENABLED
  26545. ret = xmlSchemaVReaderWalk(vctxt);
  26546. #endif
  26547. #endif
  26548. } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
  26549. /*
  26550. * SAX validation.
  26551. */
  26552. ret = xmlParseDocument(vctxt->parserCtxt);
  26553. } else {
  26554. VERROR_INT("xmlSchemaVStart",
  26555. "no instance to validate");
  26556. ret = -1;
  26557. }
  26558. xmlSchemaPostRun(vctxt);
  26559. if (ret == 0)
  26560. ret = vctxt->err;
  26561. return (ret);
  26562. }
  26563. /**
  26564. * xmlSchemaValidateOneElement:
  26565. * @ctxt: a schema validation context
  26566. * @elem: an element node
  26567. *
  26568. * Validate a branch of a tree, starting with the given @elem.
  26569. *
  26570. * Returns 0 if the element and its subtree is valid, a positive error
  26571. * code number otherwise and -1 in case of an internal or API error.
  26572. */
  26573. int
  26574. xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
  26575. {
  26576. if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
  26577. return (-1);
  26578. if (ctxt->schema == NULL)
  26579. return (-1);
  26580. ctxt->doc = elem->doc;
  26581. ctxt->node = elem;
  26582. ctxt->validationRoot = elem;
  26583. return(xmlSchemaVStart(ctxt));
  26584. }
  26585. /**
  26586. * xmlSchemaValidateDoc:
  26587. * @ctxt: a schema validation context
  26588. * @doc: a parsed document tree
  26589. *
  26590. * Validate a document tree in memory.
  26591. *
  26592. * Returns 0 if the document is schemas valid, a positive error code
  26593. * number otherwise and -1 in case of internal or API error.
  26594. */
  26595. int
  26596. xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
  26597. {
  26598. if ((ctxt == NULL) || (doc == NULL))
  26599. return (-1);
  26600. ctxt->doc = doc;
  26601. ctxt->node = xmlDocGetRootElement(doc);
  26602. if (ctxt->node == NULL) {
  26603. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  26604. XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
  26605. (xmlNodePtr) doc, NULL,
  26606. "The document has no document element", NULL, NULL);
  26607. return (ctxt->err);
  26608. }
  26609. ctxt->validationRoot = ctxt->node;
  26610. return (xmlSchemaVStart(ctxt));
  26611. }
  26612. /************************************************************************
  26613. * *
  26614. * Function and data for SAX streaming API *
  26615. * *
  26616. ************************************************************************/
  26617. typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
  26618. typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
  26619. struct _xmlSchemaSplitSAXData {
  26620. xmlSAXHandlerPtr user_sax;
  26621. void *user_data;
  26622. xmlSchemaValidCtxtPtr ctxt;
  26623. xmlSAXHandlerPtr schemas_sax;
  26624. };
  26625. #define XML_SAX_PLUG_MAGIC 0xdc43ba21
  26626. struct _xmlSchemaSAXPlug {
  26627. unsigned int magic;
  26628. /* the original callbacks information */
  26629. xmlSAXHandlerPtr *user_sax_ptr;
  26630. xmlSAXHandlerPtr user_sax;
  26631. void **user_data_ptr;
  26632. void *user_data;
  26633. /* the block plugged back and validation information */
  26634. xmlSAXHandler schemas_sax;
  26635. xmlSchemaValidCtxtPtr ctxt;
  26636. };
  26637. /* All those functions just bounces to the user provided SAX handlers */
  26638. static void
  26639. internalSubsetSplit(void *ctx, const xmlChar *name,
  26640. const xmlChar *ExternalID, const xmlChar *SystemID)
  26641. {
  26642. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26643. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26644. (ctxt->user_sax->internalSubset != NULL))
  26645. ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
  26646. SystemID);
  26647. }
  26648. static int
  26649. isStandaloneSplit(void *ctx)
  26650. {
  26651. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26652. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26653. (ctxt->user_sax->isStandalone != NULL))
  26654. return(ctxt->user_sax->isStandalone(ctxt->user_data));
  26655. return(0);
  26656. }
  26657. static int
  26658. hasInternalSubsetSplit(void *ctx)
  26659. {
  26660. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26661. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26662. (ctxt->user_sax->hasInternalSubset != NULL))
  26663. return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
  26664. return(0);
  26665. }
  26666. static int
  26667. hasExternalSubsetSplit(void *ctx)
  26668. {
  26669. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26670. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26671. (ctxt->user_sax->hasExternalSubset != NULL))
  26672. return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
  26673. return(0);
  26674. }
  26675. static void
  26676. externalSubsetSplit(void *ctx, const xmlChar *name,
  26677. const xmlChar *ExternalID, const xmlChar *SystemID)
  26678. {
  26679. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26680. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26681. (ctxt->user_sax->externalSubset != NULL))
  26682. ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
  26683. SystemID);
  26684. }
  26685. static xmlParserInputPtr
  26686. resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  26687. {
  26688. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26689. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26690. (ctxt->user_sax->resolveEntity != NULL))
  26691. return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
  26692. systemId));
  26693. return(NULL);
  26694. }
  26695. static xmlEntityPtr
  26696. getEntitySplit(void *ctx, const xmlChar *name)
  26697. {
  26698. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26699. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26700. (ctxt->user_sax->getEntity != NULL))
  26701. return(ctxt->user_sax->getEntity(ctxt->user_data, name));
  26702. return(NULL);
  26703. }
  26704. static xmlEntityPtr
  26705. getParameterEntitySplit(void *ctx, const xmlChar *name)
  26706. {
  26707. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26708. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26709. (ctxt->user_sax->getParameterEntity != NULL))
  26710. return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
  26711. return(NULL);
  26712. }
  26713. static void
  26714. entityDeclSplit(void *ctx, const xmlChar *name, int type,
  26715. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  26716. {
  26717. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26718. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26719. (ctxt->user_sax->entityDecl != NULL))
  26720. ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
  26721. systemId, content);
  26722. }
  26723. static void
  26724. attributeDeclSplit(void *ctx, const xmlChar * elem,
  26725. const xmlChar * name, int type, int def,
  26726. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  26727. {
  26728. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26729. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26730. (ctxt->user_sax->attributeDecl != NULL)) {
  26731. ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
  26732. def, defaultValue, tree);
  26733. } else {
  26734. xmlFreeEnumeration(tree);
  26735. }
  26736. }
  26737. static void
  26738. elementDeclSplit(void *ctx, const xmlChar *name, int type,
  26739. xmlElementContentPtr content)
  26740. {
  26741. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26742. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26743. (ctxt->user_sax->elementDecl != NULL))
  26744. ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
  26745. }
  26746. static void
  26747. notationDeclSplit(void *ctx, const xmlChar *name,
  26748. const xmlChar *publicId, const xmlChar *systemId)
  26749. {
  26750. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26751. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26752. (ctxt->user_sax->notationDecl != NULL))
  26753. ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
  26754. systemId);
  26755. }
  26756. static void
  26757. unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
  26758. const xmlChar *publicId, const xmlChar *systemId,
  26759. const xmlChar *notationName)
  26760. {
  26761. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26762. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26763. (ctxt->user_sax->unparsedEntityDecl != NULL))
  26764. ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
  26765. systemId, notationName);
  26766. }
  26767. static void
  26768. setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
  26769. {
  26770. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26771. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26772. (ctxt->user_sax->setDocumentLocator != NULL))
  26773. ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
  26774. }
  26775. static void
  26776. startDocumentSplit(void *ctx)
  26777. {
  26778. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26779. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26780. (ctxt->user_sax->startDocument != NULL))
  26781. ctxt->user_sax->startDocument(ctxt->user_data);
  26782. }
  26783. static void
  26784. endDocumentSplit(void *ctx)
  26785. {
  26786. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26787. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26788. (ctxt->user_sax->endDocument != NULL))
  26789. ctxt->user_sax->endDocument(ctxt->user_data);
  26790. }
  26791. static void
  26792. processingInstructionSplit(void *ctx, const xmlChar *target,
  26793. const xmlChar *data)
  26794. {
  26795. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26796. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26797. (ctxt->user_sax->processingInstruction != NULL))
  26798. ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
  26799. }
  26800. static void
  26801. commentSplit(void *ctx, const xmlChar *value)
  26802. {
  26803. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26804. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26805. (ctxt->user_sax->comment != NULL))
  26806. ctxt->user_sax->comment(ctxt->user_data, value);
  26807. }
  26808. /*
  26809. * Varargs error callbacks to the user application, harder ...
  26810. */
  26811. static void
  26812. warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26813. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26814. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26815. (ctxt->user_sax->warning != NULL)) {
  26816. TODO
  26817. }
  26818. }
  26819. static void
  26820. errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26821. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26822. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26823. (ctxt->user_sax->error != NULL)) {
  26824. TODO
  26825. }
  26826. }
  26827. static void
  26828. fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26829. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26830. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26831. (ctxt->user_sax->fatalError != NULL)) {
  26832. TODO
  26833. }
  26834. }
  26835. /*
  26836. * Those are function where both the user handler and the schemas handler
  26837. * need to be called.
  26838. */
  26839. static void
  26840. charactersSplit(void *ctx, const xmlChar *ch, int len)
  26841. {
  26842. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26843. if (ctxt == NULL)
  26844. return;
  26845. if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
  26846. ctxt->user_sax->characters(ctxt->user_data, ch, len);
  26847. if (ctxt->ctxt != NULL)
  26848. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26849. }
  26850. static void
  26851. ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
  26852. {
  26853. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26854. if (ctxt == NULL)
  26855. return;
  26856. if ((ctxt->user_sax != NULL) &&
  26857. (ctxt->user_sax->ignorableWhitespace != NULL))
  26858. ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
  26859. if (ctxt->ctxt != NULL)
  26860. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26861. }
  26862. static void
  26863. cdataBlockSplit(void *ctx, const xmlChar *value, int len)
  26864. {
  26865. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26866. if (ctxt == NULL)
  26867. return;
  26868. if ((ctxt->user_sax != NULL) &&
  26869. (ctxt->user_sax->cdataBlock != NULL))
  26870. ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
  26871. if (ctxt->ctxt != NULL)
  26872. xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
  26873. }
  26874. static void
  26875. referenceSplit(void *ctx, const xmlChar *name)
  26876. {
  26877. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26878. if (ctxt == NULL)
  26879. return;
  26880. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26881. (ctxt->user_sax->reference != NULL))
  26882. ctxt->user_sax->reference(ctxt->user_data, name);
  26883. if (ctxt->ctxt != NULL)
  26884. xmlSchemaSAXHandleReference(ctxt->user_data, name);
  26885. }
  26886. static void
  26887. startElementNsSplit(void *ctx, const xmlChar * localname,
  26888. const xmlChar * prefix, const xmlChar * URI,
  26889. int nb_namespaces, const xmlChar ** namespaces,
  26890. int nb_attributes, int nb_defaulted,
  26891. const xmlChar ** attributes) {
  26892. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26893. if (ctxt == NULL)
  26894. return;
  26895. if ((ctxt->user_sax != NULL) &&
  26896. (ctxt->user_sax->startElementNs != NULL))
  26897. ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
  26898. URI, nb_namespaces, namespaces,
  26899. nb_attributes, nb_defaulted,
  26900. attributes);
  26901. if (ctxt->ctxt != NULL)
  26902. xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
  26903. URI, nb_namespaces, namespaces,
  26904. nb_attributes, nb_defaulted,
  26905. attributes);
  26906. }
  26907. static void
  26908. endElementNsSplit(void *ctx, const xmlChar * localname,
  26909. const xmlChar * prefix, const xmlChar * URI) {
  26910. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26911. if (ctxt == NULL)
  26912. return;
  26913. if ((ctxt->user_sax != NULL) &&
  26914. (ctxt->user_sax->endElementNs != NULL))
  26915. ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
  26916. if (ctxt->ctxt != NULL)
  26917. xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
  26918. }
  26919. /**
  26920. * xmlSchemaSAXPlug:
  26921. * @ctxt: a schema validation context
  26922. * @sax: a pointer to the original xmlSAXHandlerPtr
  26923. * @user_data: a pointer to the original SAX user data pointer
  26924. *
  26925. * Plug a SAX based validation layer in a SAX parsing event flow.
  26926. * The original @saxptr and @dataptr data are replaced by new pointers
  26927. * but the calls to the original will be maintained.
  26928. *
  26929. * Returns a pointer to a data structure needed to unplug the validation layer
  26930. * or NULL in case of errors.
  26931. */
  26932. xmlSchemaSAXPlugPtr
  26933. xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
  26934. xmlSAXHandlerPtr *sax, void **user_data)
  26935. {
  26936. xmlSchemaSAXPlugPtr ret;
  26937. xmlSAXHandlerPtr old_sax;
  26938. if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
  26939. return(NULL);
  26940. /*
  26941. * We only allow to plug into SAX2 event streams
  26942. */
  26943. old_sax = *sax;
  26944. if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
  26945. return(NULL);
  26946. if ((old_sax != NULL) &&
  26947. (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
  26948. ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
  26949. return(NULL);
  26950. /*
  26951. * everything seems right allocate the local data needed for that layer
  26952. */
  26953. ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
  26954. if (ret == NULL) {
  26955. return(NULL);
  26956. }
  26957. memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
  26958. ret->magic = XML_SAX_PLUG_MAGIC;
  26959. ret->schemas_sax.initialized = XML_SAX2_MAGIC;
  26960. ret->ctxt = ctxt;
  26961. ret->user_sax_ptr = sax;
  26962. ret->user_sax = old_sax;
  26963. if (old_sax == NULL) {
  26964. /*
  26965. * go direct, no need for the split block and functions.
  26966. */
  26967. ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
  26968. ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
  26969. /*
  26970. * Note that we use the same text-function for both, to prevent
  26971. * the parser from testing for ignorable whitespace.
  26972. */
  26973. ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
  26974. ret->schemas_sax.characters = xmlSchemaSAXHandleText;
  26975. ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
  26976. ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
  26977. ret->user_data = ctxt;
  26978. *user_data = ctxt;
  26979. } else {
  26980. /*
  26981. * for each callback unused by Schemas initialize it to the Split
  26982. * routine only if non NULL in the user block, this can speed up
  26983. * things at the SAX level.
  26984. */
  26985. if (old_sax->internalSubset != NULL)
  26986. ret->schemas_sax.internalSubset = internalSubsetSplit;
  26987. if (old_sax->isStandalone != NULL)
  26988. ret->schemas_sax.isStandalone = isStandaloneSplit;
  26989. if (old_sax->hasInternalSubset != NULL)
  26990. ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
  26991. if (old_sax->hasExternalSubset != NULL)
  26992. ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
  26993. if (old_sax->resolveEntity != NULL)
  26994. ret->schemas_sax.resolveEntity = resolveEntitySplit;
  26995. if (old_sax->getEntity != NULL)
  26996. ret->schemas_sax.getEntity = getEntitySplit;
  26997. if (old_sax->entityDecl != NULL)
  26998. ret->schemas_sax.entityDecl = entityDeclSplit;
  26999. if (old_sax->notationDecl != NULL)
  27000. ret->schemas_sax.notationDecl = notationDeclSplit;
  27001. if (old_sax->attributeDecl != NULL)
  27002. ret->schemas_sax.attributeDecl = attributeDeclSplit;
  27003. if (old_sax->elementDecl != NULL)
  27004. ret->schemas_sax.elementDecl = elementDeclSplit;
  27005. if (old_sax->unparsedEntityDecl != NULL)
  27006. ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
  27007. if (old_sax->setDocumentLocator != NULL)
  27008. ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
  27009. if (old_sax->startDocument != NULL)
  27010. ret->schemas_sax.startDocument = startDocumentSplit;
  27011. if (old_sax->endDocument != NULL)
  27012. ret->schemas_sax.endDocument = endDocumentSplit;
  27013. if (old_sax->processingInstruction != NULL)
  27014. ret->schemas_sax.processingInstruction = processingInstructionSplit;
  27015. if (old_sax->comment != NULL)
  27016. ret->schemas_sax.comment = commentSplit;
  27017. if (old_sax->warning != NULL)
  27018. ret->schemas_sax.warning = warningSplit;
  27019. if (old_sax->error != NULL)
  27020. ret->schemas_sax.error = errorSplit;
  27021. if (old_sax->fatalError != NULL)
  27022. ret->schemas_sax.fatalError = fatalErrorSplit;
  27023. if (old_sax->getParameterEntity != NULL)
  27024. ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
  27025. if (old_sax->externalSubset != NULL)
  27026. ret->schemas_sax.externalSubset = externalSubsetSplit;
  27027. /*
  27028. * the 6 schemas callback have to go to the splitter functions
  27029. * Note that we use the same text-function for ignorableWhitespace
  27030. * if possible, to prevent the parser from testing for ignorable
  27031. * whitespace.
  27032. */
  27033. ret->schemas_sax.characters = charactersSplit;
  27034. if ((old_sax->ignorableWhitespace != NULL) &&
  27035. (old_sax->ignorableWhitespace != old_sax->characters))
  27036. ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
  27037. else
  27038. ret->schemas_sax.ignorableWhitespace = charactersSplit;
  27039. ret->schemas_sax.cdataBlock = cdataBlockSplit;
  27040. ret->schemas_sax.reference = referenceSplit;
  27041. ret->schemas_sax.startElementNs = startElementNsSplit;
  27042. ret->schemas_sax.endElementNs = endElementNsSplit;
  27043. ret->user_data_ptr = user_data;
  27044. ret->user_data = *user_data;
  27045. *user_data = ret;
  27046. }
  27047. /*
  27048. * plug the pointers back.
  27049. */
  27050. *sax = &(ret->schemas_sax);
  27051. ctxt->sax = *sax;
  27052. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27053. xmlSchemaPreRun(ctxt);
  27054. return(ret);
  27055. }
  27056. /**
  27057. * xmlSchemaSAXUnplug:
  27058. * @plug: a data structure returned by xmlSchemaSAXPlug
  27059. *
  27060. * Unplug a SAX based validation layer in a SAX parsing event flow.
  27061. * The original pointers used in the call are restored.
  27062. *
  27063. * Returns 0 in case of success and -1 in case of failure.
  27064. */
  27065. int
  27066. xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
  27067. {
  27068. xmlSAXHandlerPtr *sax;
  27069. void **user_data;
  27070. if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
  27071. return(-1);
  27072. plug->magic = 0;
  27073. xmlSchemaPostRun(plug->ctxt);
  27074. /* restore the data */
  27075. sax = plug->user_sax_ptr;
  27076. *sax = plug->user_sax;
  27077. if (plug->user_sax != NULL) {
  27078. user_data = plug->user_data_ptr;
  27079. *user_data = plug->user_data;
  27080. }
  27081. /* free and return */
  27082. xmlFree(plug);
  27083. return(0);
  27084. }
  27085. /**
  27086. * xmlSchemaValidateSetLocator:
  27087. * @vctxt: a schema validation context
  27088. * @f: the locator function pointer
  27089. * @ctxt: the locator context
  27090. *
  27091. * Allows to set a locator function to the validation context,
  27092. * which will be used to provide file and line information since
  27093. * those are not provided as part of the SAX validation flow
  27094. * Setting @f to NULL disable the locator.
  27095. */
  27096. void
  27097. xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
  27098. xmlSchemaValidityLocatorFunc f,
  27099. void *ctxt)
  27100. {
  27101. if (vctxt == NULL) return;
  27102. vctxt->locFunc = f;
  27103. vctxt->locCtxt = ctxt;
  27104. }
  27105. /**
  27106. * xmlSchemaValidateStreamLocator:
  27107. * @ctx: the xmlTextReaderPtr used
  27108. * @file: returned file information
  27109. * @line: returned line information
  27110. *
  27111. * Internal locator function for the readers
  27112. *
  27113. * Returns 0 in case the Schema validation could be (de)activated and
  27114. * -1 in case of error.
  27115. */
  27116. static int
  27117. xmlSchemaValidateStreamLocator(void *ctx, const char **file,
  27118. unsigned long *line) {
  27119. xmlParserCtxtPtr ctxt;
  27120. if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
  27121. return(-1);
  27122. if (file != NULL)
  27123. *file = NULL;
  27124. if (line != NULL)
  27125. *line = 0;
  27126. ctxt = (xmlParserCtxtPtr) ctx;
  27127. if (ctxt->input != NULL) {
  27128. if (file != NULL)
  27129. *file = ctxt->input->filename;
  27130. if (line != NULL)
  27131. *line = ctxt->input->line;
  27132. return(0);
  27133. }
  27134. return(-1);
  27135. }
  27136. /**
  27137. * xmlSchemaValidateStreamInternal:
  27138. * @ctxt: a schema validation context
  27139. * @pctxt: a parser context
  27140. *
  27141. * Returns 0 if the document is schemas valid, a positive error code
  27142. * number otherwise and -1 in case of internal or API error.
  27143. */
  27144. static int
  27145. xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
  27146. xmlParserCtxtPtr pctxt) {
  27147. xmlSchemaSAXPlugPtr plug = NULL;
  27148. int ret;
  27149. pctxt->linenumbers = 1;
  27150. xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
  27151. ctxt->parserCtxt = pctxt;
  27152. ctxt->input = pctxt->input->buf;
  27153. /*
  27154. * Plug the validation and launch the parsing
  27155. */
  27156. plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
  27157. if (plug == NULL) {
  27158. ret = -1;
  27159. goto done;
  27160. }
  27161. ctxt->input = pctxt->input->buf;
  27162. ctxt->sax = pctxt->sax;
  27163. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27164. ret = xmlSchemaVStart(ctxt);
  27165. if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
  27166. ret = ctxt->parserCtxt->errNo;
  27167. if (ret == 0)
  27168. ret = 1;
  27169. }
  27170. done:
  27171. ctxt->parserCtxt = NULL;
  27172. ctxt->sax = NULL;
  27173. ctxt->input = NULL;
  27174. if (plug != NULL) {
  27175. xmlSchemaSAXUnplug(plug);
  27176. }
  27177. return (ret);
  27178. }
  27179. /**
  27180. * xmlSchemaValidateStream:
  27181. * @ctxt: a schema validation context
  27182. * @input: the input to use for reading the data
  27183. * @enc: an optional encoding information
  27184. * @sax: a SAX handler for the resulting events
  27185. * @user_data: the context to provide to the SAX handler.
  27186. *
  27187. * Validate an input based on a flow of SAX event from the parser
  27188. * and forward the events to the @sax handler with the provided @user_data
  27189. * the user provided @sax handler must be a SAX2 one.
  27190. *
  27191. * Returns 0 if the document is schemas valid, a positive error code
  27192. * number otherwise and -1 in case of internal or API error.
  27193. */
  27194. int
  27195. xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
  27196. xmlParserInputBufferPtr input, xmlCharEncoding enc,
  27197. xmlSAXHandlerPtr sax, void *user_data)
  27198. {
  27199. xmlParserCtxtPtr pctxt = NULL;
  27200. xmlParserInputPtr inputStream = NULL;
  27201. int ret;
  27202. if ((ctxt == NULL) || (input == NULL))
  27203. return (-1);
  27204. /*
  27205. * prepare the parser
  27206. */
  27207. if (sax != NULL) {
  27208. pctxt = xmlNewSAXParserCtxt(sax, user_data);
  27209. if (pctxt == NULL)
  27210. return (-1);
  27211. } else {
  27212. pctxt = xmlNewParserCtxt();
  27213. if (pctxt == NULL)
  27214. return (-1);
  27215. /* We really want pctxt->sax to be NULL here. */
  27216. xmlFree(pctxt->sax);
  27217. pctxt->sax = NULL;
  27218. }
  27219. #if 0
  27220. if (options)
  27221. xmlCtxtUseOptions(pctxt, options);
  27222. #endif
  27223. inputStream = xmlNewIOInputStream(pctxt, input, enc);;
  27224. if (inputStream == NULL) {
  27225. ret = -1;
  27226. goto done;
  27227. }
  27228. inputPush(pctxt, inputStream);
  27229. ctxt->enc = enc;
  27230. ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
  27231. done:
  27232. /* cleanup */
  27233. if (pctxt != NULL) {
  27234. xmlFreeParserCtxt(pctxt);
  27235. }
  27236. return (ret);
  27237. }
  27238. /**
  27239. * xmlSchemaValidateFile:
  27240. * @ctxt: a schema validation context
  27241. * @filename: the URI of the instance
  27242. * @options: a future set of options, currently unused
  27243. *
  27244. * Do a schemas validation of the given resource, it will use the
  27245. * SAX streamable validation internally.
  27246. *
  27247. * Returns 0 if the document is valid, a positive error code
  27248. * number otherwise and -1 in case of an internal or API error.
  27249. */
  27250. int
  27251. xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
  27252. const char * filename,
  27253. int options ATTRIBUTE_UNUSED)
  27254. {
  27255. int ret;
  27256. xmlParserCtxtPtr pctxt = NULL;
  27257. if ((ctxt == NULL) || (filename == NULL))
  27258. return (-1);
  27259. pctxt = xmlCreateURLParserCtxt(filename, 0);
  27260. if (pctxt == NULL)
  27261. return (-1);
  27262. /* We really want pctxt->sax to be NULL here. */
  27263. xmlFree(pctxt->sax);
  27264. pctxt->sax = NULL;
  27265. ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
  27266. xmlFreeParserCtxt(pctxt);
  27267. return (ret);
  27268. }
  27269. /**
  27270. * xmlSchemaValidCtxtGetParserCtxt:
  27271. * @ctxt: a schema validation context
  27272. *
  27273. * allow access to the parser context of the schema validation context
  27274. *
  27275. * Returns the parser context of the schema validation context or NULL
  27276. * in case of error.
  27277. */
  27278. xmlParserCtxtPtr
  27279. xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
  27280. {
  27281. if (ctxt == NULL)
  27282. return(NULL);
  27283. return (ctxt->parserCtxt);
  27284. }
  27285. #endif /* LIBXML_SCHEMAS_ENABLED */